urfave / cli

A simple, fast, and fun package for building command line apps in Go
https://cli.urfave.org
MIT License
22.25k stars 1.7k forks source link

are flag symlinks/inheritance supported? #1976

Open samlaf opened 4 days ago

samlaf commented 4 days ago

this is either a question about v2, or a feature request for v3.

The way I currently like to organize my flags is like I've done in https://github.com/Layr-Labs/eigenda-proxy/blob/480324a0c60da9f7e498daa264cb68564f06290a/flags/flags.go#L76, where modules/packages themselves define their flags (in a cli.go file, of which there can be one per flag package if a specific sdk for eg is meant to be included in different clis that use urfave, viper, etc.) themselves, and then a cli can import all of the locally defined flags to define its own set of flags.

I prefer this approach than to have a massive flags definition flag for each CLI. One problem though is that for some CLIs, two of the subpackages define the same flags, which sometimes have different names. Whenever this happens, what I would want to do (but tried and failed) is to define some "global" or "shared" flags in my binary, hide the respective flags in the underlying packages, but still populate them from the value given to this global flag. In a sense, this would mean the subpackage flags would be "symlinked" to the global flag.

Eg:

# package foo
flag private_key
# package bar
flag my_private_key

I would want to define a shared flag, which would be inherited by the (potentially same-named) packaged flags.

# shared cli flags
flag private_key
# package foo
flag private_key (hidden but inherits the value from the global private_key flag)
# package bar
flag private_key (hidden but inherits the value from the global private_key flag)
dearchap commented 3 days ago

@samlaf When you say you have two different packages define the same flag but have different names what does that mean ? Do you mean that these two flags are supposed to give the same behavior to the application ? If you know what these flags are in advance(as you are defining them globally) why dont you just remove them from the Flag list from the package ? What you are asking is more of a golang dynamic loading/binding behavior rather than a cli specific question.

samlaf commented 3 days ago

@dearchap they could or could not have the same name. They don't necessarily have the same behavior (since the different packages might use them differently), but they should have the same value.

If they are from packages defined by the same binary as the CLI I am creating, then I could change them to have the same name. This way, once feature I would like is for urfave to allow flags defined with the same name to all be bound at the same time (instead of crashing my process with a "flags defined twice" error).

If you know what these flags are in advance(as you are defining them globally) why dont you just remove them from the Flag list from the package ?

The main constraint that I am working with, which might be something you don't recommend (but I'm not sure how to do it otherwise while keeping things clean and not requiring a gazillion lines of boilerplate) is that each of my packages/structs define their own config + cli flags to populate that config. I like this locality of code, especially when I have a few different CLIs reusing a same library from some exported module. Otherwise I would have to redefine + write the code for populating a config from flags in each separate CLI.

Does this not make sense? If there are better ways to architect stuff, I'm all ears!

What you are asking is more of a golang dynamic loading/binding behavior rather than a cli specific question.

Not sure what you mean by this, mind expanding with an example?