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
|
||||
hiddens map[string]struct{}
|
||||
completions complete.Flags
|
||||
ui cli.Ui
|
||||
}
|
||||
|
||||
// NewFlagSets creates a new flag sets.
|
||||
|
@ -564,6 +565,7 @@ func NewFlagSets(ui cli.Ui) *FlagSets {
|
|||
mainSet: mainSet,
|
||||
hiddens: make(map[string]struct{}),
|
||||
completions: complete.Flags{},
|
||||
ui: ui,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -582,8 +584,16 @@ func (f *FlagSets) Completions() complete.Flags {
|
|||
}
|
||||
|
||||
// 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 {
|
||||
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.
|
||||
|
@ -603,10 +613,10 @@ func (f *FlagSets) Visit(fn func(*flag.Flag)) {
|
|||
}
|
||||
|
||||
// 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
|
||||
|
||||
for _, set := range fs.flagSets {
|
||||
for _, set := range f.flagSets {
|
||||
printFlagTitle(&out, set.name+":")
|
||||
set.VisitAll(func(f *flag.Flag) {
|
||||
// Skip any hidden flags
|
||||
|
|
|
@ -292,3 +292,19 @@ func parseFlagFile(raw string) (string, error) {
|
|||
|
||||
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/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"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