diff --git a/README.md b/README.md index c0bb338..3a183b1 100644 --- a/README.md +++ b/README.md @@ -210,7 +210,7 @@ Subcommands can be defined for a more git-like command line app. app.Commands = []cli.Command{ { Name: "add", - ShortName: "a", + Names: []string{"a"}, Usage: "add a task to the list", Action: func(c *cli.Context) { println("added task: ", c.Args().First()) @@ -218,7 +218,7 @@ app.Commands = []cli.Command{ }, { Name: "complete", - ShortName: "c", + Names: []string{"c"}, Usage: "complete a task on the list", Action: func(c *cli.Context) { println("completed task: ", c.Args().First()) @@ -226,7 +226,7 @@ app.Commands = []cli.Command{ }, { Name: "template", - ShortName: "r", + Names: []string{"r"}, Usage: "options for task templates", Subcommands: []cli.Command{ { @@ -244,7 +244,7 @@ app.Commands = []cli.Command{ }, }, }, - }, + }, } ... ``` @@ -262,8 +262,8 @@ app := cli.NewApp() app.EnableBashCompletion = true app.Commands = []cli.Command{ { - Name: "complete", - ShortName: "c", + Name: "complete", + Names: []string{"c"}, Usage: "complete a task on the list", Action: func(c *cli.Context) { println("completed task: ", c.Args().First()) diff --git a/app.go b/app.go index 3d4ed12..cd29005 100644 --- a/app.go +++ b/app.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "os" + "strings" "text/tabwriter" "text/template" "time" @@ -88,8 +89,12 @@ func (a *App) Run(arguments []string) (err error) { }() HelpPrinter = func(templ string, data interface{}) { + funcMap := template.FuncMap{ + "join": strings.Join, + } + w := tabwriter.NewWriter(a.Writer, 0, 8, 1, '\t', 0) - t := template.Must(template.New("help").Parse(templ)) + t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) err := t.Execute(w, data) if err != nil { panic(err) diff --git a/app_test.go b/app_test.go index 6143d36..4a40b89 100644 --- a/app_test.go +++ b/app_test.go @@ -23,7 +23,7 @@ func ExampleApp() { } app.Author = "Harrison" app.Email = "harrison@lolwut.com" - app.Authors = []cli.Author{{"Oliver Allen", "oliver@toyshop.com"}} + app.Authors = []cli.Author{cli.Author{Name: "Oliver Allen", Email: "oliver@toyshop.com"}} app.Run(os.Args) // Output: // Hello Jeremy @@ -37,13 +37,13 @@ func ExampleAppSubcommand() { app.Commands = []cli.Command{ { Name: "hello", - ShortName: "hi", + Aliases: []string{"hi"}, Usage: "use it to see a description", Description: "This is how we describe hello the function", Subcommands: []cli.Command{ { Name: "english", - ShortName: "en", + Aliases: []string{"en"}, Usage: "sends a greeting in english", Description: "greets someone in english", Flags: []cli.Flag{ @@ -78,7 +78,7 @@ func ExampleAppHelp() { app.Commands = []cli.Command{ { Name: "describeit", - ShortName: "d", + Aliases: []string{"d"}, Usage: "use it to see a description", Description: "This is how we describe describeit the function", Action: func(c *cli.Context) { @@ -108,7 +108,7 @@ func ExampleAppBashComplete() { app.Commands = []cli.Command{ { Name: "describeit", - ShortName: "d", + Aliases: []string{"d"}, Usage: "use it to see a description", Description: "This is how we describe describeit the function", Action: func(c *cli.Context) { @@ -162,8 +162,8 @@ var commandAppTests = []struct { func TestApp_Command(t *testing.T) { app := cli.NewApp() - fooCommand := cli.Command{Name: "foobar", ShortName: "f"} - batCommand := cli.Command{Name: "batbaz", ShortName: "b"} + fooCommand := cli.Command{Name: "foobar", Aliases: []string{"f"}} + batCommand := cli.Command{Name: "batbaz", Aliases: []string{"b"}} app.Commands = []cli.Command{ fooCommand, batCommand, diff --git a/cli_test.go b/cli_test.go index 879a793..8a8df97 100644 --- a/cli_test.go +++ b/cli_test.go @@ -12,17 +12,17 @@ func Example() { app.Usage = "task list on the command line" app.Commands = []cli.Command{ { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", + Name: "add", + Aliases: []string{"a"}, + Usage: "add a task to the list", Action: func(c *cli.Context) { println("added task: ", c.Args().First()) }, }, { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", + Name: "complete", + Aliases: []string{"c"}, + Usage: "complete a task on the list", Action: func(c *cli.Context) { println("completed task: ", c.Args().First()) }, @@ -38,13 +38,13 @@ func ExampleSubcommand() { app.Commands = []cli.Command{ { Name: "hello", - ShortName: "hi", + Aliases: []string{"hi"}, Usage: "use it to see a description", Description: "This is how we describe hello the function", Subcommands: []cli.Command{ { Name: "english", - ShortName: "en", + Aliases: []string{"en"}, Usage: "sends a greeting in english", Description: "greets someone in english", Flags: []cli.Flag{ @@ -58,9 +58,9 @@ func ExampleSubcommand() { println("Hello, ", c.String("name")) }, }, { - Name: "spanish", - ShortName: "sp", - Usage: "sends a greeting in spanish", + Name: "spanish", + Aliases: []string{"sp"}, + Usage: "sends a greeting in spanish", Flags: []cli.Flag{ cli.StringFlag{ Name: "surname", @@ -72,9 +72,9 @@ func ExampleSubcommand() { println("Hola, ", c.String("surname")) }, }, { - Name: "french", - ShortName: "fr", - Usage: "sends a greeting in french", + Name: "french", + Aliases: []string{"fr"}, + Usage: "sends a greeting in french", Flags: []cli.Flag{ cli.StringFlag{ Name: "nickname", diff --git a/command.go b/command.go index 07c919a..b61691c 100644 --- a/command.go +++ b/command.go @@ -10,8 +10,10 @@ import ( type Command struct { // The name of the command Name string - // short name of the command. Typically one character + // short name of the command. Typically one character (deprecated, use `Aliases`) ShortName string + // A list of aliases for the command + Aliases []string // A short description of the usage of this command Usage string // A longer explanation of how the command works @@ -117,9 +119,24 @@ func (c Command) Run(ctx *Context) error { return nil } +func (c Command) Names() []string { + names := []string{c.Name} + + if c.ShortName != "" { + names = append(names, c.ShortName) + } + + return append(names, c.Aliases...) +} + // Returns true if Command.Name or Command.ShortName matches given name func (c Command) HasName(name string) bool { - return c.Name == name || (c.ShortName != "" && c.ShortName == name) + for _, n := range c.Names() { + if n == name { + return true + } + } + return false } func (c Command) startApp(ctx *Context) error { diff --git a/command_test.go b/command_test.go index c0f556a..4125b0c 100644 --- a/command_test.go +++ b/command_test.go @@ -17,7 +17,7 @@ func TestCommandDoNotIgnoreFlags(t *testing.T) { command := cli.Command{ Name: "test-cmd", - ShortName: "tc", + Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", Action: func(_ *cli.Context) {}, @@ -37,7 +37,7 @@ func TestCommandIgnoreFlags(t *testing.T) { command := cli.Command{ Name: "test-cmd", - ShortName: "tc", + Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", Action: func(_ *cli.Context) {}, diff --git a/help.go b/help.go index ee71155..7c4f81b 100644 --- a/help.go +++ b/help.go @@ -18,7 +18,7 @@ AUTHOR(S): {{range .Authors}}{{ . }} {{end}} COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} {{end}}{{if .Flags}} GLOBAL OPTIONS: {{range .Flags}}{{.}} @@ -52,7 +52,7 @@ USAGE: {{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...] COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} {{end}}{{if .Flags}} OPTIONS: {{range .Flags}}{{.}} @@ -60,9 +60,9 @@ OPTIONS: ` var helpCommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", + Name: "help", + Aliases: []string{"h"}, + Usage: "Shows a list of commands or help for one command", Action: func(c *Context) { args := c.Args() if args.Present() { @@ -74,9 +74,9 @@ var helpCommand = Command{ } var helpSubcommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", + Name: "help", + Aliases: []string{"h"}, + Usage: "Shows a list of commands or help for one command", Action: func(c *Context) { args := c.Args() if args.Present() { @@ -102,9 +102,8 @@ func ShowAppHelp(c *Context) { // Prints the list of subcommands as the default app completion method func DefaultAppComplete(c *Context) { for _, command := range c.App.Commands { - fmt.Fprintln(c.App.Writer, command.Name) - if command.ShortName != "" { - fmt.Fprintln(c.App.Writer, command.ShortName) + for _, name := range command.Names() { + fmt.Fprintln(c.App.Writer, name) } } }