Added a small utility method to display warnings when parsing command arguments. (#16441)
* Added a small utility method to display warnings when parsing command arguments Will print warning if flag is passed after arguments e.g. vault <command> -a b -c In this example -c will be interpreted as an argument which may be misleading
This commit is contained in:
parent
1b1c6fe168
commit
aa3e1c8a2f
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
cli: CLI commands will print a warning if flags will be ignored because they are passed after positional arguments.
|
||||||
|
```
|
|
@ -549,6 +549,7 @@ type FlagSets struct {
|
||||||
mainSet *flag.FlagSet
|
mainSet *flag.FlagSet
|
||||||
hiddens map[string]struct{}
|
hiddens map[string]struct{}
|
||||||
completions complete.Flags
|
completions complete.Flags
|
||||||
|
ui cli.Ui
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFlagSets creates a new flag sets.
|
// NewFlagSets creates a new flag sets.
|
||||||
|
@ -564,6 +565,7 @@ func NewFlagSets(ui cli.Ui) *FlagSets {
|
||||||
mainSet: mainSet,
|
mainSet: mainSet,
|
||||||
hiddens: make(map[string]struct{}),
|
hiddens: make(map[string]struct{}),
|
||||||
completions: complete.Flags{},
|
completions: complete.Flags{},
|
||||||
|
ui: ui,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,8 +584,16 @@ func (f *FlagSets) Completions() complete.Flags {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses the given flags, returning any errors.
|
// Parse parses the given flags, returning any errors.
|
||||||
|
// Warnings, if any, regarding the arguments format are sent to stdout
|
||||||
func (f *FlagSets) Parse(args []string) error {
|
func (f *FlagSets) Parse(args []string) error {
|
||||||
return f.mainSet.Parse(args)
|
err := f.mainSet.Parse(args)
|
||||||
|
|
||||||
|
warnings := generateFlagWarnings(f.Args())
|
||||||
|
if warnings != "" {
|
||||||
|
f.ui.Warn(warnings)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsed reports whether the command-line flags have been parsed.
|
// Parsed reports whether the command-line flags have been parsed.
|
||||||
|
@ -603,10 +613,10 @@ func (f *FlagSets) Visit(fn func(*flag.Flag)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Help builds custom help for this command, grouping by flag set.
|
// Help builds custom help for this command, grouping by flag set.
|
||||||
func (fs *FlagSets) Help() string {
|
func (f *FlagSets) Help() string {
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
|
|
||||||
for _, set := range fs.flagSets {
|
for _, set := range f.flagSets {
|
||||||
printFlagTitle(&out, set.name+":")
|
printFlagTitle(&out, set.name+":")
|
||||||
set.VisitAll(func(f *flag.Flag) {
|
set.VisitAll(func(f *flag.Flag) {
|
||||||
// Skip any hidden flags
|
// Skip any hidden flags
|
||||||
|
|
|
@ -292,3 +292,19 @@ func parseFlagFile(raw string) (string, error) {
|
||||||
|
|
||||||
return raw, nil
|
return raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateFlagWarnings(args []string) string {
|
||||||
|
var trailingFlags []string
|
||||||
|
for _, arg := range args {
|
||||||
|
if strings.HasPrefix(arg, "-") {
|
||||||
|
trailingFlags = append(trailingFlags, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(trailingFlags) > 0 {
|
||||||
|
return fmt.Sprintf("Flags must be provided before positional arguments. "+
|
||||||
|
"The following arguments will not be parsed as flags: [%s]", strings.Join(trailingFlags, ","))
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -209,3 +210,48 @@ func TestParseFlagFile(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArgWarnings(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
args []string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]string{"a", "b", "c"},
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"a", "-b"},
|
||||||
|
"-b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"a", "--b"},
|
||||||
|
"--b",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"a-b", "-c"},
|
||||||
|
"-c",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"a", "-b-c"},
|
||||||
|
"-b-c",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-a", "b"},
|
||||||
|
"-a",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
tc := tc
|
||||||
|
|
||||||
|
t.Run(tc.expected, func(t *testing.T) {
|
||||||
|
warnings := generateFlagWarnings(tc.args)
|
||||||
|
if !strings.Contains(warnings, tc.expected) {
|
||||||
|
t.Fatalf("expected %s to contain %s", warnings, tc.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue