Skip to content

Conversation

@eparis
Copy link
Collaborator

@eparis eparis commented May 8, 2015

Today --flag arg does not work. It just fails to parse. So fix that.

At the same time allow flags to specify that their args are 'optional'. Much as with a bool =true =false are optional. So one could do

var flagvar int
flag.IntVar(&flagvar, "list", 0, "list the number of items")
flag.Lookup("list").NoOptDefVal = 10

In which case --flag and --flag=20 would be valid, but --flag 20 would not work.

@eparis
Copy link
Collaborator Author

eparis commented May 8, 2015

I see this as an alternative to #18

Both have the same results, just how and what is specified...

Thoughts?

@eparis
Copy link
Collaborator Author

eparis commented May 27, 2015

Since 9294901

long arguments followed by a space do not work

$ ./test --flagname 1235
flag needs an argument: --flagname
Usage of ./test:
      --flagname=1234: help message for flagname

Test program:

import (
    "fmt"
    "os"

    "github.com/spf13/pflag"
)

func main() {
    var flagvar int
    pflag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
    pflag.Parse()

    fmt.Fprintf(os.Stdout, "val=%v\n", flagvar)
}

So I decided to look at what ls does (and some other coreutils binaries), with 'optional' arguments. Optional arguments can not use the form --flag arg. It must use form --flag=arg.

ls --color is optional:

$ ls --color
$ ls --color=never
$ ls --color never
ls: cannot access never: No such file or directory

Man Page:
       --color[=WHEN]
              colorize the output; WHEN can be 'never', 'auto', or 'always' (the default); more info below

argument to ls --tabsize is not optional

$ ls -T 7
$ ls --tabsize=7
$ ls --tabsize 7
$ ls --tabsize
ls: option '--tabsize' requires an argument
Try 'ls --help' for more information.

Man Page:
       -T, --tabsize=COLS
              assume tab stops at each COLS instead of 8

Given we already do not support --flag arg losing that parse ability by adding optional args is no actual lose.

That means the only place we do lose something is a flag which is both optional and provides a short form. Very few coreutils binaries have both optional and shortform flags. (mktemp, shred, split, tail, uniq) However they also do not allow -s arg for example:

$ tail --follow /tmp/bob

^C
$ tail --follow=name /tmp/bob

^C
$ tail -f name /tmp/bob
tail: cannot open ‘name’ for reading: No such file or directory
==> /tmp/bob <==

^C

We would, I think, want to turn on --flag arg with a patch like the following however....

diff --git a/flag.go b/flag.go
index 9f16733..93222c8 100644
--- a/flag.go
+++ b/flag.go
@@ -530,11 +530,15 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
        }
        var value string
        if len(split) == 1 {
-               if bv, ok := flag.Value.(boolFlag); !ok || !bv.IsBoolFlag() {
+               if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() {
+                       value = "true"
+               } else if len(a) > 0 {
+                       value = a[0]
+                       a = a[1:]
+               } else {
                        err = f.failf("flag needs an argument: %s", s)
                        return
                }
-               value = "true"
        } else {
                value = split[1]
        }

@eparis eparis force-pushed the optional-args branch 2 times, most recently from c6da467 to ee1be60 Compare May 27, 2015 21:13
@eparis
Copy link
Collaborator Author

eparis commented Jun 1, 2015

At this point I'm feeling like I want to merge this. It is completely in line with what the ls command does. How much better of an example could we have to follow?

@eparis eparis changed the title Set default values if no arg given Allow flags to take optional arguments Jun 1, 2015
@eparis eparis changed the title Allow flags to take optional arguments Fix '--flag arg' and Allow flags to take optional arguments Jun 1, 2015
@sgotti
Copy link

sgotti commented Jun 15, 2015

@eparis I tested your changes (mainly the Add support for '--flag arg') for rkt/rkt#1028. Perhaps just this fix (if the other one needs more approval) should be merged in its own PR?

About the Set default values if no arg given, maybe some documentation explaining the feature (like your examples above or the one provided by #18), and how to detect if a flag was provided or not (looking at the Changed value) will be good (also if this is not related to this patch but this patch makes the difference between provided or not provided stronger).

Thanks!

sgotti added a commit to sgotti/rkt that referenced this pull request Jun 16, 2015
This patch converts rkt to use the cobra cli library. It doesn't do any
other change. For this reason the help/usage output is different from
the previous one.

Cobra internally uses the github.com/spf13/pflag library (forked from
github.com/ogier/pflag, it's not a dropin replacement for stdlib flag
packages due to an additional method Type() added to the Value
interface). This library handles posix flags and interspersed flags
(flags after non flag arguments).
This means that long flags must start with a double dash (with package
flag also a single dash is accepted).
Until spf13/pflag#20 isn't fixed, an `=` between the long flag and its
value is needed.

Cobra adds the ability to merge the parent command flags (called
persistent flags) to all the child commands. In this way there's no need
to specify the global flags after the executable and before the command
name.

This patch also enables the handling of unambiguous not fully typed
commands (like `rkt l` for `rkt list`).

In rkt there're three special kind of arguments parsing, that needs
special handling of the cobra/pflags default behavior:

fetch: It can handle multiple images with an optional --signature option
after every image. To avoid the --signature being parsed as a normal
flag, interspersed flags must be disabled.

enter: it handles an executable and optional arguments. To avoid these
arguments being parsed as rkt flags, interspersed flags must be
disabled.

run/prepare: it can handle multiple images with image specific
arguments. To do this the image arguments should be inserted between
"--" and "---". This uses a special argument parsing to handle the "--"
that usually makes the flag (and also pflag) libraries stop parsing
flags, eating the "--"  and returning everything after it as arguments
to the relative command. To get the same behavior with the pflags
library, interspersed flags must be disabled and the "--" must be
readded to the command's arguments.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 16, 2015
This patch converts rkt to use the cobra cli library. It doesn't do any
other change. For this reason the help/usage output is different from
the previous one.

Cobra internally uses the github.com/spf13/pflag library (forked from
github.com/ogier/pflag, it's not a dropin replacement for stdlib flag
packages due to an additional method Type() added to the Value
interface). This library handles posix flags and interspersed flags
(flags after non flag arguments).
This means that long flags must start with a double dash (with package
flag also a single dash is accepted).
Until spf13/pflag#20 isn't fixed, an `=` between the long flag and its
value is needed.

Cobra adds the ability to merge the parent command flags (called
persistent flags) to all the child commands. In this way there's no need
to specify the global flags after the executable and before the command
name.

This patch also enables the handling of unambiguous not fully typed
commands (like `rkt l` for `rkt list`).

In rkt there're three special kind of arguments parsing, that needs
special handling of the cobra/pflags default behavior:

fetch: It can handle multiple images with an optional --signature option
after every image. To avoid the --signature being parsed as a normal
flag, interspersed flags must be disabled.

enter: it handles an executable and optional arguments. To avoid these
arguments being parsed as rkt flags, interspersed flags must be
disabled.

run/prepare: it can handle multiple images with image specific
arguments. To do this the image arguments should be inserted between
"--" and "---". This uses a special argument parsing to handle the "--"
that usually makes the flag (and also pflag) libraries stop parsing
flags, eating the "--"  and returning everything after it as arguments
to the relative command. To get the same behavior with the pflags
library, interspersed flags must be disabled and the "--" must be
readded to the command's arguments.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 16, 2015
This patch converts rkt to use the cobra cli library. It doesn't do any
other change. For this reason the help/usage output is different from
the previous one.

Cobra internally uses the github.com/spf13/pflag library (forked from
github.com/ogier/pflag, it's not a dropin replacement for stdlib flag
packages due to an additional method Type() added to the Value
interface). This library handles posix flags and interspersed flags
(flags after non flag arguments).
This means that long flags must start with a double dash (with package
flag also a single dash is accepted).
Until spf13/pflag#20 isn't fixed, an `=` between the long flag and its
value is needed.

Cobra adds the ability to merge the parent command flags (called
persistent flags) to all the child commands. In this way there's no need
to specify the global flags after the executable and before the command
name.

This patch also enables the handling of unambiguous not fully typed
commands (like `rkt l` for `rkt list`).

In rkt there're three special kind of arguments parsing, that needs
special handling of the cobra/pflags default behavior:

fetch: It can handle multiple images with an optional --signature option
after every image. To avoid the --signature being parsed as a normal
flag, interspersed flags must be disabled.

enter: it handles an executable and optional arguments. To avoid these
arguments being parsed as rkt flags, interspersed flags must be
disabled.

run/prepare: it can handle multiple images with image specific
arguments. To do this the image arguments should be inserted between
"--" and "---". This uses a special argument parsing to handle the "--"
that usually makes the flag (and also pflag) libraries stop parsing
flags, eating the "--"  and returning everything after it as arguments
to the relative command. To get the same behavior with the pflags
library, interspersed flags must be disabled and the "--" must be
readded to the command's arguments.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 16, 2015
This patch converts rkt to use the cobra cli library. It doesn't do any
other change. For this reason the help/usage output is different from
the previous one.

Cobra internally uses the github.com/spf13/pflag library (forked from
github.com/ogier/pflag, it's not a dropin replacement for stdlib flag
packages due to an additional method Type() added to the Value
interface). This library handles posix flags and interspersed flags
(flags after non flag arguments).
This means that long flags must start with a double dash (with package
flag also a single dash is accepted).
Until spf13/pflag#20 isn't fixed, an `=` between the long flag and its
value is needed.

Cobra adds the ability to merge the parent command flags (called
persistent flags) to all the child commands. In this way there's no need
to specify the global flags after the executable and before the command
name.

This patch also enables the handling of unambiguous not fully typed
commands (like `rkt l` for `rkt list`).

In rkt there're three special kind of arguments parsing, that needs
special handling of the cobra/pflags default behavior:

fetch: It can handle multiple images with an optional --signature option
after every image. To avoid the --signature being parsed as a normal
flag, interspersed flags must be disabled.

enter: it handles an executable and optional arguments. To avoid these
arguments being parsed as rkt flags, interspersed flags must be
disabled.

run/prepare: it can handle multiple images with image specific
arguments. To do this the image arguments should be inserted between
"--" and "---". This uses a special argument parsing to handle the "--"
that usually makes the flag (and also pflag) libraries stop parsing
flags, eating the "--"  and returning everything after it as arguments
to the relative command. To get the same behavior with the pflags
library, interspersed flags must be disabled and the "--" must be
readded to the command's arguments.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 17, 2015
This patch converts rkt to use the cobra cli library. It doesn't do any
other change. For this reason the help/usage output is different from
the previous one.

Cobra internally uses the github.com/spf13/pflag library (forked from
github.com/ogier/pflag, it's not a dropin replacement for stdlib flag
packages due to an additional method Type() added to the Value
interface). This library handles posix flags and interspersed flags
(flags after non flag arguments).
This means that long flags must start with a double dash (with package
flag also a single dash is accepted).
Until spf13/pflag#20 isn't fixed, an `=` between the long flag and its
value is needed.

Cobra adds the ability to merge the parent command flags (called
persistent flags) to all the child commands. In this way there's no need
to specify the global flags after the executable and before the command
name.

This patch also enables the handling of unambiguous not fully typed
commands (like `rkt l` for `rkt list`).

In rkt there're three special kind of arguments parsing, that needs
special handling of the cobra/pflags default behavior:

fetch: It can handle multiple images with an optional --signature option
after every image. To avoid the --signature being parsed as a normal
flag, interspersed flags must be disabled.

enter: it handles an executable and optional arguments. To avoid these
arguments being parsed as rkt flags, interspersed flags must be
disabled.

run/prepare: it can handle multiple images with image specific
arguments. To do this the image arguments should be inserted between
"--" and "---". This uses a special argument parsing to handle the "--"
that usually makes the flag (and also pflag) libraries stop parsing
flags, eating the "--"  and returning everything after it as arguments
to the relative command. To get the same behavior with the pflags
library, interspersed flags must be disabled and the "--" must be
readded to the command's arguments.
eparis added a commit that referenced this pull request Jun 22, 2015
Fix '--flag arg' and Allow flags to take optional arguments
@eparis eparis merged commit 6ff05c5 into spf13:master Jun 22, 2015
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 27, 2015
starting from spf13/pflag#20 it accepts also `--flag value` while
before `--flag=value` was needed. Additionaly it supports default values
for flags specified without an explicit value (`--flag`) (which is
different from the default value for flags not passed as arguments).

In that cae, the `--flag=value` is needed for flags that can have a
default value because the parser won't know if the argument after
`--flag` is the flag's value or another argument.

This patches changed the way flags are handled and removed the use of
the boolFlag interface as now default values can be provided for every
type (not just bool) setting the NoOptDefVal variable.

This patch fixes rkt to use the new behavior.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 27, 2015
starting from spf13/pflag#20 it accepts also `--flag value` while
before `--flag=value` was needed. Additionaly it supports default values
for flags specified without an explicit value (`--flag`) (which is
different from the default value for flags not passed as arguments).

In that cae, the `--flag=value` is needed for flags that can have a
default value because the parser won't know if the argument after
`--flag` is the flag's value or another argument.

That fix also changed the way flags are handled and removed the use of
the boolFlag interface as now default values can be provided for every
type (not just bool) by setting the NoOptDefVal variable.

This patch fixes rkt to use the new behavior.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 27, 2015
starting from spf13/pflag#20 it accepts also `--flag value` while
before `--flag=value` was needed. Additionaly it supports default values
for flags specified without an explicit value (`--flag`) (which is
different from the default value for flags not passed as arguments).

In that case, the `--flag=value` is needed for flags that can have a
default value because the parser won't know if the argument after
`--flag` is the flag's value or another argument.

That fix also changed the way flags are handled and removed the use of
the boolFlag interface as now default values can be provided for every
type (not just bool) by setting the NoOptDefVal variable.

This patch fixes rkt to use the new behavior.
sgotti added a commit to sgotti/rkt that referenced this pull request Jun 27, 2015
starting from spf13/pflag#20 it accepts also `--flag value` while
before `--flag=value` was needed. Additionally it supports default values
for flags specified without an explicit value (`--flag`) (which is
different from the default value for flags not passed as arguments).

In that case, the `--flag=value` is needed for flags that can have a
default value because the parser won't know if the argument after
`--flag` is the flag's value or another argument.

That fix also changed the way flags are handled and removed the use of
the boolFlag interface as now default values can be provided for every
type (not just bool) by setting the NoOptDefVal variable.

This patch fixes rkt to use the new behavior.
@eparis eparis deleted the optional-args branch August 12, 2015 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants