mirror of
https://github.com/spf13/cobra
synced 2024-05-19 11:16:42 +00:00
Compare commits
5 commits
69fccc1c88
...
e35bf966fd
Author | SHA1 | Date | |
---|---|---|---|
e35bf966fd | |||
0c72800b8d | |||
c5dacb3ea4 | |||
285460dca6 | |||
4955da7c11 |
5
.github/workflows/test.yml
vendored
5
.github/workflows/test.yml
vendored
|
@ -43,13 +43,13 @@ jobs:
|
|||
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.20'
|
||||
go-version: '^1.21'
|
||||
check-latest: true
|
||||
cache: true
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: golangci/golangci-lint-action@v3.6.0
|
||||
- uses: golangci/golangci-lint-action@v3.7.0
|
||||
with:
|
||||
version: latest
|
||||
args: --verbose
|
||||
|
@ -67,6 +67,7 @@ jobs:
|
|||
- 18
|
||||
- 19
|
||||
- 20
|
||||
- 21
|
||||
name: '${{ matrix.platform }} | 1.${{ matrix.go }}.x'
|
||||
runs-on: ${{ matrix.platform }}-latest
|
||||
steps:
|
||||
|
|
74
command.go
74
command.go
|
@ -181,6 +181,9 @@ type Command struct {
|
|||
// versionTemplate is the version template defined by user.
|
||||
versionTemplate string
|
||||
|
||||
// errPrefix is the error message prefix defined by user.
|
||||
errPrefix 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
|
||||
|
@ -188,6 +191,11 @@ type Command struct {
|
|||
// errWriter is a writer defined by the user that replaces stderr
|
||||
errWriter io.Writer
|
||||
|
||||
// outFallbackWriter is a writer defined by the user that is used if outWriter is nil
|
||||
outFallbackWriter io.Writer
|
||||
// errFallbackWriter is a writer defined by the user that is used if errWriter is nil
|
||||
errFallbackWriter io.Writer
|
||||
|
||||
// FParseErrWhitelist flag parse errors to be ignored
|
||||
FParseErrWhitelist FParseErrWhitelist
|
||||
|
||||
|
@ -279,16 +287,30 @@ func (c *Command) SetOutput(output io.Writer) {
|
|||
|
||||
// SetOut sets the destination for usage messages.
|
||||
// If newOut is nil, os.Stdout is used.
|
||||
// Deprecated: Use SetOutFallback and/or SetErrFallback instead (see https://github.com/spf13/cobra/issues/1708)
|
||||
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.
|
||||
// Deprecated: Use SetOutFallback and/or SetErrFallback instead (see https://github.com/spf13/cobra/issues/1708)
|
||||
func (c *Command) SetErr(newErr io.Writer) {
|
||||
c.errWriter = newErr
|
||||
}
|
||||
|
||||
// SetOutFallback sets the destination for usage messages when SetOut() was not used.
|
||||
// If newOut is nil, os.Stdout is used.
|
||||
func (c *Command) SetOutFallback(newOut io.Writer) {
|
||||
c.outFallbackWriter = newOut
|
||||
}
|
||||
|
||||
// SetErrFallback sets the destination for error messages when SetErr() was not used.
|
||||
// If newErr is nil, os.Stderr is used.
|
||||
func (c *Command) SetErrFallback(newErr io.Writer) {
|
||||
c.errFallbackWriter = newErr
|
||||
}
|
||||
|
||||
// SetIn sets the source for input data
|
||||
// If newIn is nil, os.Stdin is used.
|
||||
func (c *Command) SetIn(newIn io.Reader) {
|
||||
|
@ -346,6 +368,11 @@ func (c *Command) SetVersionTemplate(s string) {
|
|||
c.versionTemplate = s
|
||||
}
|
||||
|
||||
// SetErrPrefix sets error message prefix to be used. Application can use it to set custom prefix.
|
||||
func (c *Command) SetErrPrefix(s string) {
|
||||
c.errPrefix = s
|
||||
}
|
||||
|
||||
// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.
|
||||
// The user should not have a cyclic dependency on commands.
|
||||
func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {
|
||||
|
@ -363,9 +390,10 @@ func (c *Command) OutOrStdout() io.Writer {
|
|||
return c.getOut(os.Stdout)
|
||||
}
|
||||
|
||||
// OutOrStderr returns output to stderr
|
||||
// OutOrStderr returns output to stderr.
|
||||
// Deprecated: Use OutOrStdout or ErrOrStderr instead
|
||||
func (c *Command) OutOrStderr() io.Writer {
|
||||
return c.getOut(os.Stderr)
|
||||
return c.getOutFallbackToErr(os.Stderr)
|
||||
}
|
||||
|
||||
// ErrOrStderr returns output to stderr
|
||||
|
@ -382,6 +410,9 @@ func (c *Command) getOut(def io.Writer) io.Writer {
|
|||
if c.outWriter != nil {
|
||||
return c.outWriter
|
||||
}
|
||||
if c.outFallbackWriter != nil {
|
||||
return c.outFallbackWriter
|
||||
}
|
||||
if c.HasParent() {
|
||||
return c.parent.getOut(def)
|
||||
}
|
||||
|
@ -392,12 +423,31 @@ func (c *Command) getErr(def io.Writer) io.Writer {
|
|||
if c.errWriter != nil {
|
||||
return c.errWriter
|
||||
}
|
||||
if c.errFallbackWriter != nil {
|
||||
return c.errFallbackWriter
|
||||
}
|
||||
if c.HasParent() {
|
||||
return c.parent.getErr(def)
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// getOutFallbackToErr should only be used inside OutOrStderr.
|
||||
// Deprecated: this function exists to allow for backwards compatibility only
|
||||
// (see https://github.com/spf13/cobra/issues/1708)
|
||||
func (c *Command) getOutFallbackToErr(def io.Writer) io.Writer {
|
||||
if c.outWriter != nil {
|
||||
return c.outWriter
|
||||
}
|
||||
if c.errFallbackWriter != nil {
|
||||
return c.errFallbackWriter
|
||||
}
|
||||
if c.HasParent() {
|
||||
return c.parent.getOutFallbackToErr(def)
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func (c *Command) getIn(def io.Reader) io.Reader {
|
||||
if c.inReader != nil {
|
||||
return c.inReader
|
||||
|
@ -595,6 +645,18 @@ func (c *Command) VersionTemplate() string {
|
|||
`
|
||||
}
|
||||
|
||||
// ErrPrefix return error message prefix for the command
|
||||
func (c *Command) ErrPrefix() string {
|
||||
if c.errPrefix != "" {
|
||||
return c.errPrefix
|
||||
}
|
||||
|
||||
if c.HasParent() {
|
||||
return c.parent.ErrPrefix()
|
||||
}
|
||||
return "Error:"
|
||||
}
|
||||
|
||||
func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||
flag := fs.Lookup(name)
|
||||
if flag == nil {
|
||||
|
@ -752,7 +814,9 @@ func (c *Command) findNext(next string) *Command {
|
|||
}
|
||||
|
||||
if len(matches) == 1 {
|
||||
return matches[0]
|
||||
// Temporarily disable gosec G602, which produces a false positive.
|
||||
// See https://github.com/securego/gosec/issues/1005.
|
||||
return matches[0] // #nosec G602
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1048,7 +1112,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
c = cmd
|
||||
}
|
||||
if !c.SilenceErrors {
|
||||
c.PrintErrln("Error:", err.Error())
|
||||
c.PrintErrln(c.ErrPrefix(), err.Error())
|
||||
c.PrintErrf("Run '%v --help' for usage.\n", c.CommandPath())
|
||||
}
|
||||
return c, err
|
||||
|
@ -1077,7 +1141,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
// If root command has SilenceErrors flagged,
|
||||
// all subcommands should respect it
|
||||
if !cmd.SilenceErrors && !c.SilenceErrors {
|
||||
c.PrintErrln("Error:", err.Error())
|
||||
c.PrintErrln(cmd.ErrPrefix(), err.Error())
|
||||
}
|
||||
|
||||
// If root command has SilenceUsage flagged,
|
||||
|
|
|
@ -1099,6 +1099,39 @@ func TestShorthandVersionTemplate(t *testing.T) {
|
|||
checkStringContains(t, output, "customized version: 1.0.0")
|
||||
}
|
||||
|
||||
func TestRootErrPrefixExecutedOnSubcommand(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||
rootCmd.SetErrPrefix("root error prefix:")
|
||||
rootCmd.AddCommand(&Command{Use: "sub", Run: emptyRun})
|
||||
|
||||
output, err := executeCommand(rootCmd, "sub", "--unknown-flag")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error")
|
||||
}
|
||||
|
||||
checkStringContains(t, output, "root error prefix: unknown flag: --unknown-flag")
|
||||
}
|
||||
|
||||
func TestRootAndSubErrPrefix(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root", Run: emptyRun}
|
||||
subCmd := &Command{Use: "sub", Run: emptyRun}
|
||||
rootCmd.AddCommand(subCmd)
|
||||
rootCmd.SetErrPrefix("root error prefix:")
|
||||
subCmd.SetErrPrefix("sub error prefix:")
|
||||
|
||||
if output, err := executeCommand(rootCmd, "--unknown-root-flag"); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
} else {
|
||||
checkStringContains(t, output, "root error prefix: unknown flag: --unknown-root-flag")
|
||||
}
|
||||
|
||||
if output, err := executeCommand(rootCmd, "sub", "--unknown-sub-flag"); err == nil {
|
||||
t.Errorf("Expected error")
|
||||
} else {
|
||||
checkStringContains(t, output, "sub error prefix: unknown flag: --unknown-sub-flag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionFlagExecutedOnSubcommand(t *testing.T) {
|
||||
rootCmd := &Command{Use: "root", Version: "1.0.0"}
|
||||
rootCmd.AddCommand(&Command{Use: "sub", Run: emptyRun})
|
||||
|
|
|
@ -596,6 +596,12 @@ Running an application with the '--version' flag will print the version to stdou
|
|||
the version template. The template can be customized using the
|
||||
`cmd.SetVersionTemplate(s string)` function.
|
||||
|
||||
## Error Message Prefix
|
||||
|
||||
Cobra prints an error message when receiving a non-nil error value.
|
||||
The default error message is `Error: <error contents>`.
|
||||
The Prefix, `Error:` can be customized using the `cmd.SetErrPrefix(s string)` function.
|
||||
|
||||
## PreRun and PostRun Hooks
|
||||
|
||||
It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions are run in the following order:
|
||||
|
|
Loading…
Reference in a new issue