Skip to content

Commit

Permalink
return path and script from activation command (#151)
Browse files Browse the repository at this point in the history
* return path and script from activation command

* use result struct
  • Loading branch information
wolfv authored Apr 5, 2023
1 parent fade382 commit 399fcd4
Showing 1 changed file with 39 additions and 25 deletions.
64 changes: 39 additions & 25 deletions crates/rattler_shell/src/activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,17 @@ fn prefix_path_entries(prefix: &Path, platform: &Platform) -> Vec<PathBuf> {
}
}

/// The result of a activation. It contains the activation script and the new path entries.
/// The activation script already sets the PATH environment variable, but for "environment stacking"
/// purposes it's useful to have the new path entries separately.
pub struct ActivationResult {
/// The activation script that sets the environment variables, runs activation/deactivation scripts
/// and sets the new PATH environment variable
pub script: String,
/// The new path entries that are added to the PATH environment variable
pub path: Vec<PathBuf>,
}

impl<T: Shell + Clone> Activator<T> {
/// Create a new activator for the given conda environment.
///
Expand Down Expand Up @@ -290,14 +301,15 @@ impl<T: Shell + Clone> Activator<T> {
})
}

/// Create a activation script for a given shell
pub fn activation_script(
/// Create an activation script for a given shell and platform. This
/// returns a tuple of the newly computed PATH variable and the activation script.
pub fn activation(
&self,
variables: ActivationVariables,
) -> Result<String, ActivationError> {
let mut out = String::new();
) -> Result<ActivationResult, ActivationError> {
let mut script = String::new();

let mut path_elements = variables.path.clone().unwrap_or_default();
let mut path = variables.path.clone().unwrap_or_default();
if let Some(conda_prefix) = variables.conda_prefix {
let deactivate = Activator::from_path(
Path::new(&conda_prefix),
Expand All @@ -307,48 +319,48 @@ impl<T: Shell + Clone> Activator<T> {

for (key, _) in &deactivate.env_vars {
self.shell_type
.unset_env_var(&mut out, key)
.unset_env_var(&mut script, key)
.map_err(ActivationError::FailedToWriteActivationScript)?;
}

for deactivation_script in &deactivate.deactivation_scripts {
self.shell_type
.run_script(&mut out, deactivation_script)
.run_script(&mut script, deactivation_script)
.map_err(ActivationError::FailedToWriteActivationScript)?;
}

path_elements.retain(|x| !deactivate.paths.contains(x));
path.retain(|x| !deactivate.paths.contains(x));
}

// prepend new paths
let path_elements = [self.paths.clone(), path_elements].concat();
let path = [self.paths.clone(), path].concat();

self.shell_type
.set_path(&mut out, path_elements.as_slice())
.set_path(&mut script, path.as_slice())
.map_err(ActivationError::FailedToWriteActivationScript)?;

// deliberately not taking care of `CONDA_SHLVL` or any other complications at this point
self.shell_type
.set_env_var(
&mut out,
&mut script,
"CONDA_PREFIX",
&self.target_prefix.to_string_lossy(),
)
.map_err(ActivationError::FailedToWriteActivationScript)?;

for (key, value) in &self.env_vars {
self.shell_type
.set_env_var(&mut out, key, value)
.set_env_var(&mut script, key, value)
.map_err(ActivationError::FailedToWriteActivationScript)?;
}

for activation_script in &self.activation_scripts {
self.shell_type
.run_script(&mut out, activation_script)
.run_script(&mut script, activation_script)
.map_err(ActivationError::FailedToWriteActivationScript)?;
}

Ok(out)
Ok(ActivationResult { script, path })
}
}

Expand Down Expand Up @@ -479,19 +491,21 @@ mod tests {

let activator = Activator::from_path(tdir.path(), shell_type, Platform::Osx64).unwrap();

let script = activator.activation_script(ActivationVariables {
conda_prefix: None,
path: Some(vec![
PathBuf::from("/usr/bin"),
PathBuf::from("/bin"),
PathBuf::from("/usr/sbin"),
PathBuf::from("/sbin"),
PathBuf::from("/usr/local/bin"),
]),
});
let result = activator
.activation(ActivationVariables {
conda_prefix: None,
path: Some(vec![
PathBuf::from("/usr/bin"),
PathBuf::from("/bin"),
PathBuf::from("/usr/sbin"),
PathBuf::from("/sbin"),
PathBuf::from("/usr/local/bin"),
]),
})
.unwrap();
let prefix = tdir.path().to_str().unwrap();

script.unwrap().replace(prefix, "__PREFIX__")
result.script.replace(prefix, "__PREFIX__")
}

#[test]
Expand Down

0 comments on commit 399fcd4

Please sign in to comment.