Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang conflicting command line flags

Tags:

go

I'm having trouble running tests using gocheck. I need to pass it a flag to specify which test to run, e.g. go test -gocheck.f ApiSuite.TestSomeFunction.

My test file imports a settings package, in which there's an init() function that specifies its own flags and calls flag.parseFlags(). The problem I'm having is that this seems to be overriding the gocheck flags, so I get an error that the flag -gocheck.f is not recognized.

Note: Not sure if this is relevant, but it only happens in some of my packages and not others. I assume it's just based on the order go decides to import the packages in, but I thought I'd mention it in case this is relevant.

Has anyone else run into this problem? Is there a simple way to just have all the flags combine without getting clobbered, or to make the gocheck flags take precedence over my custom flags?

like image 214
danny Avatar asked Dec 05 '12 04:12

danny


1 Answers

If more than one package calls flag.Parse without any concerns about other packages defining other flags then you're in trouble (as you've experienced already). The state of the "flag" package is a global state, so it's more or less the same as if different packages would be competing to set a value of a global variable during init to different values. That may not end well, obviously.

The easy way to prevent this: flag.Parse should be called only once (in the first approximation). That's why it is normally seen in package "main" only. If your non-main package calls flag.Parse then it typically will conflict with any flag.Parse called in package "main". Note that go test synthesizes a package main in order to test a package and flag.Parse is called from that synthesized "main" package.

On the other hand, it is more "safe" (but conflicts are possible anyway) to only define flags in a non-main package and rely on flag.Parse would be called in package "main". In the non-main package, one can then verify that flag.Parse has been invoked by using flag.Parsed().

Written above is simplified. For additional options check the package flag documentation. More "power" could be acquired in some scenarios by, for example, using flag.Flagset, i.e. by using local state for flag options within a package.

However, I personally prefer not to use package "flag" outside of package "main" in any way and rather to set up any configurable package behavior through its API. Exceptions do exist, though, e.g. in *_test files or other special cases.

like image 104
zzzz Avatar answered Oct 16 '22 15:10

zzzz