diff --git a/crates/pet-conda/src/conda_rc.rs b/crates/pet-conda/src/conda_rc.rs index 66980424..b4c66ee6 100644 --- a/crates/pet-conda/src/conda_rc.rs +++ b/crates/pet-conda/src/conda_rc.rs @@ -3,7 +3,7 @@ use crate::env_variables::EnvVariables; use log::trace; -use pet_utils::path::fix_file_path_casing; +use pet_utils::path::normalize; use std::{fs, path::PathBuf}; #[derive(Debug)] @@ -155,9 +155,7 @@ fn parse_conda_rc(conda_rc: &PathBuf) -> Option { if line.trim().starts_with('-') { if let Some(env_dir) = line.split_once('-').map(|x| x.1) { // Directories in conda-rc are where `envs` are stored. - env_dirs.push(fix_file_path_casing( - &PathBuf::from(env_dir.trim()).join("envs"), - )); + env_dirs.push(normalize(&PathBuf::from(env_dir.trim()).join("envs"))); } continue; } else { diff --git a/crates/pet-conda/src/environment_locations.rs b/crates/pet-conda/src/environment_locations.rs index 6a871939..a19daa68 100644 --- a/crates/pet-conda/src/environment_locations.rs +++ b/crates/pet-conda/src/environment_locations.rs @@ -7,7 +7,7 @@ use crate::{ utils::{is_conda_env, is_conda_install}, }; use log::trace; -use pet_utils::path::fix_file_path_casing; +use pet_utils::path::normalize; use std::{ fs, path::{Path, PathBuf}, @@ -35,7 +35,7 @@ pub fn get_conda_environment_paths(env_vars: &EnvVariables) -> Vec { envs }); - env_paths = env_paths.iter().map(|p| fix_file_path_casing(p)).collect(); + env_paths = env_paths.iter().map(normalize).collect(); env_paths.sort(); env_paths.dedup(); // For each env, check if we have a conda install directory in them and @@ -147,7 +147,7 @@ pub fn get_conda_envs_from_environment_txt(env_vars: &EnvVariables) -> Vec Vec Vec { - use pet_utils::path::fix_file_path_casing; + use pet_utils::path::normalize; let user_profile = env_vars.userprofile.clone().unwrap_or_default(); let program_data = env_vars.programdata.clone().unwrap_or_default(); @@ -210,10 +210,7 @@ pub fn get_known_conda_install_locations(env_vars: &EnvVariables) -> Vec Option { // The casing in history might not be same as that on disc // We do not want to have duplicates in different cases. // & we'd like to preserve the case of the original path as on disc. - return Some(fix_file_path_casing(conda_dir).to_path_buf()); + return Some(normalize(conda_dir).to_path_buf()); } } // Sometimes we can have paths like @@ -212,7 +212,7 @@ fn get_conda_dir_from_cmd(cmd_line: String) -> Option { // The casing in history might not be same as that on disc // We do not want to have duplicates in different cases. // & we'd like to preserve the case of the original path as on disc. - return Some(fix_file_path_casing(&cmd_line).to_path_buf()); + return Some(normalize(&cmd_line).to_path_buf()); } } None diff --git a/crates/pet-conda/src/manager.rs b/crates/pet-conda/src/manager.rs index 01681cae..d99c0503 100644 --- a/crates/pet-conda/src/manager.rs +++ b/crates/pet-conda/src/manager.rs @@ -135,20 +135,3 @@ fn get_conda_manager(path: &Path) -> Option { None } } - -// pub fn get_conda_version(conda_binary: &PathBuf) -> Option { -// let mut parent = conda_binary.parent()?; -// if parent.ends_with("bin") { -// parent = parent.parent()?; -// } -// if parent.ends_with("Library") { -// parent = parent.parent()?; -// } -// match get_conda_package_info(&parent, "conda") { -// Some(result) => Some(result.version), -// None => match get_conda_package_info(&parent.parent()?, "conda") { -// Some(result) => Some(result.version), -// None => None, -// }, -// } -// } diff --git a/crates/pet-conda/src/mod.rs b/crates/pet-conda/src/mod.rs deleted file mode 100644 index 471cf45d..00000000 --- a/crates/pet-conda/src/mod.rs +++ /dev/null @@ -1,246 +0,0 @@ -// // Copyright (c) Microsoft Corporation. All rights reserved. -// // Licensed under the MIT License. - -// mod environment_locations; -// mod environments; -// mod lib; -// mod manager; -// mod utils; - -// use crate::known::Environment; -// use crate::locator::Locator; -// use crate::locator::LocatorResult; -// use crate::messaging::EnvManager; -// use crate::messaging::PythonEnvironment; -// use crate::messaging::PythonEnvironmentBuilder; -// use crate::messaging::PythonEnvironmentCategory; -// use crate::utils::PythonEnv; -// use environment_locations::get_conda_environment_paths; -// #[allow(unused_imports)] -// pub use environment_locations::get_conda_environment_paths_from_conda_rc; -// use environment_locations::get_environments_in_conda_dir; -// use environments::get_activation_command; -// use environments::get_conda_environment_info; -// use environments::get_conda_installation_used_to_create_conda_env; -// use environments::CondaEnvironment; -// use log::error; -// use manager::get_conda_manager; -// use manager::CondaManager; -// use std::collections::HashMap; -// use std::collections::HashSet; -// use std::path::{Path, PathBuf}; -// use std::sync::Mutex; -// #[allow(unused_imports)] -// pub use utils::get_conda_package_info; -// pub use utils::is_conda_env_location; -// pub use utils::is_conda_install_location; -// #[allow(unused_imports)] -// pub use utils::CondaPackage; - -// fn get_conda_manager_from_env(env_path: &Path) -> Option { -// // Lets see if we've been given the base env. -// if let Some(manager) = get_conda_manager(env_path) { -// return Some(manager); -// } - -// // Possible we've been given an env thats in the `/envs` folder. -// if let Some(parent) = env_path.parent() { -// if parent.file_name().unwrap_or_default() == "envs" { -// return get_conda_manager(parent.parent()?); -// } -// } - -// // We've been given an env thats been created using the -p flag. -// // Get the conda install folder from the history file. -// if let Some(conda_install_folder) = get_conda_installation_used_to_create_conda_env(env_path) { -// return get_conda_manager(&conda_install_folder); -// } -// None -// } - -// fn get_known_conda_envs_from_various_locations( -// environment: &dyn Environment, -// ) -> Vec { -// get_conda_environment_paths(environment) -// .iter() -// .map(|path| get_conda_environment_info(&path)) -// .filter(Option::is_some) -// .map(Option::unwrap) -// .into_iter() -// .collect::>() -// } - -// pub struct Conda<'a> { -// pub environments: Mutex>, -// pub managers: Mutex>, -// pub environment: &'a dyn Environment, -// } - -// pub trait CondaLocator { -// fn find_in(&mut self, possible_conda_folder: &Path) -> Option; -// } - -// impl Conda<'_> { -// pub fn with<'a>(environment: &'a impl Environment) -> Conda { -// Conda { -// environment, -// environments: Mutex::new(HashMap::new()), -// managers: Mutex::new(HashMap::new()), -// } -// } -// } - -// impl CondaLocator for Conda<'_> { -// fn find_in(&mut self, conda_dir: &Path) -> Option { -// if !is_conda_install_location(conda_dir) { -// return None; -// } -// if let Some(manager) = get_conda_manager(&conda_dir) { -// let mut managers = self.managers.lock().unwrap(); -// let mut environments = self.environments.lock().unwrap(); - -// // Keep track to search again later. -// // Possible we'll find environments in other directories created using this manager -// managers.insert(conda_dir.to_path_buf(), manager.clone()); - -// let mut new_environments = vec![]; - -// // Find all the environments in the conda install folder. (under `envs` folder) -// get_environments_in_conda_dir(conda_dir) -// .iter() -// .map(|path| get_conda_environment_info(path)) -// .filter(Option::is_some) -// .map(Option::unwrap) -// .for_each(|env| { -// let env = env.to_python_environment(manager.to_manager(), &manager.conda_dir); -// if let Some(path) = env.env_path.clone() { -// if environments.contains_key(&path) { -// return; -// } -// environments.insert(path, env.clone()); -// new_environments.push(env); -// } -// }); - -// return Some(LocatorResult { -// environments: new_environments, -// managers: vec![manager.to_manager()], -// }); -// } -// return None; -// } -// } - -// impl Locator for Conda<'_> { -// fn resolve(&self, env: &PythonEnv) -> Option { -// if let Some(ref path) = env.path { -// let mut managers = self.managers.lock().unwrap(); -// let mut environments = self.environments.lock().unwrap(); - -// // Do we already have an env for this. -// if let Some(env) = environments.get(path) { -// return Some(env.clone()); -// } -// if let Some(env) = get_conda_environment_info(path) { -// if let Some(conda_dir) = &env.conda_install_folder { -// // Use existing manager if we have one. -// if let Some(manager) = managers.get(conda_dir) { -// let env = env.to_python_environment(manager.to_manager(), &conda_dir); -// environments.insert(path.clone(), env.clone()); -// return Some(env); -// } - -// if let Some(manager) = get_conda_manager(conda_dir) { -// let env = env.to_python_environment(manager.to_manager(), &conda_dir); -// managers.insert(path.clone(), manager.clone()); -// environments.insert(path.clone(), env.clone()); -// return Some(env); -// } -// } else { -// error!( -// "Unable to find conda Install folder conda install folder env: {:?}", -// env -// ); -// } -// } -// } -// None -// } - -// fn find(&mut self) -> Option { -// let mut managers = self.managers.lock().unwrap(); -// let mut environments = self.environments.lock().unwrap(); - -// let mut discovered_environments: Vec = vec![]; -// // 1. Get a list of all know conda environments -// let known_conda_envs = get_known_conda_envs_from_various_locations(self.environment); - -// // 2. Go through all conda dirs and build the conda managers. -// for env in &known_conda_envs { -// if let Some(conda_dir) = &env.conda_install_folder { -// if managers.contains_key(conda_dir) { -// continue; -// } -// if let Some(manager) = get_conda_manager(&conda_dir) { -// managers.insert(conda_dir.clone(), manager); -// } -// } -// } - -// fn get_manager( -// known_env: &CondaEnvironment, -// discovered_managers: &mut HashMap, -// ) -> Option { -// if let Some(ref path) = known_env.conda_install_folder { -// return discovered_managers.get(path).cloned(); -// } -// // If we have a conda install folder, then use that to get the manager. -// if let Some(ref conda_dir) = known_env.conda_install_folder { -// if let Some(mgr) = discovered_managers.get(conda_dir) { -// return Some(mgr.clone()); -// } -// if let Some(manager) = get_conda_manager(&conda_dir) { -// discovered_managers.insert(conda_dir.clone(), manager.clone()); -// return Some(manager); -// } - -// // We could not find the manager, this is an error. -// error!( -// "Manager not found for conda env: {:?}, known managers include {:?}", -// known_env, -// discovered_managers.values() -// ); -// } -// // If we do not have the conda install folder, then use the env path to get the manager. -// if let Some(mgr) = discovered_managers.values().next() { -// return Some(mgr.clone()); -// } else { -// error!("No conda manager, hence unable to report any environment"); -// return None; -// } -// } - -// // 5. Go through each environment we know of and build the python environments. -// for known_env in &known_conda_envs { -// // We should not hit this condition, see above. -// if let Some(manager) = get_manager(known_env, &mut managers) { -// let env = known_env.to_python_environment(manager.to_manager(), &manager.conda_dir); -// environments.insert(known_env.env_path.clone(), env.clone()); -// discovered_environments.push(env); -// } -// } - -// if managers.is_empty() && discovered_environments.is_empty() { -// return None; -// } - -// Some(LocatorResult { -// managers: managers -// .values() -// .into_iter() -// .map(|m| m.to_manager()) -// .collect::>(), -// environments: discovered_environments, -// }) -// } -// } diff --git a/crates/pet-conda/tests/conda_rc_test.rs b/crates/pet-conda/tests/conda_rc_test.rs index 5b9d6a11..1590f8c5 100644 --- a/crates/pet-conda/tests/conda_rc_test.rs +++ b/crates/pet-conda/tests/conda_rc_test.rs @@ -2,14 +2,13 @@ // Licensed under the MIT License. mod common; -use common::resolve_test_path; -use pet_conda::conda_rc::Condarc; -use std::path::PathBuf; #[cfg(unix)] #[test] fn no_conda_rc() { use common::create_env_variables; + use common::resolve_test_path; + use pet_conda::conda_rc::Condarc; let root = resolve_test_path(&["unix", "root_empty"]); let home = resolve_test_path(&["unix", "user_home_with_environments_txt"]); @@ -24,6 +23,9 @@ fn no_conda_rc() { #[test] fn finds_conda_rc() { use common::create_env_variables; + use common::resolve_test_path; + use pet_conda::conda_rc::Condarc; + use std::path::PathBuf; let root = resolve_test_path(&["unix", "conda_rc", "root"]); let home = resolve_test_path(&["unix", "conda_rc", "user_home"]); @@ -44,6 +46,9 @@ fn finds_conda_rc() { #[test] fn finds_conda_rc_from_conda_root_env_variable() { use common::create_env_variables; + use common::resolve_test_path; + use pet_conda::conda_rc::Condarc; + use std::path::PathBuf; let root = resolve_test_path(&["unix", "conda_rc_conda_root_var", "root"]); let home = resolve_test_path(&["unix", "conda_rc_conda_root_var", "user_home"]); @@ -75,6 +80,9 @@ fn finds_conda_rc_from_conda_root_env_variable() { #[test] fn finds_conda_rc_from_root() { use common::create_env_variables; + use common::resolve_test_path; + use pet_conda::conda_rc::Condarc; + use std::path::PathBuf; let root = resolve_test_path(&["unix", "conda_rc_root", "root"]); let home = resolve_test_path(&["unix", "conda_rc_root", "user_home"]); diff --git a/crates/pet-conda/tests/environment_locations_test.rs b/crates/pet-conda/tests/environment_locations_test.rs index bf3c738d..9767af51 100644 --- a/crates/pet-conda/tests/environment_locations_test.rs +++ b/crates/pet-conda/tests/environment_locations_test.rs @@ -2,15 +2,14 @@ // Licensed under the MIT License. mod common; -use common::{create_env_variables, resolve_test_path}; -use pet_conda::environment_locations::{ - get_conda_envs_from_environment_txt, get_environments, get_known_conda_locations, -}; -use std::path::PathBuf; #[cfg(unix)] #[test] fn read_environment_txt() { + use common::{create_env_variables, resolve_test_path}; + use pet_conda::environment_locations::get_conda_envs_from_environment_txt; + use std::path::PathBuf; + let root = resolve_test_path(&["unix", "root_empty"]).into(); let home = resolve_test_path(&["unix", "user_home_with_environments_txt"]).into(); let env = create_env_variables(home, root); @@ -53,6 +52,9 @@ fn read_environment_txt() { #[cfg(unix)] #[test] fn non_existent_envrionments_txt() { + use common::{create_env_variables, resolve_test_path}; + use pet_conda::environment_locations::get_conda_envs_from_environment_txt; + let root = resolve_test_path(&["unix", "root_empty"]).into(); let home = resolve_test_path(&["unix", "bogus directory"]).into(); let env = create_env_variables(home, root); @@ -65,6 +67,10 @@ fn non_existent_envrionments_txt() { #[cfg(unix)] #[test] fn known_install_locations() { + use common::{create_env_variables, resolve_test_path}; + use pet_conda::environment_locations::get_known_conda_locations; + use std::path::PathBuf; + let root = resolve_test_path(&["unix", "root_empty"]).into(); let home = resolve_test_path(&["unix", "user_home"]).into(); let env = create_env_variables(home, root); @@ -102,6 +108,9 @@ fn known_install_locations() { #[cfg(unix)] #[test] fn list_conda_envs_in_install_location() { + use common::resolve_test_path; + use pet_conda::environment_locations::get_environments; + let path = resolve_test_path(&["unix", "anaconda3-2023.03"]); let mut locations = get_environments(&path); diff --git a/crates/pet-conda/tests/manager_test.rs b/crates/pet-conda/tests/manager_test.rs index f36f1089..1face145 100644 --- a/crates/pet-conda/tests/manager_test.rs +++ b/crates/pet-conda/tests/manager_test.rs @@ -2,12 +2,13 @@ // Licensed under the MIT License. mod common; -use common::resolve_test_path; -use pet_conda::manager::CondaManager; #[cfg(unix)] #[test] fn finds_manager_from_root_env() { + use common::resolve_test_path; + use pet_conda::manager::CondaManager; + let path = resolve_test_path(&["unix", "anaconda3-2023.03"]); let manager = CondaManager::from(&path).unwrap(); @@ -19,6 +20,9 @@ fn finds_manager_from_root_env() { #[cfg(unix)] #[test] fn finds_manager_from_root_within_an_env() { + use common::resolve_test_path; + use pet_conda::manager::CondaManager; + let conda_dir = resolve_test_path(&["unix", "anaconda3-2023.03"]); let path = resolve_test_path(&["unix", "anaconda3-2023.03", "envs", "env_python_3"]); @@ -39,6 +43,9 @@ fn finds_manager_from_root_within_an_env() { #[cfg(unix)] #[test] fn does_not_find_conda_env_for_bogus_dirs() { + use common::resolve_test_path; + use pet_conda::manager::CondaManager; + let path = resolve_test_path(&["unix", "bogus_directory"]); assert_eq!(CondaManager::from(&path).is_none(), true); diff --git a/crates/pet-core/src/os_environment.rs b/crates/pet-core/src/os_environment.rs index ed5a36ea..64b520b4 100644 --- a/crates/pet-core/src/os_environment.rs +++ b/crates/pet-core/src/os_environment.rs @@ -3,6 +3,8 @@ use std::{env, path::PathBuf}; +use pet_utils::path::normalize; + pub trait Environment { fn get_user_home(&self) -> Option; /** @@ -105,7 +107,7 @@ impl Environment for EnvironmentApi { fn get_user_home() -> Option { let home = env::var("HOME").or_else(|_| env::var("USERPROFILE")); match home { - Ok(home) => Some(PathBuf::from(home)), + Ok(home) => Some(normalize(PathBuf::from(home))), Err(_) => None, } } diff --git a/crates/pet-core/src/python_environment.rs b/crates/pet-core/src/python_environment.rs index d6d5610e..b19f5005 100644 --- a/crates/pet-core/src/python_environment.rs +++ b/crates/pet-core/src/python_environment.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; +use pet_utils::path::normalize; use serde::{Deserialize, Serialize}; use crate::{arch::Architecture, manager::EnvManager}; @@ -166,7 +167,14 @@ impl PythonEnvironmentBuilder { } pub fn executable(mut self, executable: Option) -> Self { - self.executable = executable; + self.executable.clone_from(&executable); + if let Some(exe) = executable { + if let Some(parent) = exe.parent() { + if let Some(file_name) = exe.file_name() { + self.executable = Some(normalize(parent).join(file_name)) + } + } + } self } @@ -176,7 +184,10 @@ impl PythonEnvironmentBuilder { } pub fn prefix(mut self, prefix: Option) -> Self { - self.prefix = prefix; + self.prefix.clone_from(&prefix); + if let Some(resolved) = prefix { + self.prefix = Some(normalize(resolved)) + } self } @@ -186,7 +197,10 @@ impl PythonEnvironmentBuilder { } pub fn project(mut self, project: Option) -> Self { - self.project = project; + self.project.clone_from(&project); + if let Some(resolved) = project { + self.project = Some(normalize(resolved)) + } self } diff --git a/crates/pet-global-virtualenvs/src/lib.rs b/crates/pet-global-virtualenvs/src/lib.rs index b02d796e..3af5d252 100644 --- a/crates/pet-global-virtualenvs/src/lib.rs +++ b/crates/pet-global-virtualenvs/src/lib.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use pet_conda::utils::is_conda_env; -use pet_utils::path::fix_file_path_casing; +use pet_utils::path::normalize; use std::{fs, path::PathBuf}; fn get_global_virtualenv_dirs( @@ -12,7 +12,7 @@ fn get_global_virtualenv_dirs( let mut venv_dirs: Vec = vec![]; if let Some(work_on_home) = work_on_home_env_var { - let work_on_home = fix_file_path_casing(&PathBuf::from(work_on_home)); + let work_on_home = normalize(PathBuf::from(work_on_home)); if fs::metadata(&work_on_home).is_ok() { venv_dirs.push(work_on_home); } diff --git a/crates/pet-pipenv/src/lib.rs b/crates/pet-pipenv/src/lib.rs index b1d0f409..19769567 100644 --- a/crates/pet-pipenv/src/lib.rs +++ b/crates/pet-pipenv/src/lib.rs @@ -7,12 +7,12 @@ use pet_core::{ python_environment::{PythonEnvironment, PythonEnvironmentBuilder, PythonEnvironmentCategory}, Locator, LocatorResult, }; -use pet_utils::{env::PythonEnv, path::fix_file_path_casing}; +use pet_utils::{env::PythonEnv, path::normalize}; fn get_pipenv_project(env: &PythonEnv) -> Option { let project_file = env.prefix.clone()?.join(".project"); let contents = fs::read_to_string(project_file).ok()?; - let project_folder = fix_file_path_casing(&PathBuf::from(contents.trim().to_string())); + let project_folder = normalize(PathBuf::from(contents.trim().to_string())); if fs::metadata(&project_folder).is_ok() { Some(project_folder) } else { diff --git a/crates/pet-pyenv/src/environment_locations.rs b/crates/pet-pyenv/src/environment_locations.rs index 3de41a0c..07f049c4 100644 --- a/crates/pet-pyenv/src/environment_locations.rs +++ b/crates/pet-pyenv/src/environment_locations.rs @@ -1,19 +1,21 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use pet_utils::path::normalize; + use crate::env_variables::EnvVariables; use std::{fs, path::PathBuf}; #[cfg(windows)] pub fn get_home_pyenv_dir(env_vars: &EnvVariables) -> Option { let home = env_vars.home.clone()?; - Some(home.join(".pyenv").join("pyenv-win")) + Some(normalize(home.join(".pyenv").join("pyenv-win"))) } #[cfg(unix)] pub fn get_home_pyenv_dir(env_vars: &EnvVariables) -> Option { let home = env_vars.home.clone()?; - Some(home.join(".pyenv")) + Some(normalize(home.join(".pyenv"))) } pub fn get_binary_from_known_paths(env_vars: &EnvVariables) -> Option { @@ -25,7 +27,7 @@ pub fn get_binary_from_known_paths(env_vars: &EnvVariables) -> Option { }; if let Ok(metadata) = fs::metadata(&exe) { if metadata.is_file() { - return Some(exe); + return Some(normalize(exe)); } } } diff --git a/crates/pet-utils/src/env.rs b/crates/pet-utils/src/env.rs index 56ec2f78..8bfa6ba6 100644 --- a/crates/pet-utils/src/env.rs +++ b/crates/pet-utils/src/env.rs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use crate::path::normalize; use std::path::PathBuf; #[derive(Debug)] @@ -12,8 +13,12 @@ pub struct PythonEnv { impl PythonEnv { pub fn new(executable: PathBuf, prefix: Option, version: Option) -> Self { + let mut prefix = prefix.clone(); + if let Some(value) = prefix { + prefix = normalize(value).into(); + } Self { - executable, + executable: normalize(executable), prefix, version, } diff --git a/crates/pet-utils/src/path.rs b/crates/pet-utils/src/path.rs index 5485929c..27c18ce3 100644 --- a/crates/pet-utils/src/path.rs +++ b/crates/pet-utils/src/path.rs @@ -6,17 +6,14 @@ use std::{ path::{Path, PathBuf}, }; -// This function is used to fix the casing of the file path. -// by returning the actual path with the correct casing as found on the OS. -// This is a noop for Unix systems. -// I.e. this function is only useful on Windows. -pub fn fix_file_path_casing(path: &Path) -> PathBuf { - // Return the path as is. - if cfg!(unix) { - return path.to_path_buf(); - } - let has_unc_prefix = path.to_string_lossy().starts_with(r"\\?\"); - if let Ok(resolved) = fs::canonicalize(path) { +// Similar to fs::canonicalize, but ignores UNC paths and returns the path as is (for windows). +pub fn normalize>(path: P) -> PathBuf { + if let Ok(resolved) = fs::canonicalize(&path) { + if cfg!(unix) { + return resolved; + } + // Windows specific handling, https://github.com/rust-lang/rust/issues/42869 + let has_unc_prefix = path.as_ref().to_string_lossy().starts_with(r"\\?\"); if resolved.to_string_lossy().starts_with(r"\\?\") && !has_unc_prefix { // If the resolved path has a UNC prefix, but the original path did not, // we need to remove the UNC prefix. @@ -25,6 +22,6 @@ pub fn fix_file_path_casing(path: &Path) -> PathBuf { resolved } } else { - path.to_path_buf() + path.as_ref().to_path_buf() } } diff --git a/crates/pet-virtualenvwrapper/src/environment_locations.rs b/crates/pet-virtualenvwrapper/src/environment_locations.rs index 494e845e..e75375fb 100644 --- a/crates/pet-virtualenvwrapper/src/environment_locations.rs +++ b/crates/pet-virtualenvwrapper/src/environment_locations.rs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use pet_utils::path::normalize; + use crate::env_variables::EnvVariables; use std::{fs, path::PathBuf}; @@ -13,11 +15,11 @@ fn get_default_virtualenvwrapper_path(env_vars: &EnvVariables) -> Option Option Option { if let Some(work_on_home) = &environment.workon_home { if let Ok(work_on_home) = std::fs::canonicalize(work_on_home) { if fs::metadata(&work_on_home).is_ok() { - return Some(work_on_home); + return Some(normalize(&work_on_home)); } } } diff --git a/crates/pet-virtualenvwrapper/src/environments.rs b/crates/pet-virtualenvwrapper/src/environments.rs index 72645e70..f4619bb2 100644 --- a/crates/pet-virtualenvwrapper/src/environments.rs +++ b/crates/pet-virtualenvwrapper/src/environments.rs @@ -3,7 +3,7 @@ use crate::{env_variables::EnvVariables, environment_locations::get_work_on_home_path}; use pet_utils::{ - env::PythonEnv, executable::find_executable, path::fix_file_path_casing, pyvenv_cfg::PyVenvCfg, + env::PythonEnv, executable::find_executable, path::normalize, pyvenv_cfg::PyVenvCfg, }; use pet_virtualenv::is_virtualenv; use std::{fs, path::PathBuf}; @@ -28,9 +28,9 @@ pub fn is_virtualenvwrapper(env: &PythonEnv, environment: &EnvVariables) -> bool pub fn get_project(env: &PythonEnv) -> Option { let project_file = env.prefix.clone()?.join(".project"); let contents = fs::read_to_string(project_file).ok()?; - let project_folder = fix_file_path_casing(&PathBuf::from(contents.trim().to_string())); + let project_folder = normalize(PathBuf::from(contents.trim().to_string())); if fs::metadata(&project_folder).is_ok() { - Some(project_folder) + Some(normalize(&project_folder)) } else { None } diff --git a/crates/pet-windows-registry/src/environments.rs b/crates/pet-windows-registry/src/environments.rs index 3f39a134..a8bec1e7 100644 --- a/crates/pet-windows-registry/src/environments.rs +++ b/crates/pet-windows-registry/src/environments.rs @@ -11,7 +11,7 @@ use pet_core::{ LocatorResult, }; #[cfg(windows)] -use pet_utils::path::fix_file_path_casing; +use pet_utils::path::normalize; #[cfg(windows)] use pet_windows_store::is_windows_app_folder_in_program_files; #[cfg(windows)] @@ -96,7 +96,7 @@ fn get_registry_pythons_from_key_for_company( Ok(install_path_key) => { let env_path: String = install_path_key.get_value("").ok().unwrap_or_default(); - let env_path = fix_file_path_casing(&PathBuf::from(env_path)); + let env_path = normalize(&PathBuf::from(env_path)); if is_windows_app_folder_in_program_files(&env_path) { trace!( "Found Python ({}) in {}\\Software\\Python\\{}\\{}, but skipping as this is a Windows Store Python", @@ -154,7 +154,7 @@ fn get_registry_pythons_from_key_for_company( ); continue; } - let executable = fix_file_path_casing(&PathBuf::from(executable)); + let executable = normalize(&PathBuf::from(executable)); if !executable.exists() { warn!( "Python executable ({}) file not found for {}\\Software\\Python\\{}\\{}", diff --git a/crates/pet-windows-store/src/environments.rs b/crates/pet-windows-store/src/environments.rs index 492d513d..dd0858a2 100644 --- a/crates/pet-windows-store/src/environments.rs +++ b/crates/pet-windows-store/src/environments.rs @@ -12,7 +12,7 @@ use pet_core::python_environment::PythonEnvironment; #[cfg(windows)] use pet_core::{arch::Architecture, python_environment::PythonEnvironmentBuilder}; #[cfg(windows)] -use pet_utils::path::fix_file_path_casing; +use pet_utils::path::normalize; #[cfg(windows)] use regex::Regex; use std::path::PathBuf; @@ -49,7 +49,7 @@ impl PotentialPython { let exe = self.exe.clone().unwrap_or_default(); let parent = path.parent()?.to_path_buf(); // This dir definitely exists. if let Some(result) = get_package_display_name_and_location(&name, hkcu) { - let env_path = fix_file_path_casing(&PathBuf::from(result.env_path)); + let env_path = normalize(&PathBuf::from(result.env_path)); Some( PythonEnvironmentBuilder::new(