urfave / cli

A simple, fast, and fun package for building command line apps in Go

Home Page:https://cli.urfave.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamically keyed maps

nrwiersma opened this issue · comments

Checklist

  • Are you running the latest v3 release? The list of releases is here.
  • Did you check the manual for your release? The v3 manual is here.
  • Did you perform a search about this feature? Here's the GitHub guide about searching.

What problem does this solve?

First off, thank you for you time in this project, it is greatly appreciated.

Secondly, I am aware this is perhaps a fairly out there idea, and fully understand if this is not a direction you wish to pursue.

That said, now that maps exist in v3, it would be great to support some form of dynamically keyed args. For example:

I would like to take hosts and TLS certs for a dynamic set of regions. As it stands now, this is not possible without using additional configuration files when using environment variables. To make the problem more interesting, things like TLS certs will often be kept in separate files or secrets, to make handling them simpler, not in a single large config file.

Solution description

The cli would allow single keyed matcher that could be split into a prefix and postfix, and could look something like this:

cli.MatchedMapFlag{
  Name: "region-conns",
  Match: "conns.%s.host",
  EnvVars: []string{"CONNS_%s_HOST"},
}

Which would accept:

$ app --conns.eu.host=127.0.0.1 --conns.za.host=10.0.0.1

or

$ CONNS_EU_HOST=127.0.0.1 CONNS_ZA_HOST=10.0.0.1 app

and would be accessed as

fmt.Println(c.MatchedMap("region-conns"))
// {eu: 127.0.0.1, za: 10.0.0.1}

I fully understand that this deviates from the standard flag parsing but I believe it could be very a very powerful addition.

Describe alternatives you've considered

I have considered using v3 maps which might work purely from a command line PoV, but they break down with environment variables, as they all need to live in the same variable.

@nrwiersma You surmise correct that this deviates from std flag parsing. Even though I like this feature It is non-trivial to implement. With v3 you could get away with a regular map

--conns.host="eu:127.0.0.1" --conns.host="us:192.168.0.1" 

I really dont see this as very beneficial from a maintenance standpoint.

Fait enough. However, you cannot do the same with environment variables, which is 90% of how I use this.

I do understand the implementation and maintenance burden.