From 154c787c720881209b4c6c581a2b4ce188b88bb3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 23 May 2018 09:30:54 -0700 Subject: [PATCH] Add `-Z advanced-env` feature flag. --- src/cargo/core/features.rs | 2 + src/cargo/util/config.rs | 87 ++++++++++++++++++++------------------ tests/testsuite/config.rs | 9 ++++ 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index b83e242ce..29e644be3 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -308,6 +308,7 @@ pub struct CliUnstable { pub avoid_dev_deps: bool, pub minimal_versions: bool, pub package_features: bool, + pub advanced_env: bool, } impl CliUnstable { @@ -342,6 +343,7 @@ impl CliUnstable { "avoid-dev-deps" => self.avoid_dev_deps = true, "minimal-versions" => self.minimal_versions = true, "package-features" => self.package_features = true, + "advanced-env" => self.advanced_env = true, _ => bail!("unknown `-Z` flag specified: {}", k), } diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 9a6cfea5e..d62ebc159 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -965,7 +965,10 @@ impl<'de, 'config> de::Deserializer<'de> for Deserializer<'config> { visitor.visit_bool(v.parse().unwrap()) } else if let Ok(v) = v.parse::() { visitor.visit_i64(v) - } else if v.starts_with("[") && v.ends_with("]") { + } else if self.config.cli_unstable().advanced_env + && v.starts_with("[") + && v.ends_with("]") + { visitor.visit_seq(ConfigSeqAccess::new(self.config, self.key.clone())?) } else { visitor.visit_string(v.clone()) @@ -1121,16 +1124,18 @@ impl<'config> ConfigMapAccess<'config> { set.insert(ConfigKeyPart::CasePart(key)); } } - // CARGO_PROFILE_DEV_OVERRIDES_ - let env_pattern = format!("{}_", key.to_env()); - for env_key in config.env.keys() { - if env_key.starts_with(&env_pattern) { - // CARGO_PROFILE_DEV_OVERRIDES_bar_OPT_LEVEL = 3 - let rest = &env_key[env_pattern.len()..]; - // rest = bar_OPT_LEVEL - let part = rest.splitn(2, "_").next().unwrap(); - // part = "bar" - set.insert(ConfigKeyPart::CasePart(part.to_string())); + if config.cli_unstable().advanced_env { + // CARGO_PROFILE_DEV_OVERRIDES_ + let env_pattern = format!("{}_", key.to_env()); + for env_key in config.env.keys() { + if env_key.starts_with(&env_pattern) { + // CARGO_PROFILE_DEV_OVERRIDES_bar_OPT_LEVEL = 3 + let rest = &env_key[env_pattern.len()..]; + // rest = bar_OPT_LEVEL + let part = rest.splitn(2, "_").next().unwrap(); + // part = "bar" + set.insert(ConfigKeyPart::CasePart(part.to_string())); + } } } Ok(ConfigMapAccess { @@ -1214,37 +1219,39 @@ impl ConfigSeqAccess { } } - // Parse an environment string as a TOML array. - let env_key = key.to_env(); - let def = Definition::Environment(env_key.clone()); - if let Some(v) = config.env.get(&env_key) { - if !(v.starts_with("[") && v.ends_with("]")) { - return Err(ConfigError::new( - format!("should have TOML list syntax, found `{}`", v), - def.clone(), - )); - } - let temp_key = key.last().to_env(); - let toml_s = format!("{}={}", temp_key, v); - let toml_v: toml::Value = toml::de::from_str(&toml_s).map_err(|e| { - ConfigError::new(format!("could not parse TOML list: {}", e), def.clone()) - })?; - let values = toml_v - .as_table() - .unwrap() - .get(&temp_key) - .unwrap() - .as_array() - .expect("env var was not array"); - for value in values { - // TODO: support other types - let s = value.as_str().ok_or_else(|| { - ConfigError::new( - format!("expected string, found {}", value.type_str()), + if config.cli_unstable().advanced_env { + // Parse an environment string as a TOML array. + let env_key = key.to_env(); + let def = Definition::Environment(env_key.clone()); + if let Some(v) = config.env.get(&env_key) { + if !(v.starts_with("[") && v.ends_with("]")) { + return Err(ConfigError::new( + format!("should have TOML list syntax, found `{}`", v), def.clone(), - ) + )); + } + let temp_key = key.last().to_env(); + let toml_s = format!("{}={}", temp_key, v); + let toml_v: toml::Value = toml::de::from_str(&toml_s).map_err(|e| { + ConfigError::new(format!("could not parse TOML list: {}", e), def.clone()) })?; - res.push((s.to_string(), def.clone())); + let values = toml_v + .as_table() + .unwrap() + .get(&temp_key) + .unwrap() + .as_array() + .expect("env var was not array"); + for value in values { + // TODO: support other types + let s = value.as_str().ok_or_else(|| { + ConfigError::new( + format!("expected string, found {}", value.type_str()), + def.clone(), + ) + })?; + res.push((s.to_string(), def.clone())); + } } } Ok(ConfigSeqAccess { diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index 4ee42d9e2..f9d33e8c4 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -55,6 +55,15 @@ fn new_config(env: &[(&str, &str)]) -> Config { .collect(); let mut config = Config::new(shell, cwd, homedir); config.set_env(env); + config.configure( + 0, + None, + &None, + false, + false, + &None, + &["advanced-env".into()], + ).unwrap(); config }