Description
I suggest an option to Arg
where one can specify a default value to be read from an environment variable. This would of course be visible in the --help
, and any type conversions should still take place.
Here's how it would look like (simplified):
Arg::with_name("redis-url")
.long("redis-url")
.value_name("URL")
.help("The URL to the Redis server to use.")
// .default_from_env("REDIS_URL")
.default_from_env_or("REDIS_URL", "redis://localhost:6379/0")
.required(true);
// --redis-url=URL The URL to the Redis server to use.
// Defaults to the value of the REDIS_URL environment variable, or "redis://localhost:6379/0".
// Without hardcoded default:
// --redis-url=URL The URL to the Redis server to use.
// Defaults to the value of the REDIS_URL environment variable.
If we had a validator
attached, it would be run on the value of the environment variable just like if the user provided the string (it's what they are doing, after all).
Note how I'm not advocating automatically determining environment variables to use, or loading any .env
files or such. There's no filesystem logic here. It's just to let the user assign the name of an environment variable to read from if the argument isn't part of the argv
.
Background
With the advent of 12-factor apps that are commonly configured using environment variables, there's a lot of patterns and support for setting environment variables outside of a process and then reading them inside the program.
I've always felt that command line options are more discoverable and more usable from workstations, so I usually want them as well. Having to hook environment variables up with the command-line argument parser means a lot of work.
Gains
By adding this feature, it'll be much easier to have apps that can be configured with both environment variables and from the command line with just a single source of truth and parsing. I don't need to validate values in two different places, and I can model required values and conflicting values in one place.
This would motivate people to add a list of environment variables to their --help
output as well.
It'll now be trivial to load a .env
before parsing with Clap and get the best of both worlds.
Alternatives
There's #712, which seems to be the same suggestion, but larger in that it'll automatically determine and format certain things. Maybe I'm misunderstanding that issue's description. I apologize in that case.
One can also manually deal with this by reading the values and assigning them as defaults at runtime. Help messages can also be manually enhanced with such references. This still complicates the argument definitions a lot, however.
I'm a Rust beginner, but I'd be willing to come up with a proof of concept PR if that would be welcome.