-
Notifications
You must be signed in to change notification settings - Fork 6
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
Propagate .cargo/config.toml
[env]
settings to the process environment
#16
Conversation
…nment Leaving the caller to read and merge config environment values with the process environment is not only cumbersome as seen in [rust-mobile/ndk#233], but these values need to be propagated into the process environment anyway to be usable by any subprocess spawned by the caller (ie. `cargo-apk` spawning `cargo rustc`, which can internally spawn a bunch of compilers and linkers too). Instead, do this automatically when the caller invokes `Subcommand::new` while still leaving the door open for crates to read the environment from the public `subcommand.manifest.env` member. [rust-mobile/ndk#233]: rust-mobile/ndk#233
/// It is interpreted as path and canonicalized relative to [`Self::workspace`] if | ||
/// [`EnvOption::Value::relative`] is set. | ||
/// | ||
/// Process environment variables (from [`std::env::var()`]) have [precedence] | ||
/// unless [`EnvOption::Value::force`] is set. This value is also returned if | ||
/// the given key was not set under `[env]`. | ||
/// | ||
/// [precedence]: https://doc.rust-lang.org/cargo/reference/config.html#env | ||
pub fn resolve_env(&self, key: &str) -> Result<Cow<'_, str>> { | ||
let config_var = self.config.env.as_ref().and_then(|env| env.get(key)); | ||
|
||
// Environment variables always have precedence unless | ||
// the extended format is used to set `force = true`: | ||
if let Some(env_option @ EnvOption::Value { force: true, .. }) = config_var { | ||
// Errors iresolving (canonicalizing, really) the config variable take precedence, too: | ||
return env_option.resolve_value(&self.workspace); | ||
} | ||
|
||
let process_var = std::env::var(key); | ||
if process_var != Err(VarError::NotPresent) { | ||
// Errors from env::var() also have precedence here: | ||
return Ok(process_var?.into()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a public function, not sure if we should keep it (and the tests associated with it)?
If we remove it (saves some maintenance overhead, I don't think the precedence rules still make sense when calling this function after set_env_vars()
has been used anyway), this is a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks @dvc94ch, I'll go ahead and merge+publish this again as I really want these changes now, we can do another breaking followup release once your awesome |
Environment variables can be set and override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. The entire handling of these variables is implemented in rust-mobile/cargo-subcommand#12 and rust-mobile/cargo-subcommand#16 which immediately populate the process environment with these variables when `Subcommand::new()` is called by `cargo-apk`.
Environment variables can be set and override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. The entire handling of these variables is implemented in rust-mobile/cargo-subcommand#12 and rust-mobile/cargo-subcommand#16 which immediately populate the process environment with these variables when `Subcommand::new()` is called by `cargo-apk`.
) Environment variables can be set and override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. The entire handling of these variables is implemented in rust-mobile/cargo-subcommand#12 and rust-mobile/cargo-subcommand#16 which immediately populate the process environment with these variables when `Subcommand::new()` is called by `cargo-apk`.
…nment Environment variables can be set and optionally override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. Besides exposing variables to all other processes called by `xbuild`, this also allows `xbuild` itself to be driven by variables set in `.cargo/config.toml`, such as `$ANDROID_HOME` needed for #116. rust-mobile/cargo-subcommand#12 rust-mobile/cargo-subcommand#16
…nment Environment variables can be set and optionally override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. Besides exposing variables to all other processes called by `xbuild`, this also allows `xbuild` itself to be driven by variables set in `.cargo/config.toml`, such as `$ANDROID_HOME` needed for #116. rust-mobile/cargo-subcommand#12 rust-mobile/cargo-subcommand#16
…nment Environment variables can be set and optionally override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. Besides exposing variables to all other processes called by `xbuild`, this also allows `xbuild` itself to be driven by variables set in `.cargo/config.toml`, such as `$ANDROID_HOME` needed for #116. rust-mobile/cargo-subcommand#12 rust-mobile/cargo-subcommand#16
…nment (#117) * Propagate `.cargo/config.toml` `[env]` settings to the process environment Environment variables can be set and optionally override the process environment through `.cargo/config.toml`'s `[env]` section: https://doc.rust-lang.org/cargo/reference/config.html#env These config variables have specific precedence rules with regards to overriding the environment set in the process, and can optionally represent paths relative to the parent of the containing `.cargo/` folder. Besides exposing variables to all other processes called by `xbuild`, this also allows `xbuild` itself to be driven by variables set in `.cargo/config.toml`, such as `$ANDROID_HOME` needed for #116. rust-mobile/cargo-subcommand#12 rust-mobile/cargo-subcommand#16 * cargo/config: Don't canonicalize joined `[env]` `relative` paths Cargo doesn't do this either, and canonicalization requires the path to exist which it does not have to.
Leaving the caller to read and merge config environment values with the process environment is not only cumbersome as seen in rust-windowing/android-ndk-rs#233, but these values need to be propagated into the process environment anyway to be usable by any subprocess spawned by the caller (ie.
cargo-apk
spawningcargo rustc
, which can internally spawn a bunch of compilers and linkers too).Instead, do this automatically when the caller invokes
Subcommand::new
while still leaving the door open for crates to read the environment from the publicsubcommand.manifest.env
member.