mirror of
https://github.com/spf13/cobra
synced 2024-11-16 18:57:08 +00:00
Merge github.com:spf13/cobra
This commit is contained in:
commit
50142bdfe4
3 changed files with 69 additions and 18 deletions
|
@ -216,11 +216,11 @@ For a more complete example of a larger application, please checkout [Hugo](http
|
||||||
|
|
||||||
## The Help Command
|
## The Help Command
|
||||||
|
|
||||||
Cobra automatically adds a help command to your application.
|
Cobra automatically adds a help command to your application when you have subcommands.
|
||||||
This will be called when a user runs 'app help'. Additionally help will also
|
This will be called when a user runs 'app help'. Additionally help will also
|
||||||
support all other commands as input. Say for instance you have a command called
|
support all other commands as input. Say for instance you have a command called
|
||||||
'create' without any additional configuration cobra will work when 'app help
|
'create' without any additional configuration cobra will work when 'app help
|
||||||
create' is called.
|
create' is called. Every command will automatically have the '--help' flag added.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
|
|
|
@ -461,7 +461,7 @@ func TestRootHelp(t *testing.T) {
|
||||||
x := fullSetupTest("--help")
|
x := fullSetupTest("--help")
|
||||||
|
|
||||||
checkResultContains(t, x, "Available Commands:")
|
checkResultContains(t, x, "Available Commands:")
|
||||||
checkResultContains(t, x, "for more information about that command")
|
checkResultContains(t, x, "for more information about a command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
||||||
|
@ -470,7 +470,7 @@ func TestRootHelp(t *testing.T) {
|
||||||
x = fullSetupTest("echo --help")
|
x = fullSetupTest("echo --help")
|
||||||
|
|
||||||
checkResultContains(t, x, "Available Commands:")
|
checkResultContains(t, x, "Available Commands:")
|
||||||
checkResultContains(t, x, "for more information about that command")
|
checkResultContains(t, x, "for more information about a command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
||||||
|
@ -482,7 +482,7 @@ func TestRootNoCommandHelp(t *testing.T) {
|
||||||
x := rootOnlySetupTest("--help")
|
x := rootOnlySetupTest("--help")
|
||||||
|
|
||||||
checkResultOmits(t, x, "Available Commands:")
|
checkResultOmits(t, x, "Available Commands:")
|
||||||
checkResultOmits(t, x, "for more information about that command")
|
checkResultOmits(t, x, "for more information about a command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
||||||
|
@ -491,7 +491,7 @@ func TestRootNoCommandHelp(t *testing.T) {
|
||||||
x = rootOnlySetupTest("echo --help")
|
x = rootOnlySetupTest("echo --help")
|
||||||
|
|
||||||
checkResultOmits(t, x, "Available Commands:")
|
checkResultOmits(t, x, "Available Commands:")
|
||||||
checkResultOmits(t, x, "for more information about that command")
|
checkResultOmits(t, x, "for more information about a command")
|
||||||
|
|
||||||
if strings.Contains(x.Output, "unknown flag: --help") {
|
if strings.Contains(x.Output, "unknown flag: --help") {
|
||||||
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output)
|
||||||
|
|
75
command.go
75
command.go
|
@ -40,9 +40,9 @@ type Command struct {
|
||||||
Short string
|
Short string
|
||||||
// The long message shown in the 'help <this-command>' output.
|
// The long message shown in the 'help <this-command>' output.
|
||||||
Long string
|
Long string
|
||||||
// Set of flags specific to this command.
|
// Full set of flags
|
||||||
flags *flag.FlagSet
|
flags *flag.FlagSet
|
||||||
// Set of flags children commands will inherit
|
// Set of flags childrens of this command will inherit
|
||||||
pflags *flag.FlagSet
|
pflags *flag.FlagSet
|
||||||
// Run runs the command.
|
// Run runs the command.
|
||||||
// The args are the arguments after the command name.
|
// The args are the arguments after the command name.
|
||||||
|
@ -206,12 +206,14 @@ Aliases:
|
||||||
Available Commands: {{range .Commands}}{{if .Runnable}}
|
Available Commands: {{range .Commands}}{{if .Runnable}}
|
||||||
{{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}}
|
{{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{ if .HasFlags}} Available Flags:
|
{{ if .HasLocalFlags}}Flags:
|
||||||
{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }}
|
{{.LocalFlags.FlagUsages}}{{end}}
|
||||||
|
{{ if .HasAnyPersistentFlags}}Global Flags:
|
||||||
|
{{.AllPersistentFlags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }}
|
||||||
Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}}
|
Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}}
|
||||||
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}}
|
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{ if .HasSubCommands }}
|
{{end}}{{ if .HasSubCommands }}
|
||||||
Use "{{.Root.Name}} help [command]" for more information about that command.
|
Use "{{.Root.Name}} help [command]" for more information about a command.
|
||||||
{{end}}`
|
{{end}}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,7 +709,7 @@ func (c *Command) HasParent() bool {
|
||||||
return c.parent != nil
|
return c.parent != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Commands FlagSet
|
// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents)
|
||||||
func (c *Command) Flags() *flag.FlagSet {
|
func (c *Command) Flags() *flag.FlagSet {
|
||||||
if c.flags == nil {
|
if c.flags == nil {
|
||||||
c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||||
|
@ -720,7 +722,23 @@ func (c *Command) Flags() *flag.FlagSet {
|
||||||
return c.flags
|
return c.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Commands Persistent FlagSet
|
// Get the local FlagSet specifically set in the current command
|
||||||
|
func (c *Command) LocalFlags() *flag.FlagSet {
|
||||||
|
c.mergePersistentFlags()
|
||||||
|
|
||||||
|
local := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||||
|
allPersistent := c.AllPersistentFlags()
|
||||||
|
|
||||||
|
c.Flags().VisitAll(func(f *flag.Flag) {
|
||||||
|
if allPersistent.Lookup(f.Name) == nil {
|
||||||
|
local.AddFlag(f)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Persistent FlagSet specifically set in the current command
|
||||||
func (c *Command) PersistentFlags() *flag.FlagSet {
|
func (c *Command) PersistentFlags() *flag.FlagSet {
|
||||||
if c.pflags == nil {
|
if c.pflags == nil {
|
||||||
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||||
|
@ -732,6 +750,29 @@ func (c *Command) PersistentFlags() *flag.FlagSet {
|
||||||
return c.pflags
|
return c.pflags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the Persistent FlagSet traversing the Command hierarchy
|
||||||
|
func (c *Command) AllPersistentFlags() *flag.FlagSet {
|
||||||
|
allPersistent := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||||
|
|
||||||
|
var visit func(x *Command)
|
||||||
|
visit = func(x *Command) {
|
||||||
|
if x.HasPersistentFlags() {
|
||||||
|
x.PersistentFlags().VisitAll(func(f *flag.Flag) {
|
||||||
|
if allPersistent.Lookup(f.Name) == nil {
|
||||||
|
allPersistent.AddFlag(f)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if x.HasParent() {
|
||||||
|
visit(x.parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visit(c)
|
||||||
|
|
||||||
|
return allPersistent
|
||||||
|
}
|
||||||
|
|
||||||
// For use in testing
|
// For use in testing
|
||||||
func (c *Command) ResetFlags() {
|
func (c *Command) ResetFlags() {
|
||||||
c.flagErrorBuf = new(bytes.Buffer)
|
c.flagErrorBuf = new(bytes.Buffer)
|
||||||
|
@ -742,7 +783,7 @@ func (c *Command) ResetFlags() {
|
||||||
c.pflags.SetOutput(c.flagErrorBuf)
|
c.pflags.SetOutput(c.flagErrorBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the command contain flags (local not persistent)
|
// Does the command contain any flags (local plus persistent from the entire structure)
|
||||||
func (c *Command) HasFlags() bool {
|
func (c *Command) HasFlags() bool {
|
||||||
return c.Flags().HasFlags()
|
return c.Flags().HasFlags()
|
||||||
}
|
}
|
||||||
|
@ -752,6 +793,16 @@ func (c *Command) HasPersistentFlags() bool {
|
||||||
return c.PersistentFlags().HasFlags()
|
return c.PersistentFlags().HasFlags()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does the command hierarchy contain persistent flags
|
||||||
|
func (c *Command) HasAnyPersistentFlags() bool {
|
||||||
|
return c.AllPersistentFlags().HasFlags()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the command has flags specifically declared locally
|
||||||
|
func (c *Command) HasLocalFlags() bool {
|
||||||
|
return c.LocalFlags().HasFlags()
|
||||||
|
}
|
||||||
|
|
||||||
// Climbs up the command tree looking for matching flag
|
// Climbs up the command tree looking for matching flag
|
||||||
func (c *Command) Flag(name string) (flag *flag.Flag) {
|
func (c *Command) Flag(name string) (flag *flag.Flag) {
|
||||||
flag = c.Flags().Lookup(name)
|
flag = c.Flags().Lookup(name)
|
||||||
|
@ -791,6 +842,10 @@ func (c *Command) ParseFlags(args []string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) Parent() *Command {
|
||||||
|
return c.parent
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Command) mergePersistentFlags() {
|
func (c *Command) mergePersistentFlags() {
|
||||||
var rmerge func(x *Command)
|
var rmerge func(x *Command)
|
||||||
|
|
||||||
|
@ -809,7 +864,3 @@ func (c *Command) mergePersistentFlags() {
|
||||||
|
|
||||||
rmerge(c)
|
rmerge(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) Parent() *Command {
|
|
||||||
return c.parent
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue