-
Notifications
You must be signed in to change notification settings - Fork 350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a method to expose unknown flags back to the user #199
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -399,6 +399,8 @@ func testParseWithUnknownFlags(f *FlagSet, t *testing.T) { | |
t.Error("f.Parse() = true before Parse") | ||
} | ||
f.ParseErrorsWhitelist.UnknownFlags = true | ||
var unknownFlags []string | ||
f.SetUnknownFlagsSlice(&unknownFlags) | ||
|
||
f.BoolP("boola", "a", false, "bool value") | ||
f.BoolP("boolb", "b", false, "bool2 value") | ||
|
@@ -449,6 +451,19 @@ func testParseWithUnknownFlags(f *FlagSet, t *testing.T) { | |
"stringo", "ovalue", | ||
"boole", "true", | ||
} | ||
wantUnknowns := []string{ | ||
"--unknown1", "unknown1Value", | ||
"--unknown2=unknown2Value", | ||
"-u=unknown3Value", | ||
"-p", "unknown4Value", | ||
"-q", | ||
"--unknown7=unknown7value", | ||
"--unknown8=unknown8value", | ||
"--unknown6", "", | ||
"-u", "-u", "-u", "-u", "-u", "", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realize this is brought up in the PR description, but I keep thinking about this line. If
It doesn't seem right to assume they are concatenated shorthands. You can see a working gist here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I strongly disagree that concatenating short flags and values should be supported by anything. It is very unexpected to me that this should work where valid short flags are
This should fail to work both because it's super confusing and terrible design and because it adds a high level of complexity at the flag parsing layer to support both this feature and unknown short flags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @underrun well, it's a pretty old pattern, so I think you'll have to take that up with history. The fact remains that it's a syntax currently supported, and the preservation of unknown flags should be as naive as possible so that the resulting slice can be manually passed to Parse. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't see how having unknown flags can work while allowing concatenated short flags and values though. it feels like it's reasonable to disallow this if unknown flags are requred. no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @underrun I'm not sure I fully follow, but you did help me stumble on another bug with this implementation; if the unknown flag has a value, this current implementation will swallow the value and consider it an argument, despite us having a test for this 🤔 . Works: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @underrun I think I better understand your comment now. Essentially this comes down to an inability to surface values that are separated by a space, because they are indistinguishable from arguments, and there is no way to determine if it's associated to an unknown flag type. A best effort is all that can be done, and that is achieved if the user includes |
||
"--unknown10", | ||
"--unknown11", | ||
} | ||
got := []string{} | ||
store := func(flag *Flag, value string) error { | ||
got = append(got, flag.Name) | ||
|
@@ -464,10 +479,15 @@ func testParseWithUnknownFlags(f *FlagSet, t *testing.T) { | |
t.Errorf("f.Parse() = false after Parse") | ||
} | ||
if !reflect.DeepEqual(got, want) { | ||
t.Errorf("f.ParseAll() fail to restore the args") | ||
t.Errorf("f.Parse() failed to parse with unknown args") | ||
t.Errorf("Got: %v", got) | ||
t.Errorf("Want: %v", want) | ||
} | ||
if !reflect.DeepEqual(unknownFlags, wantUnknowns) { | ||
t.Errorf("f.Parse() failed to enumerate the unknown args args") | ||
t.Errorf("Got: %v", unknownFlags) | ||
t.Errorf("Want: %v", wantUnknowns) | ||
} | ||
} | ||
|
||
func TestShorthand(t *testing.T) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm debating if I like this API or if we should just always store them in th flagset and the user call GetUnknownFlagSlice() to fetch from our internal storage. I feel ike 51/49 towards using GetUnknownFlagSlice(). But why did you go this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid I don't recall what I was thinking last week, let alone 20 months ago ;-)
My motivation for needing this ended up being going away due to other changes needed in the consuming code base and I've also since change jobs. I'm happy if someone else wants to carry this change though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This response sums up my experience trying to contribute to this repo. I've waited two years for review. That's insane.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cobra community would like this (or something like this) so that we can have an api access to unknown flags. Ether way would be fine as long as we can get them!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm finally merging down a few of these PRs into my fork and I'll update the readme to explain how to override the dependency when using cobra.
Edit: I've published my fork and will be working backwards through old PRs in the coming days, then I'll get to this one. It'd be great to get this into cobra or finally get this repo some love.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jpmcb Okay. I've made some changes to the way this was implemented and merged it into my fork. I hope that suits your needs, but feel free to open any issues and I'll jump on them.
@ijc Thanks for putting this together and making it easy!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for putting a fork together. However, I think it would be an anti-goal of the cobra project to fracture viper, pflags, and cobra by introducing a fork as a core dependency. Cobra is really just a wrapper for pflags and viper. So ideally, I'd like if this could get some love and be merged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jpmcb Yeah, I'd like that too, but I don't want to wait another 2 years for a response. No one has an obligation to use my fork, but I'm movin' on :)