Restores the ability to fetch local only flags

This commit is contained in:
fabianofranz 2015-01-29 18:55:29 -02:00 committed by spf13
parent e1e66f7b4e
commit efb045ec60
1 changed files with 62 additions and 11 deletions

View File

@ -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.
@ -200,8 +200,10 @@ 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 }}
@ -682,7 +684,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)
@ -695,7 +697,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)
@ -707,6 +725,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)
@ -717,7 +758,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()
} }
@ -727,6 +768,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)
@ -766,6 +817,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)
@ -784,7 +839,3 @@ func (c *Command) mergePersistentFlags() {
rmerge(c) rmerge(c)
} }
func (c *Command) Parent() *Command {
return c.parent
}