From 72c059b6bc966b8702e339c46ffd830a85ddb372 Mon Sep 17 00:00:00 2001 From: seanseannery Date: Sat, 7 Mar 2026 16:49:35 -0800 Subject: [PATCH] fix(flags): parse all flags regardless of help flag position Strip -h, --help, and -? from args before pflag parsing so that flags appearing after the help flag are still parsed. Previously --help -D would short-circuit pflag and discard -D. --- internal/flag_parser.go | 32 ++++++++++++-------------------- internal/flag_parser_test.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/internal/flag_parser.go b/internal/flag_parser.go index cae1599..5a20a96 100644 --- a/internal/flag_parser.go +++ b/internal/flag_parser.go @@ -64,33 +64,25 @@ Flags:`) fs.PrintDefaults() } - // -? is not a valid pflag name; strip it before fs.Parse so other flags - // (like -D) are still parsed and returned alongside ErrHelp. - helpQuestion := false + // Strip all help tokens (-h, --help, -?) before fs.Parse so that pflag + // does not short-circuit and skip flags that appear after the help flag + // (e.g. "--help -D /path" must still parse -D). + helpRequested := false + filtered := make([]string, 0, len(osArgs)) for _, a := range osArgs { - if a == "-?" { - helpQuestion = true - break + switch a { + case "-h", "--help", "-?": + helpRequested = true + default: + filtered = append(filtered, a) } } - if helpQuestion { - filtered := make([]string, 0, len(osArgs)) - for _, a := range osArgs { - if a != "-?" { - filtered = append(filtered, a) - } - } - osArgs = filtered - } - if err := fs.Parse(osArgs); err != nil { - if errors.Is(err, pflag.ErrHelp) { - return OpsFlags{Directory: *dir, DryRun: *dryRun, List: *list, Silent: *silent, Version: *ver}, nil, ErrHelp - } + if err := fs.Parse(filtered); err != nil { return OpsFlags{}, nil, err } - if helpQuestion { + if helpRequested { fs.Usage() return OpsFlags{Directory: *dir, DryRun: *dryRun, List: *list, Silent: *silent, Version: *ver}, nil, ErrHelp } diff --git a/internal/flag_parser_test.go b/internal/flag_parser_test.go index ba9fe34..fe3de6e 100644 --- a/internal/flag_parser_test.go +++ b/internal/flag_parser_test.go @@ -143,6 +143,24 @@ func TestParseOpsFlags(t *testing.T) { wantFlags: OpsFlags{Directory: "/some/path"}, wantErr: ErrHelp, }, + { + name: "--help before -D preserves Directory", + input: []string{"--help", "-D", "/some/path"}, + wantFlags: OpsFlags{Directory: "/some/path"}, + wantErr: ErrHelp, + }, + { + name: "-h before -D preserves Directory", + input: []string{"-h", "-D", "/some/path"}, + wantFlags: OpsFlags{Directory: "/some/path"}, + wantErr: ErrHelp, + }, + { + name: "-? before -D preserves Directory", + input: []string{"-?", "-D", "/some/path"}, + wantFlags: OpsFlags{Directory: "/some/path"}, + wantErr: ErrHelp, + }, { name: "-D with empty string value", input: []string{"-D", "", "prod", "cmd"},