@@ -60,6 +60,7 @@ type Env struct {
6060 cancel context.CancelCauseFunc
6161 skipMerge bool // default: merge flags later in the argument list
6262 hflag HelpFlags // default: no unlisted commands, no private flags
63+ didParse bool // whether ParseFlags was called
6364}
6465
6566// Context returns the context associated with e. If e does not have its own
@@ -153,13 +154,25 @@ func (e *Env) Write(data []byte) (int, error) {
153154 return e .output ().Write (data )
154155}
155156
156- // parseFlags parses flags from rawArgs using the flag set from env.Command.
157+ // ParseFlags parses flags from env.Args using the flag set from env.Command.
157158// If parsing succeeds, it updates env.Args.
158- // If the command specifies custom flags, this is a no-op without error.
159- func (e * Env ) parseFlags (rawArgs []string ) error {
160- if e .Command .CustomFlags {
159+ // If flags were already parsed, ParseFlags reports nil.
160+ //
161+ // Note: This is done automatically if env.Command does not set CustomFlags.
162+ // It is safe but unnecessary to call it explicitly, but it is provided to
163+ // allow an Init hook to use it.
164+ func (e * Env ) ParseFlags () error {
165+ if e .didParse {
161166 return nil
162167 }
168+ e .didParse = true
169+ return e .parseFlagsInternal (e .Args )
170+ }
171+
172+ // parseFlagsInternal parses flags from rawArgs using the flag set from env.Command.
173+ // If parsing succeeds, it updates env.Args.
174+ // Note this internal helper does NOT mark env.didParse.
175+ func (e * Env ) parseFlagsInternal (rawArgs []string ) error {
163176 e .Command .Flags .Usage = func () {}
164177 e .Command .Flags .SetOutput (io .Discard )
165178 toParse := rawArgs
@@ -392,8 +405,11 @@ func Run(env *Env, rawArgs []string) (err error) {
392405
393406 // Unless this command does custom flag parsing, parse the arguments and
394407 // check for errors before passing control to the handler.
395- if err := env .parseFlags (rawArgs ); err != nil {
396- return err
408+ if ! env .Command .CustomFlags {
409+ if err := env .parseFlagsInternal (rawArgs ); err != nil {
410+ return err
411+ }
412+ env .didParse = true // in case Init calls ParseFlags anyway
397413 }
398414
399415 if cmd .Init != nil {
0 commit comments