Skip to content
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

proposal: flag: function to add long and short version of a flag #40138

Open
lolbinarycat opened this issue Jul 9, 2020 · 14 comments
Open

proposal: flag: function to add long and short version of a flag #40138

lolbinarycat opened this issue Jul 9, 2020 · 14 comments
Labels
Projects
Milestone

Comments

@lolbinarycat
Copy link

@lolbinarycat lolbinarycat commented Jul 9, 2020

Many programs have command line options that can be specified in either a long or short form.
The most common example would be --help and -h (which are automaticaly included with flag).
As the package currently exists, there is no real good way to define other flags that have this behavior.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 9, 2020

This can be done using the Var variants of the functions. For example

var frobVal int
func init() {
    flag.IntVar(&frobVal, "frob", 0, "set the frob value")
    flag.IntVar(&frobVal, "f", 0, "set the frob value")
}
@lolbinarycat
Copy link
Author

@lolbinarycat lolbinarycat commented Jul 9, 2020

there are 2 problems with that. First, most of that code is the exact same. Second, using -h will result in 2 entries with the exact same text.

If there was a function like the one I'm proposing, the output would be more like:
-f, -frob set the frob value

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 9, 2020

OK, we can think about it. Do you have a suggested API?

@lolbinarycat
Copy link
Author

@lolbinarycat lolbinarycat commented Jul 9, 2020

I don't have any real ideas for function names, but the should probably be the same as current functions (with a normal and Var form) but with 2 name arguments (perhaps short and long?).

that's just my idea, and I'd be open to hearing any better ideas anyone has.

@jimmyfrasche
Copy link
Member

@jimmyfrasche jimmyfrasche commented Jul 9, 2020

I think something like func Synonym(flag string, synonyms ...string) would suffice. That changes the example to:

var frobVal int
func init() {
    flag.IntVar(&frobVal, "f", 0, "set the frob value")
    flag.Synonym("f", "frob") // displayed in this order in usage message
}
@cespare
Copy link
Contributor

@cespare cespare commented Jul 9, 2020

See https://github.com/rsc/getopt for an example of what you can build on top of the flag package as-is.

@ianlancetaylor ianlancetaylor changed the title flag: function to add long and short version of a flag proposal: flag: function to add long and short version of a flag Jul 9, 2020
@gopherbot gopherbot added this to the Proposal milestone Jul 9, 2020
@gopherbot gopherbot added the Proposal label Jul 9, 2020
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Jul 9, 2020
@lolbinarycat
Copy link
Author

@lolbinarycat lolbinarycat commented Jul 10, 2020

I think something like func Synonym(flag string, synonyms ...string) would suffice. That changes the example to:

var frobVal int
func init() {
    flag.IntVar(&frobVal, "f", 0, "set the frob value")
    flag.Synonym("f", "frob") // displayed in this order in usage message
}

Yeah, this seem like it would be a better way to do this, as it wouldn't require doubling the amount of functions in the package.
Perhaps Alias would be a better name though? It's already a common term in relation to shell commands, and it's also shorter to type.

@urandom
Copy link

@urandom urandom commented Jul 10, 2020

I think long and short flags can be added easily with backwards compatibility by extending the name argument of the flags. Currently, the name argument can be anything, but in practice it's just a word, since having a whitespace in the name is unusable.
Instead, by splitting the name using strings.Fields, multiple names for a single flag can be provided:

flag.IntVar(&frobVal, "frob f", 0, "set the frob value")

This way, you won't get a second entry in flag.PrintDefaults, and no new API surface will need to be introduced.

@martisch
Copy link
Member

@martisch martisch commented Jul 11, 2020

I do not think its worth it trying to squeeze it into the current function signature. I do not see any current restrictions on the name string in the flags package. Are we sure non-ASCII whitespace is currently not usable in Flag names?

@urandom
Copy link

@urandom urandom commented Jul 11, 2020

@martisch

Setting up a flag with a whitespace in it currently produces the following help text:

  -foo bar
    	usage (default true)

However, if you try to use what the help text displays ./prog -foo bar, you get the following error:

flag provided but not defined: -foo

Instead, one would have to invoke it as ./prog -foo\ bar. This is quite unusable, since the help text itself does not tell you this. I can also make an educated guess that no cli app with users has any flags that contain whitespaces.

@lolbinarycat
Copy link
Author

@lolbinarycat lolbinarycat commented Jul 15, 2020

I think long and short flags can be added easily with backwards compatibility by extending the name argument of the flags. Currently, the name argument can be anything, but in practice it's just a word, since having a whitespace in the name is unusable.
Instead, by splitting the name using strings.Fields, multiple names for a single flag can be provided:

flag.IntVar(&frobVal, "frob f", 0, "set the frob value")

This way, you won't get a second entry in flag.PrintDefaults, and no new API surface will need to be introduced.

While this likely wouldn't break anything in practice, it would technically be a breaking change, and the benefit of slightly less typing doesn't justify the cost.
Other problems include:

  • decreased readability (It's not immedialy obvious what it does)
  • slight performace decrease (all flags must now be checked for whitespace)

Also, the flag could be specified with -"foo bar" or -'foo bar', same with filename with whitespace.

@rsc
Copy link
Contributor

@rsc rsc commented Jul 15, 2020

This is a duplicate of #35761. Please see the discussion there about why this part of this is possible today and the other part is not possible at all.

@lolbinarycat
Copy link
Author

@lolbinarycat lolbinarycat commented Jul 15, 2020

@rsc what do you mean by "this part" and "the other part"?

@urandom
Copy link

@urandom urandom commented Jul 15, 2020

@lolbinarycat
Judging by the linked issue, the "other part" could be reusing the "name" argument of the flag methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Proposals
Incoming
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.