Skip to content

Commit

Permalink
Extending redirection to stdout, stderr, stdin
Browse files Browse the repository at this point in the history
  • Loading branch information
jleni authored and spf13 committed Jun 7, 2019
1 parent 5f23f55 commit 4a716d1
Showing 1 changed file with 61 additions and 8 deletions.
69 changes: 61 additions & 8 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ type Command struct {
// that we can use on every pflag set and children commands
globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName

// output is an output writer defined by user.
output io.Writer
// usageFunc is usage func defined by user.
usageFunc func(*Command) error
// usageTemplate is usage template defined by user.
Expand All @@ -195,6 +193,13 @@ type Command struct {
helpCommand *Command
// versionTemplate is the version template defined by user.
versionTemplate string

// inReader is a reader defined by the user that replaces stdin
inReader io.Reader
// outWriter is a writer defined by the user that replaces stdout
outWriter io.Writer
// errWriter is a writer defined by the user that replaces stderr
errWriter io.Writer
}

// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
Expand All @@ -206,7 +211,25 @@ func (c *Command) SetArgs(a []string) {
// SetOutput sets the destination for usage and error messages.
// If output is nil, os.Stderr is used.
func (c *Command) SetOutput(output io.Writer) {
c.output = output
c.outWriter = output
}

// SetOut sets the destination for usage messages.
// If newOut is nil, os.Stdout is used.
func (c *Command) SetOut(newOut io.Writer) {
c.outWriter = newOut
}

// SetErr sets the destination for error messages.
// If newErr is nil, os.Stderr is used.
func (c *Command) SetErr(newErr io.Writer) {
c.errWriter = newErr
}

// SetOut sets the source for input data
// If newIn is nil, os.Stdin is used.
func (c *Command) SetIn(newIn io.Reader) {
c.inReader = newIn
}

// SetUsageFunc sets usage function. Usage can be defined by application.
Expand Down Expand Up @@ -267,16 +290,46 @@ func (c *Command) OutOrStderr() io.Writer {
return c.getOut(os.Stderr)
}

// ErrOrStderr returns output to stderr
func (c *Command) ErrOrStderr() io.Writer {
return c.getErr(os.Stderr)
}

// ErrOrStderr returns output to stderr
func (c *Command) InOrStdin() io.Reader {
return c.getIn(os.Stdin)
}

func (c *Command) getOut(def io.Writer) io.Writer {
if c.output != nil {
return c.output
if c.outWriter != nil {
return c.outWriter
}
if c.HasParent() {
return c.parent.getOut(def)
}
return def
}

func (c *Command) getErr(def io.Writer) io.Writer {
if c.errWriter != nil {
return c.errWriter
}
if c.HasParent() {
return c.parent.getErr(def)
}
return def
}

func (c *Command) getIn(def io.Reader) io.Reader {
if c.inReader != nil {
return c.inReader
}
if c.HasParent() {
return c.parent.getIn(def)
}
return def
}

// UsageFunc returns either the function set by SetUsageFunc for this command
// or a parent, or it returns a default usage function.
func (c *Command) UsageFunc() (f func(*Command) error) {
Expand Down Expand Up @@ -331,11 +384,11 @@ func (c *Command) Help() error {

// UsageString return usage string.
func (c *Command) UsageString() string {
tmpOutput := c.output
tmpOutput := c.outWriter
bb := new(bytes.Buffer)
c.SetOutput(bb)
c.outWriter = bb
c.Usage()
c.output = tmpOutput
c.outWriter = tmpOutput
return bb.String()
}

Expand Down

0 comments on commit 4a716d1

Please sign in to comment.