Skip to content

Values from environment variables #814

Closed
@Mange

Description

@Mange

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions