Add Command.Aliases
and deprecate Command.ShortName
`Aliases` will be more flexible while still allowing "ShortName" behaviour via `Aliases`.
This commit is contained in:
parent
3e0905345c
commit
bf65971a6a
12
README.md
12
README.md
@ -210,7 +210,7 @@ Subcommands can be defined for a more git-like command line app.
|
|||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
ShortName: "a",
|
Names: []string{"a"},
|
||||||
Usage: "add a task to the list",
|
Usage: "add a task to the list",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
println("added task: ", c.Args().First())
|
println("added task: ", c.Args().First())
|
||||||
@ -218,7 +218,7 @@ app.Commands = []cli.Command{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "complete",
|
Name: "complete",
|
||||||
ShortName: "c",
|
Names: []string{"c"},
|
||||||
Usage: "complete a task on the list",
|
Usage: "complete a task on the list",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
println("completed task: ", c.Args().First())
|
println("completed task: ", c.Args().First())
|
||||||
@ -226,7 +226,7 @@ app.Commands = []cli.Command{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "template",
|
Name: "template",
|
||||||
ShortName: "r",
|
Names: []string{"r"},
|
||||||
Usage: "options for task templates",
|
Usage: "options for task templates",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ app.Commands = []cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
@ -262,8 +262,8 @@ app := cli.NewApp()
|
|||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "complete",
|
Name: "complete",
|
||||||
ShortName: "c",
|
Names: []string{"c"},
|
||||||
Usage: "complete a task on the list",
|
Usage: "complete a task on the list",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
println("completed task: ", c.Args().First())
|
println("completed task: ", c.Args().First())
|
||||||
|
7
app.go
7
app.go
@ -5,6 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
@ -91,8 +92,12 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
HelpPrinter = func(templ string, data interface{}) {
|
HelpPrinter = func(templ string, data interface{}) {
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"join": strings.Join,
|
||||||
|
}
|
||||||
|
|
||||||
w := tabwriter.NewWriter(a.Writer, 0, 8, 1, '\t', 0)
|
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)
|
err := t.Execute(w, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
53
app_test.go
53
app_test.go
@ -29,41 +29,24 @@ func ExampleApp() {
|
|||||||
// Hello Jeremy
|
// Hello Jeremy
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleAppSubcommand() {
|
func ExampleAppCommands() {
|
||||||
// set args for examples sake
|
// set args for examples sake
|
||||||
os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
|
os.Args = []string{"greet", "--name", "Jeremy"}
|
||||||
app := cli.NewApp()
|
|
||||||
app.Name = "say"
|
|
||||||
app.Commands = []cli.Command{
|
|
||||||
{
|
|
||||||
Name: "hello",
|
|
||||||
ShortName: "hi",
|
|
||||||
Usage: "use it to see a description",
|
|
||||||
Description: "This is how we describe hello the function",
|
|
||||||
Subcommands: []cli.Command{
|
|
||||||
{
|
|
||||||
Name: "english",
|
|
||||||
ShortName: "en",
|
|
||||||
Usage: "sends a greeting in english",
|
|
||||||
Description: "greets someone in english",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "Bob",
|
|
||||||
Usage: "Name of the person to greet",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(c *cli.Context) {
|
|
||||||
fmt.Println("Hello,", c.String("name"))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
app := cli.NewApp()
|
||||||
|
app.Name = "greet"
|
||||||
|
app.Flags = []cli.Flag{
|
||||||
|
cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
|
||||||
|
}
|
||||||
|
app.Action = func(c *cli.Context) {
|
||||||
|
fmt.Printf("Hello %v\n", c.String("name"))
|
||||||
|
}
|
||||||
|
app.Author = "Harrison"
|
||||||
|
app.Email = "harrison@lolwut.com"
|
||||||
|
app.Authors = []cli.Author{{"Oliver Allen", "oliver@toyshop.com"}}
|
||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
||||||
// Output:
|
// Output:
|
||||||
// Hello, Jeremy
|
// Hello Jeremy
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleAppHelp() {
|
func ExampleAppHelp() {
|
||||||
@ -78,7 +61,7 @@ func ExampleAppHelp() {
|
|||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "describeit",
|
Name: "describeit",
|
||||||
ShortName: "d",
|
Aliases: []string{"d"},
|
||||||
Usage: "use it to see a description",
|
Usage: "use it to see a description",
|
||||||
Description: "This is how we describe describeit the function",
|
Description: "This is how we describe describeit the function",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
@ -108,7 +91,7 @@ func ExampleAppBashComplete() {
|
|||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "describeit",
|
Name: "describeit",
|
||||||
ShortName: "d",
|
Aliases: []string{"d"},
|
||||||
Usage: "use it to see a description",
|
Usage: "use it to see a description",
|
||||||
Description: "This is how we describe describeit the function",
|
Description: "This is how we describe describeit the function",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
@ -162,8 +145,8 @@ var commandAppTests = []struct {
|
|||||||
|
|
||||||
func TestApp_Command(t *testing.T) {
|
func TestApp_Command(t *testing.T) {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
fooCommand := cli.Command{Name: "foobar", ShortName: "f"}
|
fooCommand := cli.Command{Name: "foobar", Aliases: []string{"f"}}
|
||||||
batCommand := cli.Command{Name: "batbaz", ShortName: "b"}
|
batCommand := cli.Command{Name: "batbaz", Aliases: []string{"b"}}
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
fooCommand,
|
fooCommand,
|
||||||
batCommand,
|
batCommand,
|
||||||
|
28
cli_test.go
28
cli_test.go
@ -12,17 +12,17 @@ func Example() {
|
|||||||
app.Usage = "task list on the command line"
|
app.Usage = "task list on the command line"
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "add",
|
Name: "add",
|
||||||
ShortName: "a",
|
Aliases: []string{"a"},
|
||||||
Usage: "add a task to the list",
|
Usage: "add a task to the list",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
println("added task: ", c.Args().First())
|
println("added task: ", c.Args().First())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "complete",
|
Name: "complete",
|
||||||
ShortName: "c",
|
Aliases: []string{"c"},
|
||||||
Usage: "complete a task on the list",
|
Usage: "complete a task on the list",
|
||||||
Action: func(c *cli.Context) {
|
Action: func(c *cli.Context) {
|
||||||
println("completed task: ", c.Args().First())
|
println("completed task: ", c.Args().First())
|
||||||
},
|
},
|
||||||
@ -38,13 +38,13 @@ func ExampleSubcommand() {
|
|||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "hello",
|
Name: "hello",
|
||||||
ShortName: "hi",
|
Aliases: []string{"hi"},
|
||||||
Usage: "use it to see a description",
|
Usage: "use it to see a description",
|
||||||
Description: "This is how we describe hello the function",
|
Description: "This is how we describe hello the function",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "english",
|
Name: "english",
|
||||||
ShortName: "en",
|
Aliases: []string{"en"},
|
||||||
Usage: "sends a greeting in english",
|
Usage: "sends a greeting in english",
|
||||||
Description: "greets someone in english",
|
Description: "greets someone in english",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
@ -58,9 +58,9 @@ func ExampleSubcommand() {
|
|||||||
println("Hello, ", c.String("name"))
|
println("Hello, ", c.String("name"))
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
Name: "spanish",
|
Name: "spanish",
|
||||||
ShortName: "sp",
|
Aliases: []string{"sp"},
|
||||||
Usage: "sends a greeting in spanish",
|
Usage: "sends a greeting in spanish",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "surname",
|
Name: "surname",
|
||||||
@ -72,9 +72,9 @@ func ExampleSubcommand() {
|
|||||||
println("Hola, ", c.String("surname"))
|
println("Hola, ", c.String("surname"))
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
Name: "french",
|
Name: "french",
|
||||||
ShortName: "fr",
|
Aliases: []string{"fr"},
|
||||||
Usage: "sends a greeting in french",
|
Usage: "sends a greeting in french",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "nickname",
|
Name: "nickname",
|
||||||
|
21
command.go
21
command.go
@ -10,8 +10,10 @@ import (
|
|||||||
type Command struct {
|
type Command struct {
|
||||||
// The name of the command
|
// The name of the command
|
||||||
Name string
|
Name string
|
||||||
// short name of the command. Typically one character
|
// short name of the command. Typically one character (deprecated, use `Aliases`)
|
||||||
ShortName string
|
ShortName string
|
||||||
|
// A list of aliases for the command
|
||||||
|
Aliases []string
|
||||||
// A short description of the usage of this command
|
// A short description of the usage of this command
|
||||||
Usage string
|
Usage string
|
||||||
// A longer explanation of how the command works
|
// A longer explanation of how the command works
|
||||||
@ -117,9 +119,24 @@ func (c Command) Run(ctx *Context) error {
|
|||||||
return nil
|
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
|
// Returns true if Command.Name or Command.ShortName matches given name
|
||||||
func (c Command) HasName(name string) bool {
|
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 {
|
func (c Command) startApp(ctx *Context) error {
|
||||||
|
@ -17,7 +17,7 @@ func TestCommandDoNotIgnoreFlags(t *testing.T) {
|
|||||||
|
|
||||||
command := cli.Command{
|
command := cli.Command{
|
||||||
Name: "test-cmd",
|
Name: "test-cmd",
|
||||||
ShortName: "tc",
|
Aliases: []string{"tc"},
|
||||||
Usage: "this is for testing",
|
Usage: "this is for testing",
|
||||||
Description: "testing",
|
Description: "testing",
|
||||||
Action: func(_ *cli.Context) {},
|
Action: func(_ *cli.Context) {},
|
||||||
@ -37,7 +37,7 @@ func TestCommandIgnoreFlags(t *testing.T) {
|
|||||||
|
|
||||||
command := cli.Command{
|
command := cli.Command{
|
||||||
Name: "test-cmd",
|
Name: "test-cmd",
|
||||||
ShortName: "tc",
|
Aliases: []string{"tc"},
|
||||||
Usage: "this is for testing",
|
Usage: "this is for testing",
|
||||||
Description: "testing",
|
Description: "testing",
|
||||||
Action: func(_ *cli.Context) {},
|
Action: func(_ *cli.Context) {},
|
||||||
|
21
help.go
21
help.go
@ -18,7 +18,7 @@ AUTHOR(S):
|
|||||||
{{range .Authors}}{{ . }} {{end}}
|
{{range .Authors}}{{ . }} {{end}}
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
{{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
|
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||||||
{{end}}{{if .Flags}}
|
{{end}}{{if .Flags}}
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
{{range .Flags}}{{.}}
|
{{range .Flags}}{{.}}
|
||||||
@ -52,7 +52,7 @@ USAGE:
|
|||||||
{{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...]
|
{{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...]
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
{{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
|
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||||||
{{end}}{{if .Flags}}
|
{{end}}{{if .Flags}}
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .Flags}}{{.}}
|
{{range .Flags}}{{.}}
|
||||||
@ -60,9 +60,9 @@ OPTIONS:
|
|||||||
`
|
`
|
||||||
|
|
||||||
var helpCommand = Command{
|
var helpCommand = Command{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
ShortName: "h",
|
Aliases: []string{"h"},
|
||||||
Usage: "Shows a list of commands or help for one command",
|
Usage: "Shows a list of commands or help for one command",
|
||||||
Action: func(c *Context) {
|
Action: func(c *Context) {
|
||||||
args := c.Args()
|
args := c.Args()
|
||||||
if args.Present() {
|
if args.Present() {
|
||||||
@ -74,9 +74,9 @@ var helpCommand = Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var helpSubcommand = Command{
|
var helpSubcommand = Command{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
ShortName: "h",
|
Aliases: []string{"h"},
|
||||||
Usage: "Shows a list of commands or help for one command",
|
Usage: "Shows a list of commands or help for one command",
|
||||||
Action: func(c *Context) {
|
Action: func(c *Context) {
|
||||||
args := c.Args()
|
args := c.Args()
|
||||||
if args.Present() {
|
if args.Present() {
|
||||||
@ -102,9 +102,8 @@ func ShowAppHelp(c *Context) {
|
|||||||
// Prints the list of subcommands as the default app completion method
|
// Prints the list of subcommands as the default app completion method
|
||||||
func DefaultAppComplete(c *Context) {
|
func DefaultAppComplete(c *Context) {
|
||||||
for _, command := range c.App.Commands {
|
for _, command := range c.App.Commands {
|
||||||
fmt.Fprintln(c.App.Writer, command.Name)
|
for _, name := range command.Names() {
|
||||||
if command.ShortName != "" {
|
fmt.Fprintln(c.App.Writer, name)
|
||||||
fmt.Fprintln(c.App.Writer, command.ShortName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user