cli.Main no longer calls SetOut or SetErr. SetOut also moved the usage and an unknown help topic, which cobra writes to stderr, onto stdout. execute now takes the command tree, so the tests build it, set its arguments and output streams, and run it; the exit line goes to the command's error stream, which outside a test is stderr as before. Model: opus-5-5
This commit is contained in:
+11
-12
@@ -4,8 +4,8 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// appname is the name the program reports in its logs and its version.
|
// appname is the name the program reports in its logs and its version.
|
||||||
@@ -13,23 +13,22 @@ const appname = "simplexcalc"
|
|||||||
|
|
||||||
// Main runs the command named on the command line and returns the exit
|
// Main runs the command named on the command line and returns the exit
|
||||||
// status for main to pass to os.Exit.
|
// status for main to pass to os.Exit.
|
||||||
|
//
|
||||||
|
// It leaves cobra's output streams at their defaults. cobra writes the
|
||||||
|
// usage and an unknown help topic to stderr, but SetOut moves them onto
|
||||||
|
// the stream it is given.
|
||||||
func Main(version string) int {
|
func Main(version string) int {
|
||||||
return execute(version, os.Args[1:], os.Stdout, os.Stderr)
|
return execute(rootCmd(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute is Main with the arguments and the output passed in, so that
|
// execute runs root and returns the exit status. It takes the command
|
||||||
// a test can supply them.
|
// so that a test can set its arguments and output streams first.
|
||||||
func execute(version string, args []string, stdout, stderr io.Writer) int {
|
func execute(root *cobra.Command) int {
|
||||||
root := rootCmd(version)
|
|
||||||
root.SetArgs(args)
|
|
||||||
root.SetOut(stdout)
|
|
||||||
root.SetErr(stderr)
|
|
||||||
|
|
||||||
err := root.Execute()
|
err := root.Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// cobra has already printed the error; this only sets the exit
|
// cobra has already printed the error; this only sets the exit
|
||||||
// status, which is what a supervisor and a shell script read.
|
// status, which is what a supervisor and a shell script read.
|
||||||
_, _ = fmt.Fprintln(stderr, "exiting: "+err.Error())
|
_, _ = fmt.Fprintln(root.ErrOrStderr(), "exiting: "+err.Error())
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ func TestVersionPrintsVersion(t *testing.T) {
|
|||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
status := cli.Execute("1.2.3", []string{"version"}, &stdout, &stderr)
|
root := cli.RootCmd("1.2.3")
|
||||||
|
root.SetArgs([]string{"version"})
|
||||||
|
root.SetOut(&stdout)
|
||||||
|
root.SetErr(&stderr)
|
||||||
|
|
||||||
|
status := cli.Execute(root)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
t.Fatalf("status = %d, want 0; stderr: %q", status, stderr.String())
|
t.Fatalf("status = %d, want 0; stderr: %q", status, stderr.String())
|
||||||
}
|
}
|
||||||
@@ -30,7 +35,12 @@ func TestUnknownCommandFails(t *testing.T) {
|
|||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
status := cli.Execute("1.2.3", []string{"frobnicate"}, &stdout, &stderr)
|
root := cli.RootCmd("1.2.3")
|
||||||
|
root.SetArgs([]string{"frobnicate"})
|
||||||
|
root.SetOut(&stdout)
|
||||||
|
root.SetErr(&stderr)
|
||||||
|
|
||||||
|
status := cli.Execute(root)
|
||||||
if status == 0 {
|
if status == 0 {
|
||||||
t.Fatal("status = 0, want non-zero")
|
t.Fatal("status = 0, want non-zero")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
// Execute is execute, exported for the external test package, which
|
// RootCmd and Execute are rootCmd and execute, exported for the external
|
||||||
// needs to supply the arguments and read the output.
|
// test package, which builds the command tree itself so that it can
|
||||||
|
// supply the arguments and read the output.
|
||||||
//
|
//
|
||||||
//nolint:gochecknoglobals // a test seam, not mutable state.
|
//nolint:gochecknoglobals // test seams, not mutable state.
|
||||||
var Execute = execute
|
var (
|
||||||
|
RootCmd = rootCmd
|
||||||
|
Execute = execute
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user