Add Command::next_env_prefix for env variable prefixing#6281
Add Command::next_env_prefix for env variable prefixing#6281veeceey wants to merge 2 commits intoclap-rs:masterfrom
Conversation
|
Test results (all env tests pass, including 5 new env_prefix tests): |
|
We recommend that commits represent how things should be reviewed and merged and not how they were developed. Having fixup commits means they are not atomic. There is also a strong preference for adding tests in a previous commit, with them passing, showing the current behavior. How to handle this when its a new API is context dependent. In this case, I would add the tests with the prefixes being hardcoded in each env variable and then the main commit would port it to the new API. |
| if let Some(Some(ref prefix)) = a.env_prefix { | ||
| if let Some((ref env_name, _)) = a.env { | ||
| let prefixed = format!("{}_{}", prefix, env_name.to_str().unwrap_or("")); | ||
| let value = env::var_os(&prefixed); |
There was a problem hiding this comment.
Not thrilled with us having looked up the env and now we look it up again
3450bca to
e8ca0e8
Compare
tests/builder/env.rs
Outdated
|
|
||
| #[cfg(feature = "string")] | ||
| #[test] | ||
| fn env_prefix_cli_overrides_env() { |
There was a problem hiding this comment.
This seems like it is testing env support generally rather than env-prefix-specific logic
e8ca0e8 to
05b4713
Compare
There was a problem hiding this comment.
Please keep in mind that new tests should be added in the previous commit like the other new tests.
tests/derive/env_prefix.rs
Outdated
| #[test] | ||
| fn command_next_env_prefix_cli_overrides() { | ||
| env::set_var("DERIVE_CLI_NAME", "from_env"); | ||
|
|
||
| #[derive(Debug, Clone, Parser)] | ||
| #[command(next_env_prefix = "DERIVE_CLI")] | ||
| struct CliOptions { | ||
| #[arg(long, env = "NAME")] | ||
| name: Option<String>, | ||
| } | ||
|
|
||
| let m = CliOptions::try_parse_from(vec!["", "--name", "from_cli"]).unwrap(); | ||
| assert_eq!(m.name.as_deref(), Some("from_cli")); | ||
| } |
There was a problem hiding this comment.
This seems to be testing env support
| fn command_next_env_prefix_with_flatten() { | ||
| env::set_var("FLAT_APP_DB", "mydb"); | ||
|
|
||
| #[derive(Debug, Clone, Args)] | ||
| #[command(next_env_prefix = "FLAT_APP")] | ||
| struct DbArgs { | ||
| #[arg(long, env = "DB")] | ||
| db: Option<String>, | ||
| } | ||
|
|
||
| #[derive(Debug, Clone, Parser)] | ||
| struct CliOptions { | ||
| #[command(flatten)] | ||
| db_args: DbArgs, | ||
| } |
There was a problem hiding this comment.
Missing some flatten cases that next_help_heading has, like
- flattened field with help heading
|
hey @epage, thanks for the thorough review — really helpful feedback. let me go through each point:
I'll rework the commits and push an updated version. appreciate the detailed review! |
Add tests that demonstrate the desired behavior of env variable prefixing using hardcoded prefixed env names. These tests pass with the current code and will be ported to use the new next_env_prefix / env_prefix API in the next commit. Includes both builder and derive tests covering: - Basic prefix application - Multiple args with prefix - Prefix reset - Arg-level prefix - Arg override of command prefix - Flatten with prefix on the flattened struct - Flatten with prefix on the flatten field
Add env variable prefixing support as proposed in clap-rs#3221. This follows the same pattern as next_help_heading / help_heading. - Command::next_env_prefix sets a prefix for all future args - Arg::env_prefix allows per-arg override, taking precedence - Arg::get_env_prefix getter for querying the prefix - Prefix is joined with '_' and applied during _build_self - Uses OsString operations for concatenation (no to_str) - Requires both 'env' and 'string' features - Includes env_prefix in Arg's hand-written Debug impl - Derive support via #[command(next_env_prefix = "...")] attribute - Port tests from hardcoded prefixes to the new API Closes clap-rs#3221
05b4713 to
1a94daa
Compare
|
rebased and addressed the test feedback:
|
Adds
Command::next_env_prefixwhich sets a prefix that gets prepended to all subsequent arg env variable names during build. Modeled directly afternext_help_headingas @epage suggested in #3221.How it works:
Command::next_env_prefix("MYAPP")sets the prefix for all future argsenvname and an inherited prefix, the env name gets rewritten toMYAPP_<NAME>during_build_selfnext_env_prefix(None::<&str>)The env prefix is stored on each
Arg(viaenv_prefixfield) duringarg_internal, same pattern ashelp_heading. The actual name rewriting happens during_build_selfwhich keeps help generation and env lookup unchanged.Requires both
envandstringfeatures since we need runtime string construction for the prefixed names.Closes #3221