Honor env sources on duplicated flags#2355
Conversation
|
@ibobgunardi Can you follow the PR template when submitting a PR ? Thanks |
dearchap
left a comment
There was a problem hiding this comment.
Root Cause
When the same flag instance is registered on both a parent and subcommand, FlagBase.PreParse() re-initializes f.value to the default (f.Value) without checking f.applied. This overwrites the env-sourced value set by the parents PostParse()`.
Meanwhile, FlagBase.PostParse() guards with f.hasBeenSet, which is already true (set by the parent`s PostParse), so it skips re-reading the env var. End result: the subcommand gets the zero/default value instead of the env value.
Fix Validation
hasPersistentFlagOnAncestor() uses pointer equality to detect the shared instance, and the PreParse skip in command_run.go:144-146 correctly:
- Prevents the destructive re-initialization on the subcommand
- Preserves the env (or CLI-arg) value already set on the parent
- PostParse respects
hasBeenSetand does not overwrite
Test Coverage
The test TestDuplicatePersistentFlagUsesEnvSource covers:
- Env source read by the parent
sBefore` handler ✓ - Env source value propagated to the subcommand
sAction` ✓ IsSet()returningtrueon both parent and subcommand ✓
LGTM.
|
Updated the description to follow the PR template. Thanks for the reminder. |
dearchap
left a comment
There was a problem hiding this comment.
Good question about f.applied in PreParse. I tested it — two regressions:
-
TestSliceStringFlagParsing — PreParse re-creates
f.valuefrom scratch (viaf.creator.Create). Without it,Set()appends to the existing slice, causing cross-sub-test value leakage. e.g. expected["x", "y"], got["x", "x", "y"]. -
TestRequiredFlagDelayed —
appliedbeingtrueon a shared flag instance prevents PreParse from running on the leaf command, altering required-flag behavior that non-shared flags depend on.
applied serves dual roles (prevent recursion + track initialization), so adding it to PreParse is too broad. The pointer-equality/ancestor check is correctly scoped. LGTM.
What type of PR is this?
What this PR does / why we need it:
Which issue(s) this PR fixes:
Fixes #2217
Special notes for your reviewer:
The main behavior to review is the exact flag-instance check for inherited persistent flags.
Testing
Release Notes