Skip to content

Commit 268c2eb

Browse files
committed
Fix extraction of Python version for Conda environments (#23415)
Also added a test file to ensure we test this correctly.
1 parent 094041f commit 268c2eb

File tree

2 files changed

+22
-23
lines changed

2 files changed

+22
-23
lines changed

native_locator/src/conda.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,30 +73,27 @@ pub fn is_conda_environment(any_path: &Path) -> bool {
7373
}
7474
}
7575

76-
/// Get the version of a package in a conda environment. This will find the version
77-
/// from the 'conda-meta' directory in a platform agnostic way.
78-
fn get_version_from_meta_json(json_file: &Path) -> Option<String> {
79-
let file_name = json_file.file_name()?.to_string_lossy();
80-
81-
match Regex::new(r"(?m)([\d\w\-]*)-([\d\.]*)-.*\.json")
82-
.ok()?
83-
.captures(&file_name)?
84-
.get(2)
85-
{
86-
Some(version) => Some(version.as_str().to_string()),
87-
None => None,
88-
}
76+
struct CondaPackage {
77+
path: PathBuf,
78+
version: String,
8979
}
9080

91-
/// Get the path to the json file of a package in the conda environment from the 'conda-meta' directory.
92-
fn get_conda_package_json_path(any_path: &Path, package: &str) -> Option<PathBuf> {
81+
/// Get the path to the json file along with the version of a package in the conda environment from the 'conda-meta' directory.
82+
fn get_conda_package_json_path(any_path: &Path, package: &str) -> Option<CondaPackage> {
9383
let package_name = format!("{}-", package);
9484
let conda_meta_path = get_conda_meta_path(any_path)?;
85+
let regex = Regex::new(format!("^{}-((\\d+\\.*)*)-.*.json$", package).as_str());
9586
std::fs::read_dir(conda_meta_path).ok()?.find_map(|entry| {
9687
let path = entry.ok()?.path();
9788
let file_name = path.file_name()?.to_string_lossy();
9889
if file_name.starts_with(&package_name) && file_name.ends_with(".json") {
99-
Some(path)
90+
match regex.clone().ok()?.captures(&file_name)?.get(1) {
91+
Some(version) => Some(CondaPackage {
92+
path: path.clone(),
93+
version: version.as_str().to_string(),
94+
}),
95+
None => None,
96+
}
10097
} else {
10198
None
10299
}
@@ -108,7 +105,7 @@ fn get_conda_package_json_path(any_path: &Path, package: &str) -> Option<PathBuf
108105
pub fn is_python_conda_env(any_path: &Path) -> bool {
109106
let conda_python_json_path = get_conda_package_json_path(any_path, "python");
110107
match conda_python_json_path {
111-
Some(path) => path.exists(),
108+
Some(result) => result.path.exists(),
112109
None => false,
113110
}
114111
}
@@ -117,7 +114,7 @@ pub fn is_python_conda_env(any_path: &Path) -> bool {
117114
pub fn get_conda_python_version(any_path: &Path) -> Option<String> {
118115
let conda_python_json_path = get_conda_package_json_path(any_path, "python");
119116
match conda_python_json_path {
120-
Some(path) => get_version_from_meta_json(&path),
117+
Some(result) => Some(result.version.clone()),
121118
None => None,
122119
}
123120
}
@@ -231,11 +228,13 @@ pub fn get_conda_version(conda_binary: &PathBuf) -> Option<String> {
231228
if parent.ends_with("Library") {
232229
parent = parent.parent()?;
233230
}
234-
let conda_python_json_path = match get_conda_package_json_path(&parent, "conda") {
235-
Some(exe) => Some(exe),
236-
None => get_conda_package_json_path(&parent.parent()?, "conda"),
237-
}?;
238-
get_version_from_meta_json(&conda_python_json_path)
231+
match get_conda_package_json_path(&parent, "conda") {
232+
Some(result) => Some(result.version),
233+
None => match get_conda_package_json_path(&parent.parent()?, "conda") {
234+
Some(result) => Some(result.version),
235+
None => None,
236+
},
237+
}
239238
}
240239

241240
fn get_conda_envs_from_environment_txt(environment: &dyn known::Environment) -> Vec<String> {

native_locator/tests/unix/conda/envs/one/conda-meta/python-slugify-5.0.2-pyhd3eb1b0_0.json

Whitespace-only changes.

0 commit comments

Comments
 (0)