Skip to content

Commit 8752293

Browse files
committed
command: add IsFlagSet helper to Env
1 parent 35b2cdb commit 8752293

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

command.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,18 @@ func (e *Env) parseFlags(rawArgs []string) error {
180180
return nil
181181
}
182182

183+
// IsFlagSet reports whether the specified flag is set on e. It can report true
184+
// only after flags have been parsed.
185+
func (e *Env) IsFlagSet(name string) bool {
186+
var isSet bool
187+
e.Command.Flags.Visit(func(f *flag.Flag) {
188+
if f.Name == name {
189+
isSet = true
190+
}
191+
})
192+
return isSet
193+
}
194+
183195
// C carries the description and invocation function for a command.
184196
//
185197
// To process a command-line, the [Run] function walks through the argument

parse_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,58 @@ func newTestRoot(run func(*command.Env) error) *command.C {
5454
}
5555
}
5656

57+
func TestEnv_IsFlagSet(t *testing.T) {
58+
59+
checkFlagSet := func(t *testing.T, name string, want bool) func(*command.Env) error {
60+
return func(env *command.Env) error {
61+
if ok := env.IsFlagSet(name); ok != want {
62+
t.Errorf("IsFlagSet(%q): got %v, want %v (args=%+q)", name, ok, want, env.Args)
63+
}
64+
return nil
65+
}
66+
}
67+
68+
var stringFlag string
69+
var boolFlag bool
70+
tests := []struct {
71+
flagName string
72+
args string
73+
wantSet bool
74+
}{
75+
{"string", "", false},
76+
{"bool", "", false},
77+
{"string", "a b c", false},
78+
{"bool", "a b c", false},
79+
{"string", "--string new", true},
80+
{"string", "--string new a b c", true},
81+
{"string", "a b -string new c", true}, // merged is default
82+
{"bool", "--bool", true},
83+
{"bool", "-bool a b c", true},
84+
{"bool", "a -bool b c", true}, // merged is default
85+
{"string", "-string x -bool a b c", true},
86+
{"string", "-bool -string x a", true},
87+
{"bool", "-string x -bool b", true},
88+
}
89+
90+
for _, tc := range tests {
91+
t.Run(fmt.Sprintf("%s_%v", tc.flagName, tc.wantSet), func(t *testing.T) {
92+
root := &command.C{
93+
Name: "root",
94+
SetFlags: func(_ *command.Env, fs *flag.FlagSet) {
95+
fs.StringVar(&stringFlag, "string", "old", "String value")
96+
fs.BoolVar(&boolFlag, "bool", false, "Boolean value")
97+
},
98+
Run: checkFlagSet(t, tc.flagName, tc.wantSet),
99+
}
100+
args := strings.Fields(tc.args)
101+
if err := command.Run(root.NewEnv(nil), args); err != nil {
102+
t.Errorf("Command failed; %v", err)
103+
}
104+
})
105+
}
106+
107+
}
108+
57109
func TestParse(t *testing.T) {
58110
wantArgs := []string{"x", "y"}
59111
root := newTestRoot(func(env *command.Env) error {

0 commit comments

Comments
 (0)