Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions crates/pet-conda/src/environment_locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,23 @@ pub fn get_environments(conda_dir: &Path) -> Vec<PathBuf> {
}
} else if is_conda_env(conda_dir) {
envs.push(conda_dir.to_path_buf());
// If this is a conda environment under an `envs` folder, check if the grandparent
// is the conda install directory (base env) and include it as well.
// E.g. if conda_dir is `/opt/homebrew/Caskroom/miniforge/base/envs/test`,
// then the grandparent `/opt/homebrew/Caskroom/miniforge/base` is the base env.
// This ensures the base conda environment is discovered when only child envs are
// listed in environments.txt (see https://github.com/microsoft/python-environment-tools/issues/236)
if let Some(parent) = conda_dir.parent() {
if parent.file_name().map(|n| n == "envs").unwrap_or(false) {
if let Some(grandparent) = parent.parent() {
if is_conda_install(grandparent) && !envs.contains(&grandparent.to_path_buf()) {
// Recursively get environments from the conda install directory
// This will add the base env and any other sibling envs
envs.append(&mut get_environments(grandparent));
}
}
}
}
} else if conda_dir.join("envs").exists() {
// This could be a directory where conda environments are stored.
// I.e. its not necessarily the root conda install directory.
Expand Down
56 changes: 56 additions & 0 deletions crates/pet-conda/tests/environment_locations_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,59 @@ fn list_conda_envs_in_install_location() {
]
);
}

/// Test that when get_environments is called with a child environment under the `envs` folder,
/// it also discovers the parent conda install (base environment) and all sibling environments.
/// This is the fix for https://github.com/microsoft/python-environment-tools/issues/236
/// where the base conda environment wasn't discovered when only child envs were listed
/// in environments.txt (e.g., from Homebrew Cask installs like /opt/homebrew/Caskroom/miniforge/base).
#[cfg(unix)]
#[test]
fn list_conda_envs_discovers_base_from_child_env() {
use common::resolve_test_path;
use pet_conda::environment_locations::get_environments;

// Call get_environments with a child environment path (not the install directory)
let child_env_path = resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "myenv"]);

let mut locations = get_environments(&child_env_path);
locations.sort();

// Should discover not only the child env, but also the base env (conda install dir)
// and all sibling environments
assert_eq!(
locations,
vec![
resolve_test_path(&["unix", "anaconda3-2023.03"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "env_python_3"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "myenv"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "without_python"]),
]
);
}

/// Test that get_environments works correctly with an env_python_3 child environment
/// (another sibling to verify the fix works for any child env under envs folder).
#[cfg(unix)]
#[test]
fn list_conda_envs_discovers_base_from_another_child_env() {
use common::resolve_test_path;
use pet_conda::environment_locations::get_environments;

// Call get_environments with a different child environment path
let child_env_path = resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "env_python_3"]);

let mut locations = get_environments(&child_env_path);
locations.sort();

// Should discover the base env and all sibling environments
assert_eq!(
locations,
vec![
resolve_test_path(&["unix", "anaconda3-2023.03"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "env_python_3"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "myenv"]),
resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "without_python"]),
]
);
}
Loading