github.com/jduhamel/gcli@v0.2.4-0.20151019142748-0d5307cd7e21/skeleton/resource/tmpl/go_cmd/main.go.tmpl (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"flag"
     6  	"fmt"
     7  	"io"
     8  	"log"
     9  	"os"
    10  	"strings"
    11  	"text/template"
    12  )
    13  
    14  // A Command is an implementation of a {{ .Name }} command
    15  type Command struct {
    16  	// Run runs the command.
    17  	// The args are the arguments after the command name.
    18  	Run func(args []string) int
    19  
    20  	// UsageLine is the one-line usage message.
    21  	// The first word in the line is taken to be the command name.
    22  	UsageLine string
    23  
    24  	// Short is the short description shown in the '{{ .Name }} help' output.
    25  	Short string
    26  
    27  	// Long is the long message shown in the '{{ .Name }} help <this-command>' output.
    28  	Long string
    29  
    30  	// Flag is a set of flags specific to this command.
    31  	Flag flag.FlagSet
    32  }
    33  
    34  // Name returns the command's name: the first word in the usage line.
    35  func (c *Command) Name() string {
    36  	name := c.UsageLine
    37  	i := strings.Index(name, " ")
    38  	if i >= 0 {
    39  		name = name[:i]
    40  	}
    41  	return name
    42  }
    43  
    44  func (c *Command) Usage() {
    45  	fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
    46  	fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
    47  	os.Exit(2)
    48  }
    49  
    50  // Commands lists the available commands and help topics.
    51  // The order here is the order in which they are printed by '{{ .Name }} help'.
    52  var commands = []*Command{
    53      {{ range .Commands }}cmd{{ title .FunctionName }},
    54      {{ end }}
    55  }
    56  
    57  func main() {
    58  
    59  	flag.Usage = usage
    60  	flag.Parse()
    61  	log.SetFlags(0)
    62  
    63  	args := flag.Args()
    64  	if len(args) < 1 {
    65  		usage()
    66  	}
    67  
    68  	if args[0] == "help" {
    69  		help(args[1:])
    70  		return
    71  	}
    72  
    73  	for _, cmd := range commands {
    74  		if cmd.Name() == args[0] {
    75  			cmd.Flag.Usage = func() { cmd.Usage() }
    76  
    77  			cmd.Flag.Parse(args[1:])
    78  			args = cmd.Flag.Args()
    79  
    80  			os.Exit(cmd.Run(args))
    81  		}
    82  	}
    83  
    84  	fmt.Fprintf(os.Stderr, "{{ .Name }}: unknown subcommand %q\nRun ' {{ .Name }} help' for usage.\n", args[0])
    85  	os.Exit(2)
    86  }
    87  
    88  var usageTemplate = `{{ .Name }} is a tool for {{ .Description }}
    89  
    90  Usage:
    91  
    92  	{{ .Name }} command [arguments]
    93  
    94  The commands are:
    95  {{"{{range .}}"}}
    96  	{{"{{.Name | printf "}}"%-11s"{{"}} {{.Short}}{{end}}"}}
    97  
    98  Use "{{ .Name }} help [command]" for more information about a command.
    99  
   100  `
   101  
   102  var helpTemplate = `usage: {{ .Name }} {{"{{.UsageLine}}"}}
   103  
   104  {{"{{.Long | trim}}"}}
   105  `
   106  
   107  // tmpl executes the given template text on data, writing the result to w.
   108  func tmpl(w io.Writer, text string, data interface{}) {
   109  	t := template.New("top")
   110  	t.Funcs(template.FuncMap{"trim": strings.TrimSpace})
   111  	template.Must(t.Parse(text))
   112  	if err := t.Execute(w, data); err != nil {
   113  		panic(err)
   114  	}
   115  }
   116  
   117  func printUsage(w io.Writer) {
   118  	bw := bufio.NewWriter(w)
   119  	tmpl(bw, usageTemplate, commands)
   120  	bw.Flush()
   121  }
   122  
   123  func usage() {
   124  	printUsage(os.Stderr)
   125  	os.Exit(2)
   126  }
   127  
   128  // help implements the 'help' command.
   129  func help(args []string) {
   130  	if len(args) == 0 {
   131  		printUsage(os.Stdout)
   132  		// not exit 2: succeeded at '{{ .Name }} help'.
   133  		return
   134  	}
   135  	if len(args) != 1 {
   136  		fmt.Fprintf(os.Stderr, "usage: {{ .Name }} help command\n\nToo many arguments given.\n")
   137  		os.Exit(2) // failed at '{{ .Name }} help'
   138  	}
   139  
   140  	arg := args[0]
   141  
   142  	for _, cmd := range commands {
   143  		if cmd.Name() == arg {
   144  			tmpl(os.Stdout, helpTemplate, cmd)
   145  			// not exit 2: succeeded at '{{ .Name }} help cmd'.
   146  			return
   147  		}
   148  	}
   149  
   150  	fmt.Fprintf(os.Stderr, "Unknown help topic %#q.  Run '{{ .Name }} help'.\n", arg)
   151  	os.Exit(2) // failed at '{{ .Name }} help cmd'
   152  }