Merge pull request #267 from tristanz/master
Add ArgsUsage field to document the use of arguments
This commit is contained in:
commit
9039757268
23
app.go
23
app.go
@ -13,8 +13,12 @@ import (
|
|||||||
type App struct {
|
type App struct {
|
||||||
// The name of the program. Defaults to os.Args[0]
|
// The name of the program. Defaults to os.Args[0]
|
||||||
Name string
|
Name string
|
||||||
|
// Full name of command for help, defaults to Name
|
||||||
|
HelpName string
|
||||||
// Description of the program.
|
// Description of the program.
|
||||||
Usage string
|
Usage string
|
||||||
|
// Description of the program argument format.
|
||||||
|
ArgsUsage string
|
||||||
// Version of the program
|
// Version of the program
|
||||||
Version string
|
Version string
|
||||||
// List of commands to execute
|
// List of commands to execute
|
||||||
@ -67,6 +71,7 @@ func compileTime() time.Time {
|
|||||||
func NewApp() *App {
|
func NewApp() *App {
|
||||||
return &App{
|
return &App{
|
||||||
Name: os.Args[0],
|
Name: os.Args[0],
|
||||||
|
HelpName: os.Args[0],
|
||||||
Usage: "A new cli application",
|
Usage: "A new cli application",
|
||||||
Version: "0.0.0",
|
Version: "0.0.0",
|
||||||
BashComplete: DefaultAppComplete,
|
BashComplete: DefaultAppComplete,
|
||||||
@ -82,6 +87,15 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
|
a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newCmds := []Command{}
|
||||||
|
for _, c := range a.Commands {
|
||||||
|
if c.HelpName == "" {
|
||||||
|
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
|
||||||
|
}
|
||||||
|
newCmds = append(newCmds, c)
|
||||||
|
}
|
||||||
|
a.Commands = newCmds
|
||||||
|
|
||||||
// append help to commands
|
// append help to commands
|
||||||
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
if a.Command(helpCommand.Name) == nil && !a.HideHelp {
|
||||||
a.Commands = append(a.Commands, helpCommand)
|
a.Commands = append(a.Commands, helpCommand)
|
||||||
@ -185,6 +199,15 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newCmds := []Command{}
|
||||||
|
for _, c := range a.Commands {
|
||||||
|
if c.HelpName == "" {
|
||||||
|
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
|
||||||
|
}
|
||||||
|
newCmds = append(newCmds, c)
|
||||||
|
}
|
||||||
|
a.Commands = newCmds
|
||||||
|
|
||||||
// append flags
|
// append flags
|
||||||
if a.EnableBashCompletion {
|
if a.EnableBashCompletion {
|
||||||
a.appendFlag(BashCompletionFlag)
|
a.appendFlag(BashCompletionFlag)
|
||||||
|
101
app_test.go
101
app_test.go
@ -90,10 +90,10 @@ func ExampleAppHelp() {
|
|||||||
app.Run(os.Args)
|
app.Run(os.Args)
|
||||||
// Output:
|
// Output:
|
||||||
// NAME:
|
// NAME:
|
||||||
// describeit - use it to see a description
|
// greet describeit - use it to see a description
|
||||||
//
|
//
|
||||||
// USAGE:
|
// USAGE:
|
||||||
// command describeit [arguments...]
|
// greet describeit [arguments...]
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// This is how we describe describeit the function
|
// This is how we describe describeit the function
|
||||||
@ -737,7 +737,7 @@ func TestApp_Run_SubcommandFullPath(t *testing.T) {
|
|||||||
app := NewApp()
|
app := NewApp()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
app.Writer = buf
|
app.Writer = buf
|
||||||
|
app.Name = "command"
|
||||||
subCmd := Command{
|
subCmd := Command{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Usage: "does bar things",
|
Usage: "does bar things",
|
||||||
@ -755,7 +755,7 @@ func TestApp_Run_SubcommandFullPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output := buf.String()
|
output := buf.String()
|
||||||
if !strings.Contains(output, "foo bar - does bar things") {
|
if !strings.Contains(output, "command foo bar - does bar things") {
|
||||||
t.Errorf("expected full path to subcommand: %s", output)
|
t.Errorf("expected full path to subcommand: %s", output)
|
||||||
}
|
}
|
||||||
if !strings.Contains(output, "command foo bar [arguments...]") {
|
if !strings.Contains(output, "command foo bar [arguments...]") {
|
||||||
@ -763,6 +763,99 @@ func TestApp_Run_SubcommandFullPath(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApp_Run_SubcommandHelpName(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
app.Writer = buf
|
||||||
|
app.Name = "command"
|
||||||
|
subCmd := Command{
|
||||||
|
Name: "bar",
|
||||||
|
HelpName: "custom",
|
||||||
|
Usage: "does bar things",
|
||||||
|
}
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
Description: "foo commands",
|
||||||
|
Subcommands: []Command{subCmd},
|
||||||
|
}
|
||||||
|
app.Commands = []Command{cmd}
|
||||||
|
|
||||||
|
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
if !strings.Contains(output, "custom - does bar things") {
|
||||||
|
t.Errorf("expected HelpName for subcommand: %s", output)
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "custom [arguments...]") {
|
||||||
|
t.Errorf("expected HelpName to subcommand: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApp_Run_CommandHelpName(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
app.Writer = buf
|
||||||
|
app.Name = "command"
|
||||||
|
subCmd := Command{
|
||||||
|
Name: "bar",
|
||||||
|
Usage: "does bar things",
|
||||||
|
}
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
HelpName: "custom",
|
||||||
|
Description: "foo commands",
|
||||||
|
Subcommands: []Command{subCmd},
|
||||||
|
}
|
||||||
|
app.Commands = []Command{cmd}
|
||||||
|
|
||||||
|
err := app.Run([]string{"command", "foo", "bar", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
if !strings.Contains(output, "command foo bar - does bar things") {
|
||||||
|
t.Errorf("expected full path to subcommand: %s", output)
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "command foo bar [arguments...]") {
|
||||||
|
t.Errorf("expected full path to subcommand: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApp_Run_CommandSubcommandHelpName(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
app.Writer = buf
|
||||||
|
app.Name = "base"
|
||||||
|
subCmd := Command{
|
||||||
|
Name: "bar",
|
||||||
|
HelpName: "custom",
|
||||||
|
Usage: "does bar things",
|
||||||
|
}
|
||||||
|
cmd := Command{
|
||||||
|
Name: "foo",
|
||||||
|
Description: "foo commands",
|
||||||
|
Subcommands: []Command{subCmd},
|
||||||
|
}
|
||||||
|
app.Commands = []Command{cmd}
|
||||||
|
|
||||||
|
err := app.Run([]string{"command", "foo", "--help"})
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
if !strings.Contains(output, "base foo - foo commands") {
|
||||||
|
t.Errorf("expected full path to subcommand: %s", output)
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "base foo command [command options] [arguments...]") {
|
||||||
|
t.Errorf("expected full path to subcommand: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestApp_Run_Help(t *testing.T) {
|
func TestApp_Run_Help(t *testing.T) {
|
||||||
var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}
|
var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}
|
||||||
|
|
||||||
|
10
command.go
10
command.go
@ -18,6 +18,8 @@ type Command struct {
|
|||||||
Usage string
|
Usage string
|
||||||
// A longer explanation of how the command works
|
// A longer explanation of how the command works
|
||||||
Description string
|
Description string
|
||||||
|
// A short description of the arguments of this command
|
||||||
|
ArgsUsage string
|
||||||
// The function to call when checking for bash command completions
|
// The function to call when checking for bash command completions
|
||||||
BashComplete func(context *Context)
|
BashComplete func(context *Context)
|
||||||
// An action to execute before any sub-subcommands are run, but after the context is ready
|
// An action to execute before any sub-subcommands are run, but after the context is ready
|
||||||
@ -37,6 +39,8 @@ type Command struct {
|
|||||||
// Boolean to hide built-in help command
|
// Boolean to hide built-in help command
|
||||||
HideHelp bool
|
HideHelp bool
|
||||||
|
|
||||||
|
// Full name of command for help, defaults to full command name, including parent commands.
|
||||||
|
HelpName string
|
||||||
commandNamePath []string
|
commandNamePath []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +157,12 @@ func (c Command) startApp(ctx *Context) error {
|
|||||||
|
|
||||||
// set the name and usage
|
// set the name and usage
|
||||||
app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
|
app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
|
||||||
|
if c.HelpName == "" {
|
||||||
|
app.HelpName = c.HelpName
|
||||||
|
} else {
|
||||||
|
app.HelpName = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
|
||||||
|
}
|
||||||
|
|
||||||
if c.Description != "" {
|
if c.Description != "" {
|
||||||
app.Usage = c.Description
|
app.Usage = c.Description
|
||||||
} else {
|
} else {
|
||||||
|
24
help.go
24
help.go
@ -15,7 +15,7 @@ var AppHelpTemplate = `NAME:
|
|||||||
{{.Name}} - {{.Usage}}
|
{{.Name}} - {{.Usage}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{.Name}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} [arguments...]
|
{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
|
||||||
{{if .Version}}
|
{{if .Version}}
|
||||||
VERSION:
|
VERSION:
|
||||||
{{.Version}}
|
{{.Version}}
|
||||||
@ -38,10 +38,10 @@ COPYRIGHT:
|
|||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
var CommandHelpTemplate = `NAME:
|
var CommandHelpTemplate = `NAME:
|
||||||
{{.FullName}} - {{.Usage}}
|
{{.HelpName}} - {{.Usage}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
command {{.FullName}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}}
|
{{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}{{if .Flags}}
|
{{.Description}}{{end}}{{if .Flags}}
|
||||||
@ -55,10 +55,10 @@ OPTIONS:
|
|||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
var SubcommandHelpTemplate = `NAME:
|
var SubcommandHelpTemplate = `NAME:
|
||||||
{{.Name}} - {{.Usage}}
|
{{.HelpName}} - {{.Usage}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...]
|
{{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
{{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
|
||||||
@ -69,9 +69,10 @@ OPTIONS:
|
|||||||
`
|
`
|
||||||
|
|
||||||
var helpCommand = Command{
|
var helpCommand = Command{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
Aliases: []string{"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",
|
||||||
|
ArgsUsage: "[command]",
|
||||||
Action: func(c *Context) {
|
Action: func(c *Context) {
|
||||||
args := c.Args()
|
args := c.Args()
|
||||||
if args.Present() {
|
if args.Present() {
|
||||||
@ -83,9 +84,10 @@ var helpCommand = Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var helpSubcommand = Command{
|
var helpSubcommand = Command{
|
||||||
Name: "help",
|
Name: "help",
|
||||||
Aliases: []string{"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",
|
||||||
|
ArgsUsage: "[command]",
|
||||||
Action: func(c *Context) {
|
Action: func(c *Context) {
|
||||||
args := c.Args()
|
args := c.Args()
|
||||||
if args.Present() {
|
if args.Present() {
|
||||||
|
Loading…
Reference in New Issue
Block a user