namsral/flag

not a drop-in replacement

skrassiev opened this issue · 12 comments

There is an issue, if you define a flag in a some other package, but not in a main package.

If your main package imports "abc/def/gh", and package "gh" defines a flag "-flag1", while in your main package "flag.Parse()" is called, then:

  • the standard 'flag' package successfully parses command line with "--flag1=xyz";
  • namsral/flag complains "flag provided but not defined: -flag1" .

Could you post your code because in my tests your described scenario works.

Ok, I inaccurately described the issue:

Main package imports "github.com/namsral/flag" and calls flag.Parse()
Main package imports a third-party "someotherpackage".
someotherpackage package imports just standard "flag" and declares some flags.

github.com/namsral/flag.Parse() would not see flags, declared through standard flag package in someotherpackage.

That's definitely a shortcoming as you don't have control over third-parties.

The flag package is meant to be used by program developers, not library developers. Third party packages should not depend on the flag package. Package variables should be set via exported variables, functions, the init function, etc.

there is no limitation on where the flag package should be used from.

I beg to differ; as a program developer I would like to have the final say in building the user interface instead of the library developer.

Can you provide me with example where it would be an advantage to include the flag package in a library.

Hello, I’m also facing a similar issue. But I cannot get my head around on why this happens.

Following is what I do:

  • I’m using goji's -- goji.Serve()
  • I have parameter db-address

When I’m running with namsral/flag - I get the error

flag provided but not defined: -db-address
Usage of ./server:
  -bind="::8000": Address to bind on. If this value has a colon, as in ":8000" or
        "127.0.0.1:9001", it will be treated as a TCP address. If it
        begins with a "/" or a ".", it will be treated as a path to a
        UNIX socket. If it begins with the string "fd@", as in "fd@3",
        it will be treated as a file descriptor (useful for use with
        systemd, for instance). If it begins with the string "einhorn@",
        as in "einhorn@0", the corresponding einhorn socket will be
        used. If an option is not explicitly passed, the implementation
        will automatically select among "einhorn@0" (Einhorn), "fd@3"
        (systemd), and ":8000" (fallback) based on its environment.

This error comes from https://github.com/zenazn/goji/blob/master/bind/bind.go

When I use the golang's default flag, then the error is gone.

Any reason why this goes away when I use default flags.

Within the goji package replace the flag import with github.com/namsral/flag.

Replacing flag is not trivially doable in every situation. For example, I don't believe I can do it in github.com/golang/glog without forking that package.

@namsral: I want to use glog in my main go program. When I pass -logtostderr=true -v=2 to my main go app, I get a flag provided but not defined: -logtostderr error message back. I tried to export LOGTOSTDERR=true with no luck.

It's bad practice to parse command line options in a library. Please see a previous comment on a similar issue.

Software is opinionated, namsral/flag is no exception.