Fix CLI token set command

This commit is contained in:
2026-09-13 10:34:28 +02:00
parent 594d5d0150
commit 3d8d1e5a66
3 changed files with 67 additions and 5 deletions
+44
View File
@@ -112,6 +112,50 @@ func TestFormatDurationSpelling(t *testing.T) {
}
}
// A word the parser does not expect has to be refused, not ignored: the flag
// package stops at the first non-flag argument, so a command that accepted one
// would silently drop every option after it - including the one naming the
// file it writes.
func TestParseRefusesStrayArguments(t *testing.T) {
newSet := func() (*Set, *string, *bool) {
var listen string
var flagged bool
s := NewSet("test", "UNCENSORED_SEND_TEST_")
s.String(&listen, "listen", "l", "default", "ADDR", "listen address")
s.Bool(&flagged, "vanity", "", false, "a boolean")
return s, &listen, &flagged
}
for _, args := range [][]string{
{"--vanity", "false"}, // the value a boolean never takes
{"stray"}, // a word on its own
{"--vanity", "false", "-l", "here"}, // options after the stray word
} {
s, listen, _ := newSet()
err := s.Parse(args)
if err == nil {
t.Errorf("Parse(%q) was accepted; listen = %q", args, *listen)
continue
}
if !strings.Contains(err.Error(), "unexpected argument") {
t.Errorf("Parse(%q) failed with %v, which does not name the problem", args, err)
}
}
// The forms that are actually correct still parse.
for _, args := range [][]string{
{"--vanity=false"},
{"--vanity", "-l", "here"},
{"-l", "here"},
{},
} {
s, _, _ := newSet()
if err := s.Parse(args); err != nil {
t.Errorf("Parse(%q) = %v, want it accepted", args, err)
}
}
}
// The convention is: one hyphen for a letter, two for a word. It is enforced
// here because the stdlib flag package treats both forms as the same.
func TestHyphenConvention(t *testing.T) {
+13 -2
View File
@@ -42,7 +42,6 @@ func NewSet(name, envPrefix string) *Set {
return s
}
func (s *Set) Args() []string { return s.fs.Args() }
func (s *Set) SetOutput(w io.Writer) { s.fs.SetOutput(w) }
func (s *Set) register(sp *spec) { s.specs = append(s.specs, sp) }
func (s *Set) note(long, short string) {
@@ -208,7 +207,19 @@ func (s *Set) Parse(args []string) error {
if err := s.checkConvention(args); err != nil {
return err
}
return s.fs.Parse(args)
if err := s.fs.Parse(args); err != nil {
return err
}
// A stray word is never harmless: the flag package stops parsing at the
// first non-flag argument, so every option after it is dropped in silence.
// Writing a boolean as "--vanity false" is the way this bites - it sets
// the flag to true and then discards the --data that says which file to
// write, leaving a cheerful message about the opposite of what was meant.
if extra := s.fs.Args(); len(extra) > 0 {
return fmt.Errorf("unexpected argument %q: an option's value attaches with %q, as in --name=value, and any positional argument comes first",
extra[0], "=")
}
return nil
}
// Changed reports whether an option was given on the command line.