Skip to content

Commit 36f08e4

Browse files
authored
Always clear cache before searching (#110)
1 parent 9493095 commit 36f08e4

File tree

18 files changed

+187
-310
lines changed

18 files changed

+187
-310
lines changed

crates/pet-conda/src/environment_locations.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,13 @@ use std::{
1717

1818
const APP_NAME: &str = "conda";
1919

20-
pub fn get_conda_environment_paths(
21-
env_vars: &EnvVariables,
22-
additional_env_dirs: &Vec<PathBuf>,
23-
) -> Vec<PathBuf> {
20+
pub fn get_conda_environment_paths(env_vars: &EnvVariables) -> Vec<PathBuf> {
2421
let mut env_paths = thread::scope(|s| {
2522
let mut envs = vec![];
2623
for thread in [
2724
s.spawn(|| get_conda_envs_from_environment_txt(env_vars)),
2825
s.spawn(|| get_conda_environment_paths_from_conda_rc(env_vars)),
2926
s.spawn(|| get_conda_environment_paths_from_known_paths(env_vars)),
30-
s.spawn(|| get_conda_environment_paths_from_additional_paths(additional_env_dirs)),
3127
s.spawn(|| get_known_conda_install_locations(env_vars)),
3228
] {
3329
if let Ok(mut env_paths) = thread.join() {
@@ -121,25 +117,6 @@ fn get_conda_environment_paths_from_known_paths(env_vars: &EnvVariables) -> Vec<
121117
env_paths
122118
}
123119

124-
fn get_conda_environment_paths_from_additional_paths(
125-
additional_env_dirs: &Vec<PathBuf>,
126-
) -> Vec<PathBuf> {
127-
let mut env_paths: Vec<PathBuf> = vec![];
128-
for path in additional_env_dirs {
129-
if let Ok(entries) = fs::read_dir(path) {
130-
for entry in entries.filter_map(Result::ok) {
131-
let path = entry.path();
132-
if path.is_dir() {
133-
env_paths.push(path);
134-
}
135-
}
136-
}
137-
}
138-
env_paths.append(&mut additional_env_dirs.clone());
139-
trace!("Conda environments in additional paths {:?}", env_paths);
140-
env_paths
141-
}
142-
143120
pub fn get_environments(conda_dir: &Path) -> Vec<PathBuf> {
144121
let mut envs: Vec<PathBuf> = vec![];
145122

crates/pet-conda/src/lib.rs

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use pet_core::{
1111
os_environment::Environment,
1212
python_environment::{PythonEnvironment, PythonEnvironmentKind},
1313
reporter::Reporter,
14-
Locator, LocatorResult,
14+
Locator,
1515
};
1616
use pet_python_utils::env::PythonEnv;
1717
use serde::{Deserialize, Serialize};
@@ -35,7 +35,7 @@ mod telemetry;
3535
pub mod utils;
3636

3737
pub trait CondaLocator: Send + Sync {
38-
fn find_in(&self, path: &Path) -> Option<LocatorResult>;
38+
fn find_and_report(&self, reporter: &dyn Reporter, path: &Path);
3939
fn find_and_report_missing_envs(
4040
&self,
4141
reporter: &dyn Reporter,
@@ -53,8 +53,6 @@ pub struct CondaTelemetryInfo {
5353
}
5454

5555
pub struct Conda {
56-
/// Directories where conda environments are found (env_dirs returned from `conda info --json`)
57-
pub env_dirs: Arc<Mutex<Vec<PathBuf>>>,
5856
pub environments: Arc<Mutex<HashMap<PathBuf, PythonEnvironment>>>,
5957
pub managers: Arc<Mutex<HashMap<PathBuf, CondaManager>>>,
6058
pub env_vars: EnvVariables,
@@ -63,12 +61,15 @@ pub struct Conda {
6361
impl Conda {
6462
pub fn from(env: &dyn Environment) -> Conda {
6563
Conda {
66-
env_dirs: Arc::new(Mutex::new(vec![])),
6764
environments: Arc::new(Mutex::new(HashMap::new())),
6865
managers: Arc::new(Mutex::new(HashMap::new())),
6966
env_vars: EnvVariables::from(env),
7067
}
7168
}
69+
fn clear(&self) {
70+
self.environments.lock().unwrap().clear();
71+
self.managers.lock().unwrap().clear();
72+
}
7273
}
7374

7475
impl CondaLocator for Conda {
@@ -80,19 +81,6 @@ impl CondaLocator for Conda {
8081
// Look for environments that we couldn't find without spawning conda.
8182
let user_provided_conda_exe = conda_executable.is_some();
8283
let conda_info = CondaInfo::from(conda_executable)?;
83-
84-
// Keep track of these directories for next refresh
85-
// This way we can search these directories again and they will be reported.
86-
{
87-
let mut env_dirs = self.env_dirs.lock().unwrap();
88-
env_dirs.append(&mut conda_info.envs_dirs.clone());
89-
conda_info.envs_dirs.iter().for_each(|p| {
90-
if !env_dirs.contains(p) {
91-
env_dirs.push(p.clone());
92-
}
93-
});
94-
}
95-
9684
let environments = self.environments.lock().unwrap().clone();
9785
let new_envs = conda_info
9886
.envs
@@ -133,9 +121,9 @@ impl CondaLocator for Conda {
133121
}
134122
}
135123

136-
fn find_in(&self, conda_dir: &Path) -> Option<LocatorResult> {
124+
fn find_and_report(&self, reporter: &dyn Reporter, conda_dir: &Path) {
137125
if !is_conda_install(conda_dir) {
138-
return None;
126+
return;
139127
}
140128
if let Some(manager) = CondaManager::from(conda_dir) {
141129
if let Some(conda_dir) = manager.conda_dir.clone() {
@@ -147,29 +135,23 @@ impl CondaLocator for Conda {
147135
managers.insert(conda_dir.clone(), manager.clone());
148136
drop(managers);
149137

150-
let mut new_environments = vec![];
151-
152138
// Find all the environments in the conda install folder. (under `envs` folder)
153139
for conda_env in
154140
get_conda_environments(&get_environments(&conda_dir), &manager.clone().into())
155141
{
142+
// If reported earlier, no point processing this again.
156143
let mut environments = self.environments.lock().unwrap();
157144
if environments.contains_key(&conda_env.prefix) {
158145
continue;
159146
}
160147
let env = conda_env
161148
.to_python_environment(Some(conda_dir.clone()), Some(manager.to_manager()));
162149
environments.insert(conda_env.prefix.clone(), env.clone());
163-
new_environments.push(env);
150+
reporter.report_manager(&manager.to_manager());
151+
reporter.report_environment(&env);
164152
}
165-
166-
return Some(LocatorResult {
167-
environments: new_environments,
168-
managers: vec![manager.to_manager()],
169-
});
170153
}
171154
}
172-
None
173155
}
174156
}
175157

@@ -192,7 +174,7 @@ impl Conda {
192174

193175
impl Locator for Conda {
194176
fn get_name(&self) -> &'static str {
195-
"Conda"
177+
"Conda" // Do not change this name, as this is used in telemetry.
196178
}
197179
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
198180
vec![PythonEnvironmentKind::Conda]
@@ -261,15 +243,12 @@ impl Locator for Conda {
261243

262244
fn find(&self, reporter: &dyn Reporter) {
263245
// if we're calling this again, then clear what ever cache we have.
264-
let mut environments = self.environments.lock().unwrap();
265-
environments.clear();
266-
drop(environments);
246+
self.clear();
267247

268248
let env_vars = self.env_vars.clone();
269-
let additional_paths = self.env_dirs.lock().unwrap().clone();
270249
thread::scope(|s| {
271250
// 1. Get a list of all know conda environments file paths
272-
let possible_conda_envs = get_conda_environment_paths(&env_vars, &additional_paths);
251+
let possible_conda_envs = get_conda_environment_paths(&env_vars);
273252
for path in possible_conda_envs {
274253
s.spawn(move || {
275254
// 2. Get the details of the conda environment

crates/pet-core/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub struct Configuration {
3636
pub trait Locator: Send + Sync {
3737
/// Returns the name of the locator.
3838
fn get_name(&self) -> &'static str;
39+
/// Configures the locator with the given configuration.
40+
/// Override this method if you need to have some custom configuration.
41+
/// E.g. storing some of the configuration information in the locator.
3942
fn configure(&self, _config: &Configuration) {
4043
//
4144
}

crates/pet-homebrew/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn from(env: &PythonEnv) -> Option<PythonEnvironment> {
110110

111111
impl Locator for Homebrew {
112112
fn get_name(&self) -> &'static str {
113-
"Homebrew"
113+
"Homebrew" // Do not change this name, as this is used in telemetry.
114114
}
115115
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
116116
vec![PythonEnvironmentKind::Homebrew]

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl Default for LinuxGlobalPython {
5656
}
5757
impl Locator for LinuxGlobalPython {
5858
fn get_name(&self) -> &'static str {
59-
"LinuxGlobalPython"
59+
"LinuxGlobalPython" // Do not change this name, as this is used in telemetry.
6060
}
6161
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
6262
vec![PythonEnvironmentKind::LinuxGlobal]

crates/pet-mac-commandlinetools/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl Default for MacCmdLineTools {
2929
}
3030
impl Locator for MacCmdLineTools {
3131
fn get_name(&self) -> &'static str {
32-
"MacCmdLineTools"
32+
"MacCmdLineTools" // Do not change this name, as this is used in telemetry.
3333
}
3434
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
3535
vec![PythonEnvironmentKind::MacCommandLineTools]

crates/pet-mac-python-org/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl Default for MacPythonOrg {
2828
}
2929
impl Locator for MacPythonOrg {
3030
fn get_name(&self) -> &'static str {
31-
"MacPythonOrg"
31+
"MacPythonOrg" // Do not change this name, as this is used in telemetry.
3232
}
3333
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
3434
vec![PythonEnvironmentKind::MacPythonOrg]

crates/pet-mac-xcode/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl Default for MacXCode {
2929
}
3030
impl Locator for MacXCode {
3131
fn get_name(&self) -> &'static str {
32-
"MacXCode"
32+
"MacXCode" // Do not change this name, as this is used in telemetry.
3333
}
3434
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
3535
vec![PythonEnvironmentKind::MacCommandLineTools]

crates/pet-pipenv/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl PipEnv {
7272
}
7373
impl Locator for PipEnv {
7474
fn get_name(&self) -> &'static str {
75-
"PipEnv"
75+
"PipEnv" // Do not change this name, as this is used in telemetry.
7676
}
7777
fn supported_categories(&self) -> Vec<PythonEnvironmentKind> {
7878
vec![PythonEnvironmentKind::Pipenv]

crates/pet-poetry/src/lib.rs

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use env_variables::EnvVariables;
55
use environment_locations::list_environments;
6-
use log::error;
76
use manager::PoetryManager;
87
use pet_core::{
98
os_environment::Environment,
@@ -15,10 +14,7 @@ use pet_python_utils::env::PythonEnv;
1514
use pet_virtualenv::is_virtualenv;
1615
use std::{
1716
path::PathBuf,
18-
sync::{
19-
atomic::{AtomicBool, Ordering},
20-
Arc, Mutex,
21-
},
17+
sync::{Arc, Mutex},
2218
};
2319
use telemetry::report_missing_envs;
2420

@@ -43,27 +39,31 @@ pub struct Poetry {
4339
pub workspace_directories: Arc<Mutex<Vec<PathBuf>>>,
4440
pub env_vars: EnvVariables,
4541
pub poetry_executable: Arc<Mutex<Option<PathBuf>>>,
46-
searched: AtomicBool,
4742
search_result: Arc<Mutex<Option<LocatorResult>>>,
4843
}
4944

5045
impl Poetry {
5146
pub fn new(environment: &dyn Environment) -> Self {
5247
Poetry {
53-
searched: AtomicBool::new(false),
5448
search_result: Arc::new(Mutex::new(None)),
5549
workspace_directories: Arc::new(Mutex::new(vec![])),
5650
env_vars: EnvVariables::from(environment),
5751
poetry_executable: Arc::new(Mutex::new(None)),
5852
}
5953
}
54+
fn clear(&self) {
55+
self.poetry_executable.lock().unwrap().take();
56+
self.search_result.lock().unwrap().take();
57+
}
6058
pub fn from(environment: &dyn Environment) -> Poetry {
6159
Poetry::new(environment)
6260
}
6361
fn find_with_cache(&self) -> Option<LocatorResult> {
64-
if self.searched.load(Ordering::Relaxed) {
65-
return self.search_result.lock().unwrap().clone();
62+
let mut search_result = self.search_result.lock().unwrap();
63+
if let Some(result) = search_result.clone() {
64+
return Some(result);
6665
}
66+
6767
// First find the manager
6868
let manager = manager::PoetryManager::find(
6969
self.poetry_executable.lock().unwrap().clone(),
@@ -76,28 +76,18 @@ impl Poetry {
7676
if let Some(manager) = &manager {
7777
result.managers.push(manager.to_manager());
7878
}
79-
if let Ok(values) = self.workspace_directories.lock() {
80-
let workspace_dirs = values.clone();
81-
drop(values);
82-
let envs = list_environments(&self.env_vars, &workspace_dirs.clone(), manager)
83-
.unwrap_or_default();
84-
result.environments.extend(envs.clone());
85-
}
8679

87-
match self.search_result.lock().as_mut() {
88-
Ok(search_result) => {
89-
if result.managers.is_empty() && result.environments.is_empty() {
90-
search_result.take();
91-
None
92-
} else {
93-
search_result.replace(result.clone());
94-
Some(result)
95-
}
96-
}
97-
Err(err) => {
98-
error!("Failed to cache to Poetry environments: {:?}", err);
99-
None
100-
}
80+
let workspace_dirs = self.workspace_directories.lock().unwrap().clone();
81+
let envs = list_environments(&self.env_vars, &workspace_dirs, manager).unwrap_or_default();
82+
result.environments.extend(envs.clone());
83+
84+
// Having a value in the search result means that we have already searched for environments
85+
search_result.replace(result.clone());
86+
87+
if result.managers.is_empty() && result.environments.is_empty() {
88+
None
89+
} else {
90+
Some(result)
10191
}
10292
}
10393
}
@@ -136,7 +126,7 @@ impl PoetryLocator for Poetry {
136126

137127
impl Locator for Poetry {
138128
fn get_name(&self) -> &'static str {
139-
"Poetry"
129+
"Poetry" // Do not change this name, as this is used in telemetry.
140130
}
141131
fn configure(&self, config: &Configuration) {
142132
if let Some(workspace_directories) = &config.workspace_directories {
@@ -174,6 +164,7 @@ impl Locator for Poetry {
174164
}
175165

176166
fn find(&self, reporter: &dyn Reporter) {
167+
self.clear();
177168
if let Some(result) = self.find_with_cache() {
178169
for manager in result.managers {
179170
reporter.report_manager(&manager.clone());

0 commit comments

Comments
 (0)