fix(summer): send a delegate's stderr to the root's error writer through bonfire.ErrWriter (IN-13, quick-261028-rqd)
This commit is contained in:
@@ -53,18 +53,26 @@ func OnGlobals(fn func(Globals)) RootOption {
|
||||
// It accepts command values rather than a party registry to avoid an import cycle.
|
||||
// When out is the process stdout, the error block of Execute goes to stderr.
|
||||
func NewRoot(name string, commands []Command, out io.Writer, opts ...RootOption) (*cobra.Command, error) {
|
||||
root, err := NewRootIO(name, commands, os.Stdin, out, out, opts...)
|
||||
root, console, err := newRootIO(name, commands, os.Stdin, out, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if out == nil || out == os.Stdout {
|
||||
root.SetErr(os.Stderr)
|
||||
console.errStream = os.Stderr
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// NewRootIO is NewRoot with injected stdin/stdout/stderr for tests.
|
||||
func NewRootIO(name string, commands []Command, in io.Reader, out, errW io.Writer, opts ...RootOption) (*cobra.Command, error) {
|
||||
root, _, err := newRootIO(name, commands, in, out, errW, opts...)
|
||||
return root, err
|
||||
}
|
||||
|
||||
// newRootIO builds the root of NewRootIO and returns its console too, so
|
||||
// NewRoot can record where it moved the error stream.
|
||||
func newRootIO(name string, commands []Command, in io.Reader, out, errW io.Writer, opts ...RootOption) (*cobra.Command, *console, error) {
|
||||
if out == nil {
|
||||
out = os.Stdout
|
||||
}
|
||||
@@ -84,6 +92,7 @@ func NewRootIO(name string, commands []Command, in io.Reader, out, errW io.Write
|
||||
cfg.version = BuildVersion()
|
||||
}
|
||||
output := newConsole(in, out, errW, os.Getenv, nil, nil)
|
||||
output.errStream = errW
|
||||
root := &cobra.Command{
|
||||
Use: name,
|
||||
SilenceUsage: true,
|
||||
@@ -116,24 +125,24 @@ func NewRootIO(name string, commands []Command, in io.Reader, out, errW io.Write
|
||||
}
|
||||
for _, command := range commands {
|
||||
if seen[command.Name] {
|
||||
return nil, fmt.Errorf("%w: %q", ErrDuplicateCommand, command.Name)
|
||||
return nil, nil, fmt.Errorf("%w: %q", ErrDuplicateCommand, command.Name)
|
||||
}
|
||||
seen[command.Name] = true
|
||||
cmd, err := st.wrap(command, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
root.AddCommand(cmd)
|
||||
}
|
||||
|
||||
listCmd, err := st.wrap(st.listCommand(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
root.AddCommand(listCmd)
|
||||
helpCmd, err := st.wrap(st.helpCommand(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
root.SetHelpCommand(helpCmd)
|
||||
root.SetHelpFunc(func(*cobra.Command, []string) {
|
||||
@@ -160,7 +169,7 @@ func NewRootIO(name string, commands []Command, in io.Reader, out, errW io.Write
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return root, nil
|
||||
return root, output, nil
|
||||
}
|
||||
|
||||
// rootState is what the list, help and error rendering of one root share.
|
||||
|
||||
Reference in New Issue
Block a user