Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow getting values from environmental args if not passed in via the command line #712

Closed
kbknapp opened this issue Oct 28, 2016 · 10 comments
Labels
A-parsing Area: Parser's logic and needs it changed somehow.

Comments

@kbknapp
Copy link
Member

kbknapp commented Oct 28, 2016

Priority should be passed in manually, then env args, then default values.

@kbknapp kbknapp added T: new feature A-parsing Area: Parser's logic and needs it changed somehow. labels Oct 28, 2016
@kbknapp
Copy link
Member Author

kbknapp commented Oct 28, 2016

Should add a App::env_args(name) which essentially extends the command line args with whatever is inside name. In this scenario name would contain a full set of arg(s) such as --foo bar

Should also add an Arg::env_value(name) where name can be either just a value i.e. bar in --foo bar, or the whole arg, i.e. --foo bar but only for a single argument, whereas App::env_args could theoretically contain --foo bar --baz etc.

purew added a commit to purew/clap-rs that referenced this issue Nov 4, 2016
purew added a commit to purew/clap-rs that referenced this issue Nov 6, 2016
purew added a commit to purew/clap-rs that referenced this issue Nov 10, 2016
@quodlibetor
Copy link
Contributor

Something that I would love to see is supporting the (semi-standard?) technique of having env vars (and config vars) be option/argument names, screaming snake cased and prefixed with the name of the app. To support this it would be nice if there was a App::env_arg_prefix(name) so that you could do (in pseudo-clap):

    App::env_arg_prefix("myapp").Arg("--some").Arg("required")

and be able to run your app like:

MYAPP_SOME=thing MYAPP_REQUIRED=yes myapp

This also maps pretty cleanly to loading things from config files (you could just specify a config_arg_section and have everything work theoretically the same.)

@kbknapp
Copy link
Member Author

kbknapp commented Feb 2, 2018

This has already been implemented in v2 via Arg::env and Arg::env_os. Guess I forgot to close this?

@kbknapp kbknapp closed this as completed Feb 2, 2018
@quodlibetor
Copy link
Contributor

Neat!

It would still be nice to have a similar App::fallback_args_from_os(PREFIX) flag that would make it so that every arg that has a long option would also accept PREFIX_${to_screaming_snake_case(long_name)}. It's a really useful paradigm for 12FA, and it's nice to be consistent.

@kbknapp
Copy link
Member Author

kbknapp commented Feb 5, 2018

@quodlibetor I like the idea, but for now I'd rather stick with having to declare the args one would like to use with ENV vals. If an application wants to support what you're proposing, it's as simple as adding:

Arg::with_name("some")
    .long("some")
    .env("MYAPP_SOME")

I'm not sure I'm comfortable adding code that goes through ENV vars matching a prefix, converting longs to screaming snake case, doing a match, etc. This is something that could be handled pretty easily in an external crate once v3 is out (due to App::mut_arg).

@bestouff
Copy link
Contributor

bestouff commented Feb 5, 2018

Automatically reading env vars would be really nice, but guarded by a global switch, like .auto_2fa(true) or something like that.

@kbknapp
Copy link
Member Author

kbknapp commented Feb 5, 2018

I'm not necessarily opposed to that feature/setting. But with the upcoming v3 and mut_arg I would like to start pairing back some settings that could be external crates and moving them out of the core clap code, or even creating a clap_extras crate that provides these one off, modification-only of an App or Arg instance and that don't rely on core clap internals to function.

If you'd like to open an issue with those features in mind so I can track it separately, that's fine. However, I can't promise I'll get to it anytime soon as getting v3 out the door is my priority right now.

@quodlibetor
Copy link
Contributor

@kbknapp yup, that's what I'm currently doing, it would just be nice if instead of:

App::new("cool")
    .arg(
        Arg::with_name("config")
            .env("COOL_CONFIG"))
    .arg(
        Arg::with_name("out-file")
            .env("COOL_OUT_FILE"))

I could just do:

App::new("cool")
    .map_env_with_prefix("COOL_")
    .arg(Arg::with_name("config"))
    .arg(Arg::with_name("out-file"))

It's not a huge deal, it's mostly a "every now and then I am lazy about
correctly specifying env and then it's annoying" deal.

@pronebird
Copy link

I have a use case where env variable is not backed by an argument. I am currently using after_help to outline the available environment variables. It would be great to support env and collect environment variables under ENV section just like SUBCOMMANDS or FLAGS, i.e:

App::new("cool")
  .env("MAGIC_COOKIE", "Does something cool")

@quodlibetor
Copy link
Contributor

Something that recently came up in support of having this be a global property on App is it would allow linting or errorring if there are any env vars that match the prefix, but do not match any known args:

App::new("COOL")
    .env_prefix("COOL_")
    .strict_env_prefix()
    .arg(Arg::with_name("check"))

Could fail if COOL_CHCEK is in the environment, which I'm sure would have saved me hours of debugging over the course of the career.

The mut_arg feature in combination with get_arguments does seem like it would make it pretty easy to build this in to an external crate, although I'm not sure if that would/could work with the derive macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parsing Area: Parser's logic and needs it changed somehow.
Projects
None yet
Development

No branches or pull requests

4 participants