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 ability to ignore unknown flags #160
Conversation
requesting review from @eparis |
pinging @eparis again |
Pinging @eparis, please let me know if once a day ping is too much |
ping @eparis please continue to ignore if you are busy, i just want to make sure i don't forget about it. |
How should this relate to the *OnError defines? Can you think of a good way to rationalize this into a single error handling logic? |
Thanks a lot for the review @eparis I see what you are saying. looking at this: https://github.com/spf13/pflag/blob/master/flag.go#L1087 i think with ContinueOnError, it will stop parsing flags as soon as it encounter an unknown flag, but let user decide what do to with error with IgnoreUnknownFlags, it will ignore unknown flag error encountered during parse while continuing to parse the other known flags. (it will still return error for other conditions). If it make sense, I can add this as an "ErrorHandling" type. Please let me know |
Do you think I'm not arguing that the "ErrorHandling" stuff is a good idea, it's just the thing we have. And I don't want to make a second semi-related thing if we can help it.... |
if we add another ErrorHandling type as 'IgnoreUnknownFlags', what should be the behavior incase of any other error. e.g. lets say user selected ErrorHandling to be of type IgnoreUnknownFlags, and flag parsing encountered a different error, what should we do with that error (panic, exit or continue?) |
sorry if felt that way, but i am asking for suggestions here :) this library is a master piece, and i want to keep it that way (even after my ugly contributions) |
so kindly let me know what you think we should do here, and I will try to update the PR to reflect that. |
pinging @eparis |
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'd like you to think about what a better Error handling interface would look like. I agree that having 3 new OnError
defines is not the right thing to go. I'll take this PR, but would love to hear you thought if some sort of feature bit map or something makes better sense for our error handling. And if it does make sense, can this be the first thing the implements that new error aPI?
@@ -896,6 +899,25 @@ func (f *FlagSet) usage() { | |||
} | |||
} | |||
|
|||
//--unknown (args will be empty) | |||
//--unknown --next-flag ... (args will be --next-flag ...) |
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.
What if I passed --unknown=bob --next-flag
. I think this will strip --next-flag
, but I don't think it should.
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 function just strips value for unknown flag, the flag itself is not included in args.
for --unknown=value --next-flag ...
args will be --next-flag ...
added the testcase to test this explicitly
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 really think you need to know len(split)
(from parseLongArg
) and to use that. What if it was --unknown=value subcmd
. You would strip subcmd
which is really not what the user wants.
Clearly it is a heuristic to know what to strip and what not to strip for an 'unknown' but I think we want to be as careful as we can...
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.
oh yes, thats right. i would consider this a bug :)
fixed. thank you for pointing out.
"unknown1Value", | ||
"-d=true", | ||
"-x", | ||
"--unknown2=unknown2Value", |
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 think this test need to cover the case where --unknown=value
is followed by --known
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.
added the testcase, thanks
thanks for the review @eparis I have added the test case as suggested. |
flag.go
Outdated
@@ -138,6 +138,9 @@ type FlagSet struct { | |||
// help/usage messages. | |||
SortFlags bool | |||
|
|||
// IgnoreUnknownFlags is used to indicate to ignore unknown flags | |||
IgnoreUnknownFlags bool |
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.
Convert this into some sort of generic "set" of error handling bools which we can grow as needed and I'll merge this PR.
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.
Will do that today, thanks
thanks a lot for merging eparis |
@rajatjindal I was waiting for this PR thanks for the effort! If I understand correctly, it strips all unknown flags passed, leaving known ones. I need to create a wrapper command in the form: Where What happens is that I'm loosing any given |
originally pflag will error out if it encounters any flag which was not configured by 'current cmd'. so running cmd subcmd systemcmd --systemcmd-flag, will result in 'unknown flag --systemcmd-flag' The intention of this PR was to ignore those unknown flags during parsing (in other words strip) and keep the flags which are required by 'current cmd'. do u have a use case where you want to consume systemcmd-flag in your 'current cmd'? |
@rajatjindal I want to build a command wrapper similar to the I need to preserve all flags passed to the command being wrapped. Currently this is not possible to do with the previous pflag and it's still not possible with this PR. |
I think it is possible, but now you have go back and process what if we added the 'ignored' flags to the |
@eparis thanks for pointing that, this should workaround the problem. I expected to find the "ignored" flags in the args passed to |
we'll see what @rajatjindal says about it. This API is new enough I don't mind 'breaking' it.... |
I think we should probably include IgnoredFlags *flag.FlagSet field in command, that can be set when ignoredflags is on Passing by default to run func may create prob again for user on what is child commands vs ignored flags |
@rajatjindal but would that require the user to explicitly set IgnoredFlags in advance? I would add |
Yeah, i think so, otherwise the flag parsing will fail on it. I think []string make sense |
sorry i think i misread your comment. The user will just have to set a bool flag to ignore unknown flags, but ignored flags will be read and added to IgnoredFlags while parsing. |
Making sure my thought was understood. I was saying that if we ignore a flag and arg (because the dev decided to set IgnoreUnknown) we should add those things to the Today, I think, those args are just 'non-flag' args which were not consumed by cobra. If you set 'IgnoreUnknown' your program will start getting those 'ignored' things along with the non-flag args. Now it would be your program's problem to parse and handle those 'args'. How you decide to handle those are your problem... |
I'm totally with @eparis, just unsure to be saying something nonsense, but passing everything back to the user in |
I think thats fine too. args it is then :) |
Use a tagged release of this package Relevant changes: - spf13/pflag#122 DurationSlice: implementation and tests - spf13/pflag#115 Implement BytesHex type of argument - spf13/pflag#150 Add uintSlice and boolSlice to name prettifier - spf13/pflag#155 Add multiline wrapping support - spf13/pflag#158 doc: clarify difference between string slice vs. array - spf13/pflag#160 add ability to ignore unknown flags - spf13/pflag#163 Allow Users To Show Deprecated Flags Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a tagged release of Cobra Relevant changes: - spf13/cobra#567 Add `CalledAs` method to cobra.Command - spf13/cobra#580 Update error message for missing required flags - spf13/cobra#584 Add support for --version flag - spf13/cobra#614 If user has a project in symlink, just use its destination folder and work there - spf13/cobra#649 terminates the flags when -- is found in commandline - spf13/cobra#662 Add support for ignoring parse errors - spf13/cobra#686 doc: hide hidden parent flags Also various improvements were added for generating Bash completion scripts (currently not used by us) Bump spf13/pflag to v1.0.1 Relevant changes: - spf13/pflag#122 DurationSlice: implementation and tests - spf13/pflag#115 Implement BytesHex type of argument - spf13/pflag#150 Add uintSlice and boolSlice to name prettifier - spf13/pflag#155 Add multiline wrapping support - spf13/pflag#158 doc: clarify difference between string slice vs. array - spf13/pflag#160 add ability to ignore unknown flags - spf13/pflag#163 Allow Users To Show Deprecated Flags Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a tagged release of Cobra. All relevant PR's were merged, so the fork is no longer needed. Relevant changes: - spf13/cobra#552 Add a field to disable [flags] in UseLine() - spf13/cobra#567 Add `CalledAs` method to cobra.Command - spf13/cobra#580 Update error message for missing required flags - spf13/cobra#584 Add support for --version flag - spf13/cobra#614 If user has a project in symlink, just use its destination folder and work there - spf13/cobra#649 terminates the flags when -- is found in commandline - spf13/cobra#662 Add support for ignoring parse errors - spf13/cobra#686 doc: hide hidden parent flags Also various improvements were added for generating Bash completion scripts (currently not used by us) Fixes usage output for dockerd; Before this update: dockerd --help Usage: dockerd COMMAND A self-sufficient runtime for containers. After this update: dockerd --help Usage: dockerd [OPTIONS] [flags] A self-sufficient runtime for containers. Bump spf13/pflag to v1.0.1 Relevant changes: - spf13/pflag#106 allow lookup by shorthand - spf13/pflag#113 Add SortFlags option - spf13/pflag#138 Generate flag error output for errors returned from the parseFunc - spf13/pflag#141 Fixing Count flag usage string - spf13/pflag#143 add int16 flag - spf13/pflag#122 DurationSlice: implementation and tests - spf13/pflag#115 Implement BytesHex type of argument - spf13/pflag#150 Add uintSlice and boolSlice to name prettifier - spf13/pflag#155 Add multiline wrapping support - spf13/pflag#158 doc: clarify difference between string slice vs. array - spf13/pflag#160 add ability to ignore unknown flags - spf13/pflag#163 Allow Users To Show Deprecated Flags Hide [flags] in usage output Hides the [flags] in the usage output of commands (present in newer versions of Cobra), using the `.DisableFlagsInUseLine` option. Before this change: dockerd --help Usage: dockerd [OPTIONS] [flags] A self-sufficient runtime for containers. After this change: dockerd --help Usage: dockerd [OPTIONS] A self-sufficient runtime for containers. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Â# modified: vendor/github.com/spf13/pflag/string_array.go § Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Use a tagged release of Cobra Relevant changes: - spf13/cobra#567 Add `CalledAs` method to cobra.Command - spf13/cobra#580 Update error message for missing required flags - spf13/cobra#584 Add support for --version flag - spf13/cobra#614 If user has a project in symlink, just use its destination folder and work there - spf13/cobra#649 terminates the flags when -- is found in commandline - spf13/cobra#662 Add support for ignoring parse errors - spf13/cobra#686 doc: hide hidden parent flags Also various improvements were added for generating Bash completion scripts (currently not used by us) Bump spf13/pflag to v1.0.1 Relevant changes: - spf13/pflag#122 DurationSlice: implementation and tests - spf13/pflag#115 Implement BytesHex type of argument - spf13/pflag#150 Add uintSlice and boolSlice to name prettifier - spf13/pflag#155 Add multiline wrapping support - spf13/pflag#158 doc: clarify difference between string slice vs. array - spf13/pflag#160 add ability to ignore unknown flags - spf13/pflag#163 Allow Users To Show Deprecated Flags Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: 0acb2522bd17ec6f1eb4ecb0960c792a71f08f69 Component: cli
Use a tagged release of Cobra. All relevant PR's were merged, so the fork is no longer needed. Relevant changes: - spf13/cobra#552 Add a field to disable [flags] in UseLine() - spf13/cobra#567 Add `CalledAs` method to cobra.Command - spf13/cobra#580 Update error message for missing required flags - spf13/cobra#584 Add support for --version flag - spf13/cobra#614 If user has a project in symlink, just use its destination folder and work there - spf13/cobra#649 terminates the flags when -- is found in commandline - spf13/cobra#662 Add support for ignoring parse errors - spf13/cobra#686 doc: hide hidden parent flags Also various improvements were added for generating Bash completion scripts (currently not used by us) Fixes usage output for dockerd; Before this update: dockerd --help Usage: dockerd COMMAND A self-sufficient runtime for containers. After this update: dockerd --help Usage: dockerd [OPTIONS] [flags] A self-sufficient runtime for containers. Bump spf13/pflag to v1.0.1 Relevant changes: - spf13/pflag#106 allow lookup by shorthand - spf13/pflag#113 Add SortFlags option - spf13/pflag#138 Generate flag error output for errors returned from the parseFunc - spf13/pflag#141 Fixing Count flag usage string - spf13/pflag#143 add int16 flag - spf13/pflag#122 DurationSlice: implementation and tests - spf13/pflag#115 Implement BytesHex type of argument - spf13/pflag#150 Add uintSlice and boolSlice to name prettifier - spf13/pflag#155 Add multiline wrapping support - spf13/pflag#158 doc: clarify difference between string slice vs. array - spf13/pflag#160 add ability to ignore unknown flags - spf13/pflag#163 Allow Users To Show Deprecated Flags Hide [flags] in usage output Hides the [flags] in the usage output of commands (present in newer versions of Cobra), using the `.DisableFlagsInUseLine` option. Before this change: dockerd --help Usage: dockerd [OPTIONS] [flags] A self-sufficient runtime for containers. After this change: dockerd --help Usage: dockerd [OPTIONS] A self-sufficient runtime for containers. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Â# modified: vendor/github.com/spf13/pflag/string_array.go § Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Upstream-commit: ed75c7727bf3e454a5faa6baf686de12152d911c Component: engine
@rajatjindal , the last few messages in this discussion seem to indicate that any non-consumed flags should be left in the
I am writing a wrapper around
But when i use
It appears your test code verifies that all the expected flags are parsed, and unexpected flags ignored, but it doesn't seem to be verifying that the unexpected args are present in the remaining arg list. Also, this ignore feature never made its way into the cobra documentation, it was a bit of a pita to figure this out. Might be a good idea to add it there. |
Hi Sorry for the pain it caused I am in middle of relocating right now, i can try to fix this in about 2 weeks or if you want to open a PR that will be great |
Totally agree, an ignored flag should have been kept in the argument list after flag parsing, because it is ignored. This is an important missing feature of this library which prevent developing a command wrapper (as said by @Victorcoder) that has its own "global" arguments. However this features is implemented as a kind of error to be ignored and not flags to be ignored. So I don't think it is worthwhile breaking by changing this behavior. There should be a real "IgnoreUnknownFlags" feature. |
Is there any update on the ignored flag being passed back to the remaining arg list? |
FWIW, using var execCmd = &cobra.Command{
Use: "exec -- [subcommand]",
Short: "Spawn a subprocess",
Args: cobra.MinimumNArgs(1),
Run: execRun,
}
func execRun(_ *cobra.Command, args []string) {
execCmd := args[0]
execArgs := args[1:]
# ...
} I agree it's not the ideal UX, but it gets the job done:
|
I can't seem to find a way to access the ignore flags - was this ever addressed? |
cmd = &cobra.Command{
......
FParseErrWhitelist: cobra.FParseErrWhitelist{
UnknownFlags: true,
},
} |
It will be nice if we can add ability to ignore unknown flags. This can be useful when writing wrappers on other commands where exposing all downstream flags is un-necessary.