Adding support for a custom output, default to stderr

This commit is contained in:
spf13 2013-09-11 09:51:24 -04:00
parent 8d87882095
commit 6067837866

View File

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
"io"
"os" "os"
"strings" "strings"
) )
@ -32,13 +33,13 @@ type Commander struct {
Command Command
args []string args []string
output io.Writer // nil means stderr; use out() accessor
} }
// Provide the user with a new commander. // Provide the user with a new commander.
// Not of a lot of value today, was intended to do more than just
// create a new commander.
func NewCommander() (c *Commander) { func NewCommander() (c *Commander) {
c = new(Commander) c = new(Commander)
c.cmdr = c
return return
} }
@ -65,6 +66,24 @@ func (c *Commander) Execute() (err error) {
return return
} }
func (c *Commander) out() io.Writer {
if c.output == nil {
return os.Stderr
}
return c.output
}
//Print to out
func (c *Commander) POut(i ...interface{}) {
fmt.Fprint(c.out(), i...)
}
// SetOutput sets the destination for usage and error messages.
// If output is nil, os.Stderr is used.
func (c *Commander) SetOutput(output io.Writer) {
c.output = output
}
// Command is just that, a command for your application. // Command is just that, a command for your application.
// eg. 'go run' ... 'run' is the command. Cobra requires // eg. 'go run' ... 'run' is the command. Cobra requires
// you to define the usage and description as part of your command // you to define the usage and description as part of your command
@ -90,7 +109,7 @@ type Command struct {
// Parent Command for this command // Parent Command for this command
parent *Command parent *Command
// Commander // Commander
//cmdr *Commander cmdr *Commander
flagErrorBuf *bytes.Buffer flagErrorBuf *bytes.Buffer
} }
@ -151,10 +170,25 @@ func (c *Command) AddCommand(cmds ...*Command) {
panic("Command can't be a child of itself") panic("Command can't be a child of itself")
} }
cmds[i].parent = c cmds[i].parent = c
cmds[i].cmdr = cmds[i].parent.cmdr
c.commands = append(c.commands, x) c.commands = append(c.commands, x)
} }
} }
func (c *Command) Print(i ...interface{}) {
c.cmdr.POut(i...)
}
func (c *Command) Println(i ...interface{}) {
str := fmt.Sprintln(i...)
c.Print(str)
}
func (c *Command) Printf(format string, i ...interface{}) {
str := fmt.Sprintf(format, i...)
c.Print(str)
}
// The full usage for a given command (including parents) // The full usage for a given command (including parents)
func (c *Command) Usage(depth ...int) string { func (c *Command) Usage(depth ...int) string {
i := 0 i := 0
@ -174,23 +208,23 @@ func (c *Command) Usage(depth ...int) string {
// For use in determining which flags have been assigned to which commands // For use in determining which flags have been assigned to which commands
// and which persist // and which persist
func (c *Command) DebugFlags() { func (c *Command) DebugFlags() {
fmt.Println("DebugFlags called on", c.Name()) c.Println("DebugFlags called on", c.Name())
var debugflags func(*Command) var debugflags func(*Command)
debugflags = func(x *Command) { debugflags = func(x *Command) {
if x.HasFlags() || x.HasPersistentFlags() { if x.HasFlags() || x.HasPersistentFlags() {
fmt.Println(x.Name()) c.Println(x.Name())
} }
if x.HasFlags() { if x.HasFlags() {
x.flags.VisitAll(func(f *flag.Flag) { x.flags.VisitAll(func(f *flag.Flag) {
if x.HasPersistentFlags() { if x.HasPersistentFlags() {
if x.persistentFlag(f.Name) == nil { if x.persistentFlag(f.Name) == nil {
fmt.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]") c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
} else { } else {
fmt.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]") c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [LP]")
} }
} else { } else {
fmt.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]") c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [L]")
} }
}) })
} }
@ -198,14 +232,14 @@ func (c *Command) DebugFlags() {
x.pflags.VisitAll(func(f *flag.Flag) { x.pflags.VisitAll(func(f *flag.Flag) {
if x.HasFlags() { if x.HasFlags() {
if x.flags.Lookup(f.Name) == nil { if x.flags.Lookup(f.Name) == nil {
fmt.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]") c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
} }
} else { } else {
fmt.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]") c.Println(" -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, " [P]")
} }
}) })
} }
fmt.Println(x.flagErrorBuf) c.Println(x.flagErrorBuf)
if x.HasSubCommands() { if x.HasSubCommands() {
for _, y := range x.commands { for _, y := range x.commands {
debugflags(y) debugflags(y)
@ -219,10 +253,10 @@ func (c *Command) DebugFlags() {
// Usage prints the usage details to the standard output. // Usage prints the usage details to the standard output.
func (c *Command) PrintUsage() { func (c *Command) PrintUsage() {
if c.Runnable() { if c.Runnable() {
fmt.Printf("usage: %s\n\n", c.Usage()) c.Printf("usage: %s\n\n", c.Usage())
} }
fmt.Println(strings.Trim(c.Long, "\n")) c.Println(strings.Trim(c.Long, "\n"))
} }
// Name returns the command's name: the first word in the use line. // Name returns the command's name: the first word in the use line.