Skip to content

Commit 206866d

Browse files
authored
Initial commit with skeletal code
2 parents 2368bc1 + 657687a commit 206866d

157 files changed

Lines changed: 104793 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[workspace]
2+
3+
members = ["crates/*"]
4+
resolver = "2"

crates/pet-conda/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "pet-conda"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
serde = { version = "1.0.152", features = ["derive"] }
8+
serde_json = "1.0.93"
9+
lazy_static = "1.4.0"
10+
pet-core = { path = "../pet-core" }
11+
pet-utils = { path = "../pet-utils" }
12+
log = "0.4.21"
13+
regex = "1.10.4"

crates/pet-conda/src/conda_rc.rs

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
use crate::utils::CondaEnvironmentVariables;
5+
use log::trace;
6+
use std::{fs, path::PathBuf};
7+
8+
#[derive(Debug)]
9+
pub struct Condarc {
10+
pub env_dirs: Vec<PathBuf>,
11+
}
12+
13+
impl Condarc {
14+
pub fn from(environment: &CondaEnvironmentVariables) -> Option<Condarc> {
15+
get_conda_conda_rc(environment)
16+
}
17+
}
18+
19+
#[cfg(windows)]
20+
fn get_conda_rc_search_paths(environment: &CondaEnvironmentVariables) -> Vec<PathBuf> {
21+
let mut search_paths: Vec<PathBuf> = vec![
22+
"C:\\ProgramData\\conda\\.condarc",
23+
"C:\\ProgramData\\conda\\condarc",
24+
"C:\\ProgramData\\conda\\condarc.d",
25+
]
26+
.iter()
27+
.map(|p| PathBuf::from(p))
28+
.collect();
29+
30+
if let Some(ref conda_root) = environment.conda_root {
31+
search_paths.append(&mut vec![
32+
PathBuf::from(conda_root.clone()).join(".condarc"),
33+
PathBuf::from(conda_root.clone()).join("condarc"),
34+
PathBuf::from(conda_root.clone()).join(".condarc.d"),
35+
]);
36+
}
37+
if let Some(ref home) = environment.home {
38+
search_paths.append(&mut vec![
39+
home.join(".config").join("conda").join(".condarc"),
40+
home.join(".config").join("conda").join("condarc"),
41+
home.join(".config").join("conda").join("condarc.d"),
42+
home.join(".conda").join(".condarc"),
43+
home.join(".conda").join("condarc"),
44+
home.join(".conda").join("condarc.d"),
45+
home.join(".condarc"),
46+
]);
47+
}
48+
if let Some(ref conda_prefix) = environment.conda_prefix {
49+
search_paths.append(&mut vec![
50+
PathBuf::from(conda_prefix.clone()).join(".condarc"),
51+
PathBuf::from(conda_prefix.clone()).join("condarc"),
52+
PathBuf::from(conda_prefix.clone()).join(".condarc.d"),
53+
]);
54+
}
55+
if let Some(ref condarc) = environment.condarc {
56+
search_paths.append(&mut vec![PathBuf::from(condarc)]);
57+
}
58+
59+
search_paths
60+
}
61+
62+
#[cfg(unix)]
63+
fn get_conda_rc_search_paths(environment: &CondaEnvironmentVariables) -> Vec<PathBuf> {
64+
let mut search_paths: Vec<PathBuf> = vec![
65+
"/etc/conda/.condarc",
66+
"/etc/conda/condarc",
67+
"/etc/conda/condarc.d",
68+
"/var/lib/conda/.condarc",
69+
"/var/lib/conda/condarc",
70+
"/var/lib/conda/condarc.d",
71+
]
72+
.iter()
73+
.map(|p| PathBuf::from(p))
74+
.map(|p| {
75+
// This only applies in tests.
76+
// We need this, as the root folder cannot be mocked.
77+
if let Some(ref root) = environment.root {
78+
// Strip the first `/` (this path is only for testing purposes)
79+
root.join(p.to_string_lossy()[1..].to_string())
80+
} else {
81+
p
82+
}
83+
})
84+
.collect();
85+
86+
if let Some(ref conda_root) = environment.conda_root {
87+
search_paths.append(&mut vec![
88+
PathBuf::from(conda_root.clone()).join(".condarc"),
89+
PathBuf::from(conda_root.clone()).join("condarc"),
90+
PathBuf::from(conda_root.clone()).join(".condarc.d"),
91+
]);
92+
}
93+
if let Some(ref xdg_config_home) = environment.xdg_config_home {
94+
search_paths.append(&mut vec![
95+
PathBuf::from(xdg_config_home.clone()).join(".condarc"),
96+
PathBuf::from(xdg_config_home.clone()).join("condarc"),
97+
PathBuf::from(xdg_config_home.clone()).join(".condarc.d"),
98+
]);
99+
}
100+
if let Some(ref home) = environment.home {
101+
search_paths.append(&mut vec![
102+
home.join(".config").join("conda").join(".condarc"),
103+
home.join(".config").join("conda").join("condarc"),
104+
home.join(".config").join("conda").join("condarc.d"),
105+
home.join(".conda").join(".condarc"),
106+
home.join(".conda").join("condarc"),
107+
home.join(".conda").join("condarc.d"),
108+
home.join(".condarc"),
109+
]);
110+
}
111+
if let Some(ref conda_prefix) = environment.conda_prefix {
112+
search_paths.append(&mut vec![
113+
PathBuf::from(conda_prefix.clone()).join(".condarc"),
114+
PathBuf::from(conda_prefix.clone()).join("condarc"),
115+
PathBuf::from(conda_prefix.clone()).join(".condarc.d"),
116+
]);
117+
}
118+
if let Some(ref condarc) = environment.condarc {
119+
search_paths.append(&mut vec![PathBuf::from(condarc)]);
120+
}
121+
122+
search_paths
123+
}
124+
125+
/**
126+
* The .condarc file contains a list of directories where conda environments are created.
127+
* https://conda.io/projects/conda/en/latest/configuration.html#envs-dirs
128+
*
129+
* TODO: Search for the .condarc file in the following locations:
130+
* https://conda.io/projects/conda/en/latest/user-guide/configuration/use-condarc.html#searching-for-condarc
131+
*/
132+
fn get_conda_conda_rc(environment: &CondaEnvironmentVariables) -> Option<Condarc> {
133+
let conda_rc = get_conda_rc_search_paths(environment)
134+
.into_iter()
135+
.find(|p: &PathBuf| p.exists())?;
136+
parse_conda_rc(&conda_rc)
137+
}
138+
139+
fn parse_conda_rc(conda_rc: &PathBuf) -> Option<Condarc> {
140+
let mut start_consuming_values = false;
141+
trace!("conda_rc: {:?}", conda_rc);
142+
let reader = fs::read_to_string(conda_rc).ok()?;
143+
let mut env_dirs = vec![];
144+
for line in reader.lines() {
145+
if line.starts_with("envs_dirs:") && !start_consuming_values {
146+
start_consuming_values = true;
147+
continue;
148+
}
149+
if start_consuming_values {
150+
if line.trim().starts_with("-") {
151+
if let Some(env_dir) = line.splitn(2, '-').nth(1) {
152+
// Directories in conda-rc are where `envs` are stored.
153+
env_dirs.push(PathBuf::from(env_dir.trim()).join("envs"));
154+
}
155+
continue;
156+
} else {
157+
break;
158+
}
159+
}
160+
}
161+
return Some(Condarc { env_dirs });
162+
}

0 commit comments

Comments
 (0)