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

flag: FlagSet.Parse(...) unexpected behavior with non-flag args #26104

Closed
dape-wg2 opened this issue Jun 28, 2018 · 7 comments
Closed

flag: FlagSet.Parse(...) unexpected behavior with non-flag args #26104

dape-wg2 opened this issue Jun 28, 2018 · 7 comments

Comments

@dape-wg2
Copy link

What version of Go are you using (go version)?

go version go1.9.4 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/dape/go"
GORACE=""
GOROOT="/usr/lib/go-1.9"
GOTOOLDIR="/usr/lib/go-1.9/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build733299665=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

Passing a non-flag (not prefixed with -) causes the FlagSet to stop parsing. I expected it to fail instead of silently behaving as if the input was valid.

https://play.golang.org/p/qLslIW5FbqI

fs := flag.NewFlagSet("test", flag.PanicOnError)
err := fs.Parse([]string{"no_such_thing", "-unknown"})
fmt.Println(err)

What did you expect to see?

I expected FlagSet.Parse([]string{"something", "-unknown"}) to fail.

What did you see instead?

FlagSet.Parse([]{"something", "-unknown"}) behave as if the input was valid.

This is implemented here but there are no tests to verify that this is the expected behavior.

This behavior make it possible to break almost any go program that runs on the terminal since there is no way for the developer to check the input without duplicating a lot of the code in the flag package.

@cznic
Copy link
Contributor

cznic commented Jun 28, 2018

This is working as intended.

Flag parsing stops just before the first non-flag argument ("-" is a non-flag argument) or after the terminator "--".

src: https://golang.org/pkg/flag/#pkg-overview

@robpike
Copy link
Contributor

robpike commented Jun 28, 2018

Indeed, working as intended. Flag packages from other providers might behave differently; I suggest you investigate them.

@robpike robpike closed this as completed Jun 28, 2018
@dape-wg2
Copy link
Author

OK; thanks for investigating.

Nit: while this is WAI it is still not a good experience for developers since there is no way to check if all command line arguments have been parsed or ignored. While it is possible to find a different package; it can be hard to retrofit it to existing libraries that already use this one (they don't compose well; you essentially end up writing a tiny parser to make sure the right arguments ends up in the right parsers)

@robpike
Copy link
Contributor

robpike commented Jun 29, 2018

However it is a good experience for programmers who write subcommands, for which this behavior is ideal.

@dape-wg2
Copy link
Author

Agreed; Once I actually read the docs for FlagSet.Arg(...) and FlagSet.Args(...) (and tried to code a little)

@cznic
Copy link
Contributor

cznic commented Jun 29, 2018

... since there is no way to check if all command line arguments have been parsed or ignored.

There is: by iterating os.Args.

@dape-wg2
Copy link
Author

I think there is a simpler way; but I've not verified it in detail.

If you use flag.Parse() then you can use flag.CommandLine.Args() to get the "remaining" arguments.
(which doc say; at least if you squint at it a little 😁)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants