Skip to content

Commit 23df546

Browse files
committed
Fix env duplication on merged-usr systems
On modern (merged-usr) Linux systems, `/bin`, `/sbin` and `/usr/sbin` are symlinks to `/usr/bin`. There is no point in reporting the same Python installation four times, so canonicalize search paths before searching. Before: Breakdown for finding Environments: ----------------------------------- GlobalVirtualEnvs : 17.412201ms Locators : 225.284494ms Path : 433.162905ms Workspaces : 2.161556ms Environments (41): ------------------ GlobalPaths : 14 LinuxGlobal : 16 VirtualEnvWrapper : 11 After: Breakdown for finding Environments: ----------------------------------- GlobalVirtualEnvs : 16.595382ms Locators : 223.759511ms Path : 313.276036ms Workspaces : 1.418024ms Environments (21): ------------------ GlobalPaths : 2 LinuxGlobal : 8 VirtualEnvWrapper : 11
1 parent f586845 commit 23df546

File tree

2 files changed

+18
-7
lines changed
  • crates

2 files changed

+18
-7
lines changed

crates/pet-env-var-path/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Licensed under the MIT License.
33

44
use pet_core::os_environment::Environment;
5+
use std::collections::HashSet;
6+
use std::fs;
57
use std::path::PathBuf;
68

79
pub fn get_search_paths_from_env_variables(environment: &dyn Environment) -> Vec<PathBuf> {
@@ -16,10 +18,12 @@ pub fn get_search_paths_from_env_variables(environment: &dyn Environment) -> Vec
1618

1719
environment
1820
.get_know_global_search_locations()
19-
.clone()
21+
.into_iter()
22+
.map(|p| fs::canonicalize(&p).unwrap_or(p))
23+
.collect::<HashSet<PathBuf>>()
2024
.into_iter()
2125
.filter(|p| !p.starts_with(apps_path.clone()))
22-
.collect::<Vec<PathBuf>>()
26+
.collect()
2327
} else {
2428
Vec::new()
2529
}

crates/pet-linux-global-python/src/lib.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
use std::{
5-
collections::HashMap,
5+
collections::{HashMap, HashSet},
66
fs,
77
path::{Path, PathBuf},
88
sync::{Arc, Mutex},
@@ -38,10 +38,17 @@ impl LinuxGlobalPython {
3838
return;
3939
}
4040
// Look through the /bin, /usr/bin, /usr/local/bin directories
41+
let bin_dirs: HashSet<_> = [
42+
Path::new("/bin"),
43+
Path::new("/usr/bin"),
44+
Path::new("/usr/local/bin"),
45+
]
46+
.map(|p| fs::canonicalize(p).unwrap_or(p.to_path_buf()))
47+
.into();
4148
thread::scope(|s| {
42-
for bin in ["/bin", "/usr/bin", "/usr/local/bin"] {
49+
for bin in bin_dirs {
4350
s.spawn(move || {
44-
find_and_report_global_pythons_in(bin, reporter, &self.reported_executables);
51+
find_and_report_global_pythons_in(&bin, reporter, &self.reported_executables);
4552
});
4653
}
4754
});
@@ -103,11 +110,11 @@ impl Locator for LinuxGlobalPython {
103110
}
104111

105112
fn find_and_report_global_pythons_in(
106-
bin: &str,
113+
bin: &Path,
107114
reporter: Option<&dyn Reporter>,
108115
reported_executables: &Arc<Mutex<HashMap<PathBuf, PythonEnvironment>>>,
109116
) {
110-
let python_executables = find_executables(Path::new(bin));
117+
let python_executables = find_executables(bin);
111118

112119
for exe in python_executables.clone().iter() {
113120
if reported_executables.lock().unwrap().contains_key(exe) {

0 commit comments

Comments
 (0)