Skip to content

Commit b3a5cef

Browse files
committed
Get conda env name
1 parent 9636b82 commit b3a5cef

File tree

1 file changed

+70
-17
lines changed

1 file changed

+70
-17
lines changed

crates/pet-conda/src/environments.rs

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,8 @@ impl CondaEnvironment {
3232

3333
pub fn to_python_environment(&self, conda_manager: Option<EnvManager>) -> PythonEnvironment {
3434
#[allow(unused_assignments)]
35-
let mut name: Option<String> = None;
36-
if is_conda_install(&self.prefix) {
37-
name = Some("base".to_string());
38-
} else {
39-
name = self
40-
.prefix
41-
.file_name()
42-
.map(|name| name.to_str().unwrap_or_default().to_string());
43-
}
44-
// if the conda install folder is parent of the env folder, then we can use named activation.
45-
// E.g. conda env is = <conda install>/envs/<env name>
46-
// Then we can use `<conda install>/bin/conda activate -n <env name>`
47-
if let Some(conda_dir) = &self.conda_dir {
48-
if !self.prefix.starts_with(conda_dir) {
49-
name = None;
50-
}
51-
}
35+
let name = get_conda_env_name(&self.prefix, &self.prefix, &self.conda_dir);
36+
5237
// This is a root env.
5338
let builder = PythonEnvironmentBuilder::new(Some(PythonEnvironmentKind::Conda))
5439
.executable(self.executable.clone())
@@ -168,6 +153,64 @@ pub fn get_conda_installation_used_to_create_conda_env(env_path: &Path) -> Optio
168153
}
169154
}
170155

156+
fn get_conda_env_name(
157+
env_path: &Path,
158+
prefix: &Path,
159+
conda_dir: &Option<PathBuf>,
160+
) -> Option<String> {
161+
let mut name: Option<String> = None;
162+
if is_conda_install(&prefix) {
163+
name = Some("base".to_string());
164+
} else {
165+
name = prefix
166+
.file_name()
167+
.map(|name| name.to_str().unwrap_or_default().to_string());
168+
}
169+
// if the conda install folder is parent of the env folder, then we can use named activation.
170+
// E.g. conda env is = <conda install>/envs/<env name>
171+
// Then we can use `<conda install>/bin/conda activate -n <env name>`
172+
if let Some(conda_dir) = conda_dir {
173+
if !prefix.starts_with(conda_dir) {
174+
name = get_conda_env_name_from_history_file(env_path, prefix);
175+
}
176+
}
177+
178+
name
179+
}
180+
181+
/**
182+
* The conda-meta/history file in conda environments contain the command used to create the conda environment.
183+
* And example is `# cmd: <conda install directory>\Scripts\conda-script.py create -n sample``
184+
* And example is `# cmd: conda create -n sample``
185+
*
186+
* This function returns the name of the conda environment.
187+
*/
188+
fn get_conda_env_name_from_history_file(env_path: &Path, prefix: &Path) -> Option<String> {
189+
let name = prefix
190+
.file_name()
191+
.map(|name| name.to_str().unwrap_or_default().to_string());
192+
193+
if let Some(name) = name {
194+
// First look for the conda-meta/history file in the environment folder.
195+
// This could be a conda envirment (not root) but has `conda` installed in it.
196+
let conda_meta_history = env_path.join("conda-meta").join("history");
197+
if let Ok(reader) = std::fs::read_to_string(conda_meta_history.clone()) {
198+
if let Some(line) = reader.lines().map(|l| l.trim()).find(|l| {
199+
l.to_lowercase().starts_with("# cmd:") && l.to_lowercase().contains(" create -")
200+
}) {
201+
// Sample lines
202+
// # cmd: <conda install directory>\Scripts\conda-script.py create -n samlpe1
203+
// # cmd: <conda install directory>\Scripts\conda-script.py create -p <full path>
204+
// # cmd: /Users/donjayamanne/miniconda3/bin/conda create -n conda1
205+
if is_conda_env_name_in_cmd(line.into(), &name) {
206+
return Some(name);
207+
}
208+
}
209+
}
210+
}
211+
None
212+
}
213+
171214
fn get_conda_dir_from_cmd(cmd_line: String) -> Option<PathBuf> {
172215
// Sample lines
173216
// # cmd: <conda install directory>\Scripts\conda-script.py create -n samlpe1
@@ -229,6 +272,16 @@ fn get_conda_dir_from_cmd(cmd_line: String) -> Option<PathBuf> {
229272
None
230273
}
231274

275+
fn is_conda_env_name_in_cmd(cmd_line: String, name: &str) -> bool {
276+
// Sample lines
277+
// # cmd: <conda install directory>\Scripts\conda-script.py create -n samlpe1
278+
// # cmd: <conda install directory>\Scripts\conda-script.py create -p <full path>
279+
// # cmd: /Users/donjayamanne/miniconda3/bin/conda create -n conda1
280+
// # cmd_line: "# cmd: /usr/bin/conda create -p ./prefix-envs/.conda1 python=3.12 -y"
281+
// Look for "-n <name>" in the command line
282+
cmd_line.contains(format!("-n {:?}", name).as_str())
283+
}
284+
232285
pub fn get_activation_command(
233286
env: &CondaEnvironment,
234287
manager: &EnvManager,

0 commit comments

Comments
 (0)