From 49013db40f187795c18674324bfc403b5c3a58bd Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 15:19:02 +1000
Subject: [PATCH 1/8] Tweek conda search paths

---
 crates/pet-conda/src/conda_rc.rs              | 11 ++-
 crates/pet-conda/src/environment_locations.rs | 94 +++++++++++++------
 crates/pet-fs/src/path.rs                     | 18 ++++
 3 files changed, 91 insertions(+), 32 deletions(-)

diff --git a/crates/pet-conda/src/conda_rc.rs b/crates/pet-conda/src/conda_rc.rs
index 9510f93e..b52c93e9 100644
--- a/crates/pet-conda/src/conda_rc.rs
+++ b/crates/pet-conda/src/conda_rc.rs
@@ -186,13 +186,14 @@ fn get_conda_conda_rc_from_path(conda_rc: &PathBuf) -> Option<Condarc> {
 
 fn parse_conda_rc(conda_rc: &Path) -> Option<Condarc> {
     let reader = fs::read_to_string(conda_rc).ok()?;
-    trace!("Possible conda_rc: {:?}", conda_rc);
     if let Some(cfg) = parse_conda_rc_contents(&reader) {
+        trace!("conda_rc: {:?} with env_dirs {:?}", conda_rc, cfg.env_dirs);
         Some(Condarc {
             env_dirs: cfg.env_dirs,
             files: vec![conda_rc.to_path_buf()],
         })
     } else {
+        trace!("Failed to parse or empty conda_rc: {:?}", conda_rc);
         Some(Condarc {
             env_dirs: vec![],
             files: vec![conda_rc.to_path_buf()],
@@ -220,7 +221,9 @@ fn parse_conda_rc_contents(contents: &str) -> Option<Condarc> {
                 if item_str.is_empty() {
                     continue;
                 }
-                env_dirs.push(expand_path(PathBuf::from(item_str.trim())));
+                let env_dir = expand_path(PathBuf::from(item_str.trim()));
+                trace!("env_dir: {:?} parsed as {:?}", item_str.trim(), env_dir);
+                env_dirs.push(env_dir);
             }
         }
         if let Some(items) = doc["envs_path"].as_vec() {
@@ -229,7 +232,9 @@ fn parse_conda_rc_contents(contents: &str) -> Option<Condarc> {
                 if item_str.is_empty() {
                     continue;
                 }
-                env_dirs.push(expand_path(PathBuf::from(item_str.trim())));
+                let env_dir = expand_path(PathBuf::from(item_str.trim()));
+                trace!("env_path: {:?} parsed as {:?}", item_str.trim(), env_dir);
+                env_dirs.push(env_dir);
             }
         }
     }
diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 8f67c2c5..e24ece77 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -229,12 +229,41 @@ pub fn get_known_conda_install_locations(
         known_paths.push(PathBuf::from(conda));
     }
     if let Some(home) = env_vars.clone().home {
-        known_paths.push(home.clone().join("anaconda3"));
-        known_paths.push(home.clone().join("miniconda3"));
-        known_paths.push(home.clone().join("miniforge3"));
-        known_paths.push(home.clone().join("micromamba"));
+        for prefix in [
+            home.clone(),
+            // https://stackoverflow.com/questions/35709497/anaconda-python-where-are-the-virtual-environments-stored
+            home.join(".conda"),
+            // https://stackoverflow.com/questions/35709497/anaconda-python-where-are-the-virtual-environments-stored
+            home.join(".local"),
+            // https://stackoverflow.com/questions/35709497/anaconda-python-where-are-the-virtual-environments-stored
+            PathBuf::from("C:\\ProgramData"),
+            PathBuf::from(format!(
+                "{}:\\ProgramData",
+                env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+            )),
+            // https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html
+            PathBuf::from("C:\\"),
+            PathBuf::from(format!(
+                "{}:\\",
+                env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+            )),
+        ] {
+            known_paths.push(prefix.clone().join("anaconda"));
+            known_paths.push(prefix.clone().join("anaconda3"));
+            known_paths.push(prefix.clone().join("miniconda"));
+            known_paths.push(prefix.clone().join("miniconda3"));
+            known_paths.push(prefix.clone().join("miniforge3"));
+            known_paths.push(prefix.clone().join("micromamba"));
+        }
+        // From ./conda/base/constants.py (conda repo)
+        known_paths.push(PathBuf::from("C:\\ProgramData\\conda\\conda"));
+        known_paths.push(PathBuf::from(format!(
+            "{}:\\ProgramData\\conda\\conda",
+            env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+        )));
         // E.g. C:\Users\user name\.conda where we have `envs`` under this directory.
         known_paths.push(home.join(".conda"));
+        known_paths.push(home.join(".local"));
         // E.g. C:\Users\user name\AppData\Local\conda\conda\envs
         known_paths.push(
             home.join("AppData")
@@ -266,25 +295,16 @@ pub fn get_known_conda_install_locations(
     env_vars: &EnvVariables,
     conda_executable: &Option<PathBuf>,
 ) -> Vec<PathBuf> {
-    let mut known_paths = vec![];
-    let home_value = env_vars.clone().home.unwrap_or_default();
-    let directories_to_look_in = [
-        "/opt",
-        "/usr/share",
-        "/usr/local",
-        "/usr",
-        home_value.to_str().unwrap_or_default(),
-        "", // We need to look in `/anaconda3` and `/miniconda3` as well.
+    let mut known_paths = vec![
+        // We need to look in `/anaconda3` and `/miniconda3` as well.
+        PathBuf::from("/anaconda"),
+        PathBuf::from("/anaconda3"),
+        PathBuf::from("/miniconda"),
+        PathBuf::from("/miniconda3"),
+        PathBuf::from("/miniforge"),
+        PathBuf::from("/miniforge3"),
+        PathBuf::from("/micromamba"),
     ];
-    for directory in directories_to_look_in.iter() {
-        known_paths.push(PathBuf::from(format!("{directory}/anaconda")));
-        known_paths.push(PathBuf::from(format!("{directory}/anaconda3")));
-        known_paths.push(PathBuf::from(format!("{directory}/miniconda")));
-        known_paths.push(PathBuf::from(format!("{directory}/miniconda3")));
-        known_paths.push(PathBuf::from(format!("{directory}/miniforge")));
-        known_paths.push(PathBuf::from(format!("{directory}/miniforge3")));
-        known_paths.push(PathBuf::from(format!("{directory}/micromamba")));
-    }
     if let Some(ref conda_root) = env_vars.conda_root {
         known_paths.push(expand_path(PathBuf::from(conda_root.clone())));
     }
@@ -297,14 +317,30 @@ pub fn get_known_conda_install_locations(
     if let Some(ref conda) = env_vars.conda {
         known_paths.push(expand_path(PathBuf::from(conda)));
     }
-    if let Some(ref home) = env_vars.home {
-        known_paths.push(home.clone().join("anaconda"));
-        known_paths.push(home.clone().join("anaconda3"));
-        known_paths.push(home.clone().join("miniconda"));
-        known_paths.push(home.clone().join("miniconda3"));
-        known_paths.push(home.clone().join("miniforge3"));
-        known_paths.push(home.clone().join("micromamba"));
+    if let Some(home) = env_vars.home.clone() {
+        // https://stackoverflow.com/questions/35709497/anaconda-python-where-are-the-virtual-environments-stored
+        for prefix in [
+            home.clone(),
+            // https://towardsdatascience.com/manage-your-python-virtual-environment-with-conda-a0d2934d5195
+            home.join("opt"),
+            home.join(".conda"),
+            home.join(".local"),
+            // https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html
+            PathBuf::from("/opt"),
+            PathBuf::from("/usr/share"),
+            PathBuf::from("/usr/local"),
+            PathBuf::from("/usr"),
+        ] {
+            known_paths.push(prefix.clone().join("anaconda"));
+            known_paths.push(prefix.clone().join("anaconda3"));
+            known_paths.push(prefix.clone().join("miniconda"));
+            known_paths.push(prefix.clone().join("miniconda3"));
+            known_paths.push(prefix.clone().join("miniforge3"));
+            known_paths.push(prefix.clone().join("micromamba"));
+        }
+
         known_paths.push(home.join(".conda"));
+        known_paths.push(home.join(".local"));
     }
     if let Some(conda_dir) = get_conda_dir_from_exe(conda_executable) {
         known_paths.push(conda_dir);
diff --git a/crates/pet-fs/src/path.rs b/crates/pet-fs/src/path.rs
index c3c15bf6..39a2e823 100644
--- a/crates/pet-fs/src/path.rs
+++ b/crates/pet-fs/src/path.rs
@@ -79,6 +79,24 @@ pub fn expand_path(path: PathBuf) -> PathBuf {
             }
         }
     }
+
+    // Specifically for https://docs.conda.io/projects/conda/en/23.1.x/user-guide/configuration/use-condarc.html#expansion-of-environment-variables
+    if path.to_str().unwrap_or_default().contains("${USERNAME}")
+        || path.to_str().unwrap_or_default().contains("${HOME}")
+    {
+        let username = env::var("USERNAME")
+            .or(env::var("USER"))
+            .unwrap_or_default();
+        let home = env::var("HOME")
+            .or_else(|_| env::var("USERPROFILE"))
+            .unwrap_or_default();
+        return PathBuf::from(
+            path.to_str()
+                .unwrap()
+                .replace("${USERNAME}", &username)
+                .replace("${HOME}", &home),
+        );
+    }
     path
 }
 

From e2353776375af6aea766ea57b6cf55af10d05b1b Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 15:22:34 +1000
Subject: [PATCH 2/8] fixes

---
 crates/pet-conda/src/environment_locations.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index e24ece77..6503b262 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -10,7 +10,7 @@ use log::trace;
 use pet_fs::path::{expand_path, norm_case};
 use pet_python_utils::platform_dirs::Platformdirs;
 use std::{
-    fs,
+    env, fs,
     path::{Path, PathBuf},
     thread,
 };
@@ -100,8 +100,9 @@ fn get_conda_environment_paths_from_known_paths(env_vars: &EnvVariables) -> Vec<
         // Expland variables in some of these
         // https://docs.conda.io/projects/conda/en/4.13.x/user-guide/configuration/use-condarc.html#expansion-of-environment-variables
         if let Some(conda_envs_path) = &env_vars.conda_envs_path {
-            let conda_envs_path = expand_path(PathBuf::from(conda_envs_path.clone()));
-            known_conda_paths.push(conda_envs_path);
+            for path in env::split_paths(&conda_envs_path) {
+                known_conda_paths.push(expand_path(PathBuf::from(path.clone())));
+            }
         }
 
         for path in known_conda_paths {

From 252f9cde0bb00cf759c0583d8555e812db1085d0 Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 16:03:10 +1000
Subject: [PATCH 3/8] fixes

---
 crates/pet-conda/src/environment_locations.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 6503b262..004343c8 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -101,7 +101,7 @@ fn get_conda_environment_paths_from_known_paths(env_vars: &EnvVariables) -> Vec<
         // https://docs.conda.io/projects/conda/en/4.13.x/user-guide/configuration/use-condarc.html#expansion-of-environment-variables
         if let Some(conda_envs_path) = &env_vars.conda_envs_path {
             for path in env::split_paths(&conda_envs_path) {
-                known_conda_paths.push(expand_path(PathBuf::from(path.clone())));
+                known_conda_paths.push(expand_path(path));
             }
         }
 

From b007b5349c7b0c85bdfe5c8cddbb5ebfacf1c911 Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 16:33:34 +1000
Subject: [PATCH 4/8] Fixes

---
 crates/pet-conda/src/conda_rc.rs              | 56 +++++++++++++------
 crates/pet-conda/src/env_variables.rs         |  6 ++
 crates/pet-conda/src/environment_locations.rs | 34 +++++++++--
 3 files changed, 76 insertions(+), 20 deletions(-)

diff --git a/crates/pet-conda/src/conda_rc.rs b/crates/pet-conda/src/conda_rc.rs
index b52c93e9..da4f6411 100644
--- a/crates/pet-conda/src/conda_rc.rs
+++ b/crates/pet-conda/src/conda_rc.rs
@@ -6,7 +6,7 @@ use log::trace;
 use pet_fs::path::expand_path;
 use std::{
     collections::HashSet,
-    fs,
+    env, fs,
     path::{Path, PathBuf},
 };
 use yaml_rust2::YamlLoader;
@@ -29,7 +29,7 @@ impl Condarc {
 // Search paths documented here
 // https://conda.io/projects/conda/en/latest/user-guide/configuration/use-condarc.html#searching-for-condarc
 // https://github.com/conda/conda/blob/3ae5d7cf6cbe2b0ff9532359456b7244ae1ea5ef/conda/base/constants.py#L28
-fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
+pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
     use crate::utils::change_root_of_path;
 
     let mut search_paths: Vec<PathBuf> = vec![];
@@ -40,6 +40,21 @@ fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
                 "C:\\ProgramData\\conda\\.condarc",
                 "C:\\ProgramData\\conda\\condarc",
                 "C:\\ProgramData\\conda\\condarc.d",
+                format!(
+                    "{}:\\ProgramData\\conda\\.condarc",
+                    env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+                )
+                .as_str(),
+                format!(
+                    "{}:\\ProgramData\\conda\\condarc",
+                    env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+                )
+                .as_str(),
+                format!(
+                    "{}:\\ProgramData\\conda\\condarc.d",
+                    env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
+                )
+                .as_str(),
             ]
             .iter()
             .map(PathBuf::from)
@@ -63,10 +78,11 @@ fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
         );
     }
     if let Some(ref conda_root) = env_vars.conda_root {
+        let conda_root = expand_path(PathBuf::from(conda_root.clone()));
         search_paths.append(&mut vec![
-            PathBuf::from(conda_root.clone()).join(".condarc"),
-            PathBuf::from(conda_root.clone()).join("condarc"),
-            PathBuf::from(conda_root.clone()).join(".condarc.d"),
+            conda_root.join(".condarc"),
+            conda_root.join("condarc"),
+            conda_root.join(".condarc.d"),
         ]);
     }
     if let Some(ref xdg_config_home) = env_vars.xdg_config_home {
@@ -88,21 +104,23 @@ fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
         ]);
     }
     if let Some(ref conda_prefix) = env_vars.conda_prefix {
+        let conda_prefix = expand_path(PathBuf::from(conda_prefix.clone()));
         search_paths.append(&mut vec![
-            PathBuf::from(conda_prefix.clone()).join(".condarc"),
-            PathBuf::from(conda_prefix.clone()).join("condarc"),
-            PathBuf::from(conda_prefix.clone()).join(".condarc.d"),
+            conda_prefix.join(".condarc"),
+            conda_prefix.join("condarc"),
+            conda_prefix.join(".condarc.d"),
         ]);
     }
     if let Some(ref conda_dir) = env_vars.conda_dir {
+        let conda_dir = expand_path(PathBuf::from(conda_dir.clone()));
         search_paths.append(&mut vec![
-            PathBuf::from(conda_dir.clone()).join(".condarc"),
-            PathBuf::from(conda_dir.clone()).join("condarc"),
-            PathBuf::from(conda_dir.clone()).join(".condarc.d"),
+            conda_dir.join(".condarc"),
+            conda_dir.join("condarc"),
+            conda_dir.join(".condarc.d"),
         ]);
     }
     if let Some(ref condarc) = env_vars.condarc {
-        search_paths.append(&mut vec![PathBuf::from(condarc)]);
+        search_paths.append(&mut vec![expand_path(PathBuf::from(condarc))]);
     }
 
     let search_paths: HashSet<_> = search_paths.into_iter().collect();
@@ -157,15 +175,21 @@ fn get_conda_conda_rc_from_path(conda_rc: &PathBuf) -> Option<Condarc> {
                 .map(|e| e.path())
                 .filter(|p| p.is_file())
             {
-                let file_name = path.file_name().unwrap().to_str().unwrap_or_default();
+                let file_name = path
+                    .file_name()
+                    .unwrap()
+                    .to_str()
+                    .unwrap_or_default()
+                    .to_lowercase();
                 let extension = path
                     .extension()
                     .unwrap_or_default()
                     .to_str()
-                    .unwrap_or_default();
+                    .unwrap_or_default()
+                    .to_lowercase();
 
-                if POSSIBLE_CONDA_RC_FILES.contains(&file_name)
-                    || SUPPORTED_EXTENSIONS.contains(&extension)
+                if POSSIBLE_CONDA_RC_FILES.contains(&file_name.as_str())
+                    || SUPPORTED_EXTENSIONS.contains(&extension.as_str())
                     || file_name.contains("condarc")
                 {
                     if let Some(ref mut cfg) = parse_conda_rc(&path) {
diff --git a/crates/pet-conda/src/env_variables.rs b/crates/pet-conda/src/env_variables.rs
index 1559c397..bbb91add 100644
--- a/crates/pet-conda/src/env_variables.rs
+++ b/crates/pet-conda/src/env_variables.rs
@@ -25,6 +25,10 @@ pub struct EnvVariables {
     /// https://docs.conda.io/projects/conda/en/22.11.x/user-guide/configuration/use-condarc.html
     pub conda_envs_path: Option<String>,
     pub condarc: Option<String>,
+    // https://anaconda-project.readthedocs.io/en/latest/config.html
+    pub anaconda_project_envs_path: Option<String>,
+    // https://anaconda-project.readthedocs.io/en/latest/config.html
+    pub project_dir: Option<String>,
     pub xdg_config_home: Option<String>,
     pub known_global_search_locations: Vec<PathBuf>,
 }
@@ -44,6 +48,8 @@ impl EnvVariables {
             conda: env.get_env_var("CONDA".to_string()),
             conda_prefix: env.get_env_var("CONDA_PREFIX".to_string()),
             conda_envs_path: env.get_env_var("CONDA_ENVS_PATH".to_string()),
+            anaconda_project_envs_path: env.get_env_var("ANACONDA_PROJECT_ENVS_PATH".to_string()),
+            project_dir: env.get_env_var("PROJECT_DIR".to_string()),
             condarc: env.get_env_var("CONDARC".to_string()),
             xdg_config_home: env.get_env_var("XDG_CONFIG_HOME".to_string()),
             known_global_search_locations: env.get_know_global_search_locations(),
diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 004343c8..2f140eb2 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -2,7 +2,7 @@
 // Licensed under the MIT License.
 
 use crate::{
-    conda_rc::Condarc,
+    conda_rc::{get_conda_rc_search_paths, Condarc},
     env_variables::EnvVariables,
     utils::{is_conda_env, is_conda_install},
 };
@@ -66,13 +66,25 @@ pub fn get_conda_environment_paths(
  * <user home>/AppData/Local/conda/conda/envs
  */
 fn get_conda_environment_paths_from_conda_rc(env_vars: &EnvVariables) -> Vec<PathBuf> {
+    // Use the conda rc directories as well.
+    let mut env_dirs = vec![];
+    for rc_file_dir in get_conda_rc_search_paths(env_vars) {
+        if rc_file_dir.is_dir() {
+            env_dirs.push(rc_file_dir);
+        } else if rc_file_dir.is_file() {
+            if let Some(dir) = rc_file_dir.parent() {
+                env_dirs.push(dir.to_path_buf());
+            }
+        }
+    }
+
     if let Some(conda_rc) = Condarc::from(env_vars) {
         trace!("Conda environments in .condarc {:?}", conda_rc.env_dirs);
-        conda_rc.env_dirs
+        env_dirs.append(&mut conda_rc.env_dirs.clone());
     } else {
         trace!("No Conda environments in .condarc");
-        vec![]
     }
+    env_dirs
 }
 
 fn get_conda_environment_paths_from_known_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
@@ -104,6 +116,16 @@ fn get_conda_environment_paths_from_known_paths(env_vars: &EnvVariables) -> Vec<
                 known_conda_paths.push(expand_path(path));
             }
         }
+        // https://anaconda-project.readthedocs.io/en/latest/config.html
+        if let Some(conda_envs_path) = &env_vars.anaconda_project_envs_path {
+            for path in env::split_paths(&conda_envs_path) {
+                known_conda_paths.push(expand_path(path));
+            }
+        }
+        // https://anaconda-project.readthedocs.io/en/latest/config.html
+        if let Some(project_dir) = &env_vars.project_dir {
+            known_conda_paths.push(expand_path(PathBuf::from(project_dir)));
+        }
 
         for path in known_conda_paths {
             if let Ok(entries) = fs::read_dir(path) {
@@ -226,8 +248,11 @@ pub fn get_known_conda_install_locations(
     if let Some(ref conda_prefix) = env_vars.conda_prefix {
         known_paths.push(expand_path(PathBuf::from(conda_prefix.clone())));
     }
+    if let Some(ref conda_dir) = env_vars.conda_dir {
+        known_paths.push(expand_path(PathBuf::from(conda_dir.clone())));
+    }
     if let Some(ref conda) = env_vars.conda {
-        known_paths.push(PathBuf::from(conda));
+        known_paths.push(expand_path(PathBuf::from(conda)));
     }
     if let Some(home) = env_vars.clone().home {
         for prefix in [
@@ -340,6 +365,7 @@ pub fn get_known_conda_install_locations(
             known_paths.push(prefix.clone().join("micromamba"));
         }
 
+        known_paths.push(PathBuf::from("/opt").join("conda"));
         known_paths.push(home.join(".conda"));
         known_paths.push(home.join(".local"));
     }

From c794a19b4737357fc3321e83d7119e88a73af104 Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 16:39:17 +1000
Subject: [PATCH 5/8] fixes

---
 crates/pet-conda/tests/common.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/crates/pet-conda/tests/common.rs b/crates/pet-conda/tests/common.rs
index 4519d16b..58d96542 100644
--- a/crates/pet-conda/tests/common.rs
+++ b/crates/pet-conda/tests/common.rs
@@ -32,6 +32,8 @@ pub fn create_env_variables(home: PathBuf, root: PathBuf) -> EnvVariables {
         xdg_config_home: None,
         conda_envs_path: None,
         conda_dir: None,
+        anaconda_project_envs_path: None,
+        project_dir: None,
     }
 }
 

From 2fc1e1c4184cc92969cde03781f09f1f0064ef50 Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 16:52:06 +1000
Subject: [PATCH 6/8] Support for homebrew conda

---
 crates/pet-conda/src/environment_locations.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 2f140eb2..558307e3 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -356,6 +356,8 @@ pub fn get_known_conda_install_locations(
             PathBuf::from("/usr/share"),
             PathBuf::from("/usr/local"),
             PathBuf::from("/usr"),
+            PathBuf::from("/opt/homebrew"),
+            PathBuf::from("/home/linuxbrew/.linuxbrew"),
         ] {
             known_paths.push(prefix.clone().join("anaconda"));
             known_paths.push(prefix.clone().join("anaconda3"));

From 781b8b3f06987e70d226cdb44fb9980f91f33b48 Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 17:02:50 +1000
Subject: [PATCH 7/8] misc

---
 crates/pet-conda/src/conda_rc.rs              | 12 ++++++++++++
 crates/pet-conda/src/env_variables.rs         |  4 ++++
 crates/pet-conda/src/environment_locations.rs |  3 +++
 crates/pet-conda/tests/common.rs              |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/crates/pet-conda/src/conda_rc.rs b/crates/pet-conda/src/conda_rc.rs
index da4f6411..98990f8c 100644
--- a/crates/pet-conda/src/conda_rc.rs
+++ b/crates/pet-conda/src/conda_rc.rs
@@ -40,6 +40,7 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
                 "C:\\ProgramData\\conda\\.condarc",
                 "C:\\ProgramData\\conda\\condarc",
                 "C:\\ProgramData\\conda\\condarc.d",
+                "C:\\ProgramData\\conda\\.mambarc",
                 format!(
                     "{}:\\ProgramData\\conda\\.condarc",
                     env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
@@ -66,9 +67,11 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
                 "/etc/conda/.condarc",
                 "/etc/conda/condarc",
                 "/etc/conda/condarc.d",
+                "/etc/conda/mambarc",
                 "/var/lib/conda/.condarc",
                 "/var/lib/conda/condarc",
                 "/var/lib/conda/condarc.d",
+                "/var/lib/conda/.mambarc",
             ]
             .iter()
             .map(PathBuf::from)
@@ -83,6 +86,7 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
             conda_root.join(".condarc"),
             conda_root.join("condarc"),
             conda_root.join(".condarc.d"),
+            conda_root.join(".mambarc"),
         ]);
     }
     if let Some(ref xdg_config_home) = env_vars.xdg_config_home {
@@ -90,6 +94,7 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
             PathBuf::from(xdg_config_home.clone()).join(".condarc"),
             PathBuf::from(xdg_config_home.clone()).join("condarc"),
             PathBuf::from(xdg_config_home.clone()).join(".condarc.d"),
+            PathBuf::from(xdg_config_home.clone()).join(".mambarc"),
         ]);
     }
     if let Some(ref home) = env_vars.home {
@@ -101,6 +106,9 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
             home.join(".conda").join("condarc"),
             home.join(".conda").join("condarc.d"),
             home.join(".condarc"),
+            home.join("condarc"),
+            home.join("condarc.d"),
+            home.join(".mambarc"),
         ]);
     }
     if let Some(ref conda_prefix) = env_vars.conda_prefix {
@@ -109,6 +117,7 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
             conda_prefix.join(".condarc"),
             conda_prefix.join("condarc"),
             conda_prefix.join(".condarc.d"),
+            conda_prefix.join(".mamabarc"),
         ]);
     }
     if let Some(ref conda_dir) = env_vars.conda_dir {
@@ -122,6 +131,9 @@ pub fn get_conda_rc_search_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
     if let Some(ref condarc) = env_vars.condarc {
         search_paths.append(&mut vec![expand_path(PathBuf::from(condarc))]);
     }
+    if let Some(ref mambarc) = env_vars.mambarc {
+        search_paths.append(&mut vec![expand_path(PathBuf::from(mambarc))]);
+    }
 
     let search_paths: HashSet<_> = search_paths.into_iter().collect();
     search_paths.into_iter().collect()
diff --git a/crates/pet-conda/src/env_variables.rs b/crates/pet-conda/src/env_variables.rs
index bbb91add..e2bd79c2 100644
--- a/crates/pet-conda/src/env_variables.rs
+++ b/crates/pet-conda/src/env_variables.rs
@@ -22,9 +22,11 @@ pub struct EnvVariables {
     pub conda_dir: Option<String>,
     pub conda: Option<String>,
     pub conda_prefix: Option<String>,
+    pub mamba_root_prefix: Option<String>,
     /// https://docs.conda.io/projects/conda/en/22.11.x/user-guide/configuration/use-condarc.html
     pub conda_envs_path: Option<String>,
     pub condarc: Option<String>,
+    pub mambarc: Option<String>,
     // https://anaconda-project.readthedocs.io/en/latest/config.html
     pub anaconda_project_envs_path: Option<String>,
     // https://anaconda-project.readthedocs.io/en/latest/config.html
@@ -47,10 +49,12 @@ impl EnvVariables {
             conda_root: env.get_env_var("CONDA_ROOT".to_string()),
             conda: env.get_env_var("CONDA".to_string()),
             conda_prefix: env.get_env_var("CONDA_PREFIX".to_string()),
+            mamba_root_prefix: env.get_env_var("MAMBA_ROOT_PREFIX".to_string()),
             conda_envs_path: env.get_env_var("CONDA_ENVS_PATH".to_string()),
             anaconda_project_envs_path: env.get_env_var("ANACONDA_PROJECT_ENVS_PATH".to_string()),
             project_dir: env.get_env_var("PROJECT_DIR".to_string()),
             condarc: env.get_env_var("CONDARC".to_string()),
+            mambarc: env.get_env_var("MAMBARC".to_string()),
             xdg_config_home: env.get_env_var("XDG_CONFIG_HOME".to_string()),
             known_global_search_locations: env.get_know_global_search_locations(),
         }
diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 558307e3..32e528eb 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -337,6 +337,9 @@ pub fn get_known_conda_install_locations(
     if let Some(ref conda_prefix) = env_vars.conda_prefix {
         known_paths.push(expand_path(PathBuf::from(conda_prefix.clone())));
     }
+    if let Some(ref mamba_root_prefix) = env_vars.mamba_root_prefix {
+        known_paths.push(expand_path(PathBuf::from(mamba_root_prefix.clone())));
+    }
     if let Some(ref conda_dir) = env_vars.conda_dir {
         known_paths.push(expand_path(PathBuf::from(conda_dir.clone())));
     }
diff --git a/crates/pet-conda/tests/common.rs b/crates/pet-conda/tests/common.rs
index 58d96542..1a282083 100644
--- a/crates/pet-conda/tests/common.rs
+++ b/crates/pet-conda/tests/common.rs
@@ -34,6 +34,8 @@ pub fn create_env_variables(home: PathBuf, root: PathBuf) -> EnvVariables {
         conda_dir: None,
         anaconda_project_envs_path: None,
         project_dir: None,
+        mamba_root_prefix: None,
+        mambarc: None,
     }
 }
 

From 42f9424a31457c8b2d0e5cdf580c84ee9ed2dfbf Mon Sep 17 00:00:00 2001
From: Don Jayamanne <don.jayamanne@outlook.com>
Date: Tue, 16 Jul 2024 17:17:39 +1000
Subject: [PATCH 8/8] misc

---
 crates/pet-conda/src/environment_locations.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs
index 32e528eb..0bfc0f1c 100644
--- a/crates/pet-conda/src/environment_locations.rs
+++ b/crates/pet-conda/src/environment_locations.rs
@@ -254,6 +254,7 @@ pub fn get_known_conda_install_locations(
     if let Some(ref conda) = env_vars.conda {
         known_paths.push(expand_path(PathBuf::from(conda)));
     }
+    let app_data = PathBuf::from(env::var("LOCALAPPDATA").unwrap_or_default());
     if let Some(home) = env_vars.clone().home {
         for prefix in [
             home.clone(),
@@ -273,6 +274,8 @@ pub fn get_known_conda_install_locations(
                 "{}:\\",
                 env::var("SYSTEMDRIVE").unwrap_or("C".to_string())
             )),
+            // https://community.anaconda.cloud/t/conda-update-anaconda/43656/7
+            app_data.clone(),
         ] {
             known_paths.push(prefix.clone().join("anaconda"));
             known_paths.push(prefix.clone().join("anaconda3"));
@@ -291,6 +294,7 @@ pub fn get_known_conda_install_locations(
         known_paths.push(home.join(".conda"));
         known_paths.push(home.join(".local"));
         // E.g. C:\Users\user name\AppData\Local\conda\conda\envs
+        known_paths.push(app_data.join("conda").join("conda"));
         known_paths.push(
             home.join("AppData")
                 .join("Local")
