Merge pull request #305 from fabianofranz/expose_out

Fixes how we expose help and usage and expose output without making assumptions
This commit is contained in:
Eric Paris 2016-07-15 19:55:49 -04:00 committed by GitHub
commit b24564e919
2 changed files with 16 additions and 33 deletions

View file

@ -646,7 +646,7 @@ func TestSubcommandArgEvaluation(t *testing.T) {
second := &Command{ second := &Command{
Use: "second", Use: "second",
Run: func(cmd *Command, args []string) { Run: func(cmd *Command, args []string) {
fmt.Fprintf(cmd.getOutOrStdout(), "%v", args) fmt.Fprintf(cmd.OutOrStdout(), "%v", args)
}, },
} }
first.AddCommand(second) first.AddCommand(second)

View file

@ -110,7 +110,7 @@ type Command struct {
flagErrorBuf *bytes.Buffer flagErrorBuf *bytes.Buffer
args []string // actual args parsed from flags args []string // actual args parsed from flags
output *io.Writer // nil means stderr; use Out() method instead output *io.Writer // out writer if set in SetOutput(w)
usageFunc func(*Command) error // Usage can be defined by application usageFunc func(*Command) error // Usage can be defined by application
usageTemplate string // Can be defined by Application usageTemplate string // Can be defined by Application
helpTemplate string // Can be defined by Application helpTemplate string // Can be defined by Application
@ -176,11 +176,11 @@ func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string
} }
} }
func (c *Command) getOutOrStdout() io.Writer { func (c *Command) OutOrStdout() io.Writer {
return c.getOut(os.Stdout) return c.getOut(os.Stdout)
} }
func (c *Command) getOutOrStderr() io.Writer { func (c *Command) OutOrStderr() io.Writer {
return c.getOut(os.Stderr) return c.getOut(os.Stderr)
} }
@ -205,7 +205,8 @@ func (c *Command) UsageFunc() (f func(*Command) error) {
return c.parent.UsageFunc() return c.parent.UsageFunc()
} }
return func(c *Command) error { return func(c *Command) error {
err := c.Usage() c.mergePersistentFlags()
err := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)
if err != nil { if err != nil {
c.Println(err) c.Println(err)
} }
@ -214,7 +215,7 @@ func (c *Command) UsageFunc() (f func(*Command) error) {
} }
// HelpFunc returns either the function set by SetHelpFunc for this command // HelpFunc returns either the function set by SetHelpFunc for this command
// or a parent, or it returns a function which calls c.Help() // or a parent, or it returns a function with default help behavior
func (c *Command) HelpFunc() func(*Command, []string) { func (c *Command) HelpFunc() func(*Command, []string) {
cmd := c cmd := c
for cmd != nil { for cmd != nil {
@ -224,36 +225,19 @@ func (c *Command) HelpFunc() func(*Command, []string) {
cmd = cmd.parent cmd = cmd.parent
} }
return func(*Command, []string) { return func(*Command, []string) {
err := c.Help() c.mergePersistentFlags()
err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)
if err != nil { if err != nil {
c.Println(err) c.Println(err)
} }
} }
} }
// Output the usage for the command
// Used when a user provides invalid input
// Can be defined by user by overriding UsageFunc
func (c *Command) Usage() error {
c.mergePersistentFlags()
err := tmpl(c.getOutOrStderr(), c.UsageTemplate(), c)
return err
}
// Output the help for the command
// Used when a user calls help [command]
// by the default HelpFunc in the commander
func (c *Command) Help() error {
c.mergePersistentFlags()
err := tmpl(c.getOutOrStdout(), c.HelpTemplate(), c)
return err
}
func (c *Command) UsageString() string { func (c *Command) UsageString() string {
tmpOutput := c.output tmpOutput := c.output
bb := new(bytes.Buffer) bb := new(bytes.Buffer)
c.SetOutput(bb) c.SetOutput(bb)
c.Usage() c.UsageFunc()(c)
c.output = tmpOutput c.output = tmpOutput
return bb.String() return bb.String()
} }
@ -736,10 +720,9 @@ func (c *Command) initHelpCmd() {
cmd, _, e := c.Root().Find(args) cmd, _, e := c.Root().Find(args)
if cmd == nil || e != nil { if cmd == nil || e != nil {
c.Printf("Unknown help topic %#q.", args) c.Printf("Unknown help topic %#q.", args)
c.Root().Usage() c.Root().UsageFunc()(cmd)
} else { } else {
helpFunc := cmd.HelpFunc() cmd.HelpFunc()(cmd, args)
helpFunc(cmd, args)
} }
}, },
} }
@ -833,18 +816,18 @@ main:
} }
} }
// Print is a convenience method to Print to the defined output // Print is a convenience method to Print to the defined output, fallback to Stderr if not set
func (c *Command) Print(i ...interface{}) { func (c *Command) Print(i ...interface{}) {
fmt.Fprint(c.getOutOrStderr(), i...) fmt.Fprint(c.OutOrStderr(), i...)
} }
// Println is a convenience method to Println to the defined output // Println is a convenience method to Println to the defined output, fallback to Stderr if not set
func (c *Command) Println(i ...interface{}) { func (c *Command) Println(i ...interface{}) {
str := fmt.Sprintln(i...) str := fmt.Sprintln(i...)
c.Print(str) c.Print(str)
} }
// Printf is a convenience method to Printf to the defined output // Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set
func (c *Command) Printf(format string, i ...interface{}) { func (c *Command) Printf(format string, i ...interface{}) {
str := fmt.Sprintf(format, i...) str := fmt.Sprintf(format, i...)
c.Print(str) c.Print(str)