--log-level and --config are pre-parsed from anywhere in argv, but the top-level parser declares neither, so passing them before the subcommand is rejected as an unknown flag.
Reproduction
$ ofelia --log-level debug version
unknown flag `log-level'
$ ofelia --config /etc/ofelia/config.ini validate
unknown flag `config'
$ ofelia validate --config /etc/ofelia/config.ini
(works)
Why it happens
main pre-parses both flags with flags.IgnoreUnknown to configure the logger and locate the config before the real parser is built (ofelia.go, the pre struct). The pre-parser scans all of argv, so the position does not matter to it. The flags are then declared only on the subcommands that need them, so flags.NewNamedParser rejects them when they appear before the subcommand.
Why it matters
ofelia --config=… daemon is the form most people reach for, and it is also what a reader would infer from the fact that --config governs which file every subcommand reads. Getting an unknown flag for it reads like the flag does not exist.
Suggested fix
Declare both on the top-level parser as well (an options group on flags.NewNamedParser), so the two positions behave the same. The pre-parse stays as it is — it has to run before the logger exists.
Found while adding exit-code tests in #771. Two unit tests there had to be rewritten because they used the rejected position and only passed because every invocation returned 0.
--log-leveland--configare pre-parsed from anywhere in argv, but the top-level parser declares neither, so passing them before the subcommand is rejected as an unknown flag.Reproduction
Why it happens
mainpre-parses both flags withflags.IgnoreUnknownto configure the logger and locate the config before the real parser is built (ofelia.go, theprestruct). The pre-parser scans all of argv, so the position does not matter to it. The flags are then declared only on the subcommands that need them, soflags.NewNamedParserrejects them when they appear before the subcommand.Why it matters
ofelia --config=… daemonis the form most people reach for, and it is also what a reader would infer from the fact that--configgoverns which file every subcommand reads. Getting anunknown flagfor it reads like the flag does not exist.Suggested fix
Declare both on the top-level parser as well (an options group on
flags.NewNamedParser), so the two positions behave the same. The pre-parse stays as it is — it has to run before the logger exists.Found while adding exit-code tests in #771. Two unit tests there had to be rewritten because they used the rejected position and only passed because every invocation returned 0.