Support custom FlagStringer for MutuallyExclusiveFlags - #2414
Support custom FlagStringer for MutuallyExclusiveFlags#2414SHIVANSHGARG07 wants to merge 5 commits into
Conversation
Adds a Stringer field to MutuallyExclusiveFlags that lets callers override how flags within the group are rendered in help output. Flags opt in via the new FlagStringerOverrider interface. Fixes urfave#2220
FlagStringFunc is a func type and cannot be marshaled to JSON, which broke the staticcheck SA1026 lint check via json.Marshal(cmd) in existing tests. Tag the field with json:"-" to exclude it.
dearchap
left a comment
There was a problem hiding this comment.
Overall: Clean implementation following existing patterns. A few suggestions below.
Suggestion 1: Rename
|
Suggestion 2: Add test for non-implementing flagsThe func TestMutuallyExclusiveFlags_PropagateStringerSkipsNonImplementor(t *testing.T) {
customStringer := func(f Flag) string {
return "custom:" + f.Names()[0]
}
// plainStringFlag is a minimal Flag impl that does NOT implement StringerSetter
type plainStringFlag struct {
StringFlag
}
grp := MutuallyExclusiveFlags{
Stringer: customStringer,
Flags: [][]Flag{
{
&plainStringFlag{StringFlag{Name: "plain"}},
},
},
}
// should not panic
grp.propagateStringer()
// stringer should NOT have been set — verify default behavior
assert.NotEmpty(t, grp.Flags[0][0].String())
}This ensures that the interface assertion skip path is covered and will not regress. |
Suggestion 3: Verify
|
…er, add skip-non-implementor test
|
Thanks for the review! Addressed all three suggestions in the latest commit:
Also synced the branch with the latest main since it was flagged out-of-date. |
What type of PR is this?
What this PR does / why we need it:
Adds a
Stringerfield toMutuallyExclusiveFlagsthat lets callersoverride how flags within the group are rendered in help output.
Previously, flags inside a mutex group could only use the package-level
FlagStringer, so there was no way to add group-specific context (e.g.marking one of the flags as "required") to the help text.
flag.go: added theFlagStringerOverriderinterface(
SetStringer(FlagStringFunc)) that flags implement to opt in to acustom stringer.
flag_mutex.go: addedStringer FlagStringFuncfield toMutuallyExclusiveFlags, pluspropagateStringer()which pushes thegroup's stringer down to member flags (mirrors the existing
propagateCategory()pattern used forCategory).flag_impl.go:FlagBasenow stores an optional per-flagstringerand uses it in
String()when set; implementsSetStringer.flag_bool_with_inverse.go: same treatment forBoolWithInverseFlag,which doesn't embed
FlagBaseand needed a separate implementation.command_setup.go: callsgrp.propagateStringer()alongside theexisting
grp.propagateCategory()call during command setup.godoc-current.txt: regenerated to reflect the new public API.Which issue(s) this PR fixes:
Fixes #2220
Special notes for your reviewer:
Followed the existing
propagateCategorypattern for consistency.BoolWithInverseFlagneeded a standalone implementation since itdoesn't embed
FlagBase.Testing
Added
TestMutuallyExclusiveFlags_PropagateStringerandTestMutuallyExclusiveFlags_PropagateStringerNilinflag_mutex_test.go. Ran the full suite withgo test ./...— allpassing.
Release Notes