Add Command environment variable inheritance docs

The interaction between the environment variable methods can be confusing. Specifically `env_clear` and `remove_env` have a side effects not mentioned: they disable inheriting environment variables from the parent process. I wanted to fully document this behavior as well as explain relevant edge cases in each of the `Command` env methods.

This is further confused by the return of `get_envs` which will return key/None if `remove_env` has been used, but an empty iterator if `env_clear` has been called. Or a non-empty iterator if `env_clear` was called and later explicit mappings are added. Currently there is no way (that I'm able to find) of observing whether or not the internal `env_clear=true` been toggled on the `Command` struct via its public API.

Ultimately environment variable mappings can be in one of several states:

- Explicitly set value (via `envs` / `env`) will take precedence over parent mapping
- Not explicitly set, will inherit mapping from parent
- Explicitly removed via `remove_env`, this single mapping will not inherit from parent
- Implicitly removed via `env_clear`, no mappings will inherit from parent

I tried to represent this in the relevant sections of the docs. 

This is my second ever doc PR (whoop!). I'm happy to take specific or general doc feedback. Also happy to explain the logic behind any changes or additions I made.
This commit is contained in:
schneems 2023-03-17 12:42:40 -05:00
parent 511364e787
commit 75657d5289

View File

@ -644,10 +644,19 @@ pub fn args<I, S>(&mut self, args: I) -> &mut Command
self self
} }
/// Inserts or updates an environment variable mapping. /// Inserts or updates an explicit environment variable mapping.
/// ///
/// Note that environment variable names are case-insensitive (but case-preserving) on Windows, /// This method allows you to add an environment variable mapping to the spawned process or
/// and case-sensitive on all other platforms. /// overwrite a previously set value. You can use [`Command::envs`] to set multiple environment
/// variables simultaneously.
///
/// Child processes will inherit environment variables from their parent process by default.
/// Environment variables explicitly set using [`Command::env`] take precedence over inherited
/// variables. You can disable environment variable inheritance entirely using
/// [`Command::env_clear`] or for a single key using [`Command::env_remove`].
///
/// Note that environment variable names are case-insensitive (but
/// case-preserving) on Windows and case-sensitive on all other platforms.
/// ///
/// # Examples /// # Examples
/// ///
@ -671,7 +680,19 @@ pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
self self
} }
/// Adds or updates multiple environment variable mappings. /// Inserts or updates multiple explicit environment variable mappings.
///
/// This method allows you to add multiple environment variable mappings to the spawned process
/// or overwrite previously set values. You can use [`Command::env`] to set a single environment
/// variable.
///
/// Child processes will inherit environment variables from their parent process by default.
/// Environment variables explicitly set using [`Command::envs`] take precedence over inherited
/// variables. You can disable environment variable inheritance entirely using
/// [`Command::env_clear`] or for a single key using [`Command::env_remove`].
///
/// Note that environment variable names are case-insensitive (but case-preserving) on Windows
/// and case-sensitive on all other platforms.
/// ///
/// # Examples /// # Examples
/// ///
@ -708,7 +729,18 @@ pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
self self
} }
/// Removes an environment variable mapping. /// Removes an explicitly set environment variable and prevents inheriting it from a parent
/// process.
///
/// This method will remove the explicit value of an environment variable set via
/// [`Command::env`] or [`Command::envs`]. In addition, it will prevent the spawned child
/// process from inheriting that environment variable from its parent process.
///
/// After calling [`Command::env_remove`], the value associated with its key from
/// [`Command::get_envs`] will be [`None`].
///
/// To clear all explicitly set environment variables and disable all environment variable
/// inheritance, you can use [`Command::env_clear`].
/// ///
/// # Examples /// # Examples
/// ///
@ -728,7 +760,17 @@ pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
self self
} }
/// Clears the entire environment map for the child process. /// Clears all explicitly set environment variables and prevents inheriting any parent process
/// environment variables.
///
/// This method will remove all explicitly added environment variables set via [`Command::env`]
/// or [`Command::envs`]. In addition, it will prevent the spawned child process from inheriting
/// any environment variable from its parent process.
///
/// After calling [`Command::env_remove`], the iterator from [`Command::get_envs`] will be
/// empty.
///
/// You can use [`Command::env_remove`] to clear a single mapping.
/// ///
/// # Examples /// # Examples
/// ///
@ -980,17 +1022,21 @@ pub fn get_args(&self) -> CommandArgs<'_> {
CommandArgs { inner: self.inner.get_args() } CommandArgs { inner: self.inner.get_args() }
} }
/// Returns an iterator of the environment variables that will be set when /// Returns an iterator of the environment variables explicitly set for the child process.
/// the process is spawned.
/// ///
/// Each element is a tuple `(&OsStr, Option<&OsStr>)`, where the first /// Environment variables explicitly set using [`Command::env`], [`Command::envs`], and
/// value is the key, and the second is the value, which is [`None`] if /// [`Command::env_remove`] can be retrieved with this method.
/// the environment variable is to be explicitly removed.
/// ///
/// This only includes environment variables explicitly set with /// Note that this output does not include environment variables inherited from the parent
/// [`Command::env`], [`Command::envs`], and [`Command::env_remove`]. It /// process.
/// does not include environment variables that will be inherited by the ///
/// child process. /// Each element is a tuple key/value pair `(&OsStr, Option<&OsStr>)`. A [`None`] value
/// indicates its key was explicitly removed via [`Command::env_clear`]. The associated key for
/// the [`None`] value will no longer inherit from its parent process.
///
/// An empty iterator can indicate that no explicit mappings were added or that
/// [`Command::env_clear`] was called. After calling [`Command::env_clear`], the child process
/// will not inherit any environment variables from its parent process.
/// ///
/// # Examples /// # Examples
/// ///