Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions crates/pet-core/src/python_environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ pub struct PythonEnvironment {
// Some of the known symlinks for the environment.
// E.g. in the case of Homebrew there are a number of symlinks that are created.
pub symlinks: Option<Vec<PathBuf>>,
/// The folder/path that was searched to find this environment.
/// Generally applies to workspace folder, and means that the environment was found in this folder or is related to this folder.
/// Similar in meaqning to `project` but is more of a search path.
pub search_path: Option<PathBuf>,
}

impl Ord for PythonEnvironment {
Expand Down Expand Up @@ -146,9 +142,6 @@ impl std::fmt::Display for PythonEnvironment {
if let Some(project) = &self.project {
writeln!(f, " Project : {}", project.to_str().unwrap()).unwrap_or_default();
}
if let Some(search_path) = &self.search_path {
writeln!(f, " Search Path : {}", search_path.to_str().unwrap()).unwrap_or_default();
}
if let Some(arch) = &self.arch {
writeln!(f, " Architecture: {arch}").unwrap_or_default();
}
Expand Down Expand Up @@ -198,7 +191,6 @@ pub struct PythonEnvironmentBuilder {
project: Option<PathBuf>,
arch: Option<Architecture>,
symlinks: Option<Vec<PathBuf>>,
search_path: Option<PathBuf>,
}

impl PythonEnvironmentBuilder {
Expand All @@ -214,7 +206,6 @@ impl PythonEnvironmentBuilder {
project: None,
arch: None,
symlinks: None,
search_path: None,
}
}

Expand Down Expand Up @@ -277,11 +268,6 @@ impl PythonEnvironmentBuilder {
self
}

pub fn search_path(mut self, search_path: Option<PathBuf>) -> Self {
self.search_path = search_path;
self
}

fn update_symlinks_and_exe(&mut self, symlinks: Option<Vec<PathBuf>>) {
let mut all = vec![];
if let Some(ref exe) = self.executable {
Expand Down Expand Up @@ -336,7 +322,6 @@ impl PythonEnvironmentBuilder {
manager: self.manager,
project: self.project,
arch: self.arch,
search_path: self.search_path,
symlinks,
}
}
Expand Down
27 changes: 4 additions & 23 deletions crates/pet/src/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ pub fn find_and_report_envs(
locators,
false,
&global_env_search_paths,
None,
);
summary.lock().unwrap().find_path_time = start.elapsed();
});
Expand Down Expand Up @@ -117,7 +116,6 @@ pub fn find_and_report_envs(
locators,
false,
&global_env_search_paths,
None,
);
summary.lock().unwrap().find_global_virtual_envs_time = start.elapsed();
});
Expand Down Expand Up @@ -173,7 +171,6 @@ fn find_python_environments_in_workspace_folders_recursive(
reporter,
true,
&[],
Some(workspace_folder.clone()),
);

// If this is a virtual env folder, no need to scan this.
Expand All @@ -189,14 +186,7 @@ fn find_python_environments_in_workspace_folders_recursive(
.filter(should_search_for_environments_in_path)
.filter(|p| !paths_to_search_first.contains(p))
{
find_python_environments(
vec![folder],
reporter,
locators,
true,
&[],
Some(workspace_folder.clone()),
);
find_python_environments(vec![folder], reporter, locators, true, &[]);
}
}
}
Expand All @@ -210,23 +200,20 @@ fn find_python_environments(
locators: &Arc<Vec<Arc<dyn Locator>>>,
is_workspace_folder: bool,
global_env_search_paths: &[PathBuf],
search_path: Option<PathBuf>,
) {
if paths.is_empty() {
return;
}
thread::scope(|s| {
for item in paths {
let locators = locators.clone();
let search_path = search_path.clone();
s.spawn(move || {
find_python_environments_in_paths_with_locators(
vec![item],
&locators,
reporter,
is_workspace_folder,
global_env_search_paths,
search_path,
);
});
}
Expand All @@ -239,7 +226,6 @@ fn find_python_environments_in_paths_with_locators(
reporter: &dyn Reporter,
is_workspace_folder: bool,
global_env_search_paths: &[PathBuf],
search_path: Option<PathBuf>,
) {
for path in paths {
let executables = if is_workspace_folder {
Expand Down Expand Up @@ -275,7 +261,6 @@ fn find_python_environments_in_paths_with_locators(
locators,
reporter,
global_env_search_paths,
search_path.clone(),
);
}
}
Expand All @@ -285,17 +270,13 @@ fn identify_python_executables_using_locators(
locators: &Arc<Vec<Arc<dyn Locator>>>,
reporter: &dyn Reporter,
global_env_search_paths: &[PathBuf],
search_path: Option<PathBuf>,
) {
for exe in executables.into_iter() {
let executable = exe.clone();
let env = PythonEnv::new(exe.to_owned(), None, None);
if let Some(env) = identify_python_environment_using_locators(
&env,
locators,
global_env_search_paths,
search_path.clone(),
) {
if let Some(env) =
identify_python_environment_using_locators(&env, locators, global_env_search_paths)
{
reporter.report_environment(&env);
if let Some(manager) = env.manager {
reporter.report_manager(&manager);
Expand Down
16 changes: 3 additions & 13 deletions crates/pet/src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,24 +202,14 @@ pub fn handle_resolve(context: Arc<Context>, id: u32, params: Value) {
match serde_json::from_value::<ResolveOptions>(params.clone()) {
Ok(request_options) => {
let executable = request_options.executable.clone();
let search_paths = context
.configuration
.read()
.unwrap()
.clone()
.workspace_directories;
let search_paths = search_paths.unwrap_or_default();
// Start in a new thread, we can have multiple resolve requests.
let environment = context.os_environment.clone();
thread::spawn(move || {
let now = SystemTime::now();
trace!("Resolving env {:?}", executable);
if let Some(result) = resolve_environment(
&executable,
&context.locators,
search_paths,
environment.deref(),
) {
if let Some(result) =
resolve_environment(&executable, &context.locators, environment.deref())
{
if let Some(resolved) = result.resolved {
// Gather telemetry of this resolved env and see what we got wrong.
let _ = report_inaccuracies_identified_after_resolving(
Expand Down
52 changes: 6 additions & 46 deletions crates/pet/src/locators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,12 @@ pub fn identify_python_environment_using_locators(
env: &PythonEnv,
locators: &[Arc<dyn Locator>],
global_env_search_paths: &[PathBuf],
search_path: Option<PathBuf>,
) -> Option<PythonEnvironment> {
let executable = env.executable.clone();
let search_paths = if let Some(search_path) = search_path {
vec![search_path]
} else {
vec![]
};
if let Some(mut env) =
locators.iter().fold(
None,
|e, loc| if e.is_some() { e } else { loc.try_from(env) },
)
{
identify_and_set_search_path(&mut env, &search_paths);
if let Some(env) = locators.iter().fold(
None,
|e, loc| if e.is_some() { e } else { loc.try_from(env) },
) {
return Some(env);
}

Expand All @@ -112,14 +103,13 @@ pub fn identify_python_environment_using_locators(
// We try to get the interpreter info, hoping that the real exe returned might be identifiable.
if let Some(resolved_env) = ResolvedPythonEnv::from(&executable) {
let env = resolved_env.to_python_env();
if let Some(mut env) =
if let Some(env) =
locators.iter().fold(
None,
|e, loc| if e.is_some() { e } else { loc.try_from(&env) },
)
{
trace!("Env ({:?}) in Path resolved as {:?}", executable, env.kind);
identify_and_set_search_path(&mut env, &search_paths);
// TODO: Telemetry point.
// As we had to spawn earlier.
return Some(env);
Expand Down Expand Up @@ -147,42 +137,12 @@ pub fn identify_python_environment_using_locators(
"Env ({:?}) in Path resolved as {:?} and reported as {:?}",
executable, resolved_env, fallback_kind
);
let mut env = create_unknown_env(resolved_env, fallback_kind);
identify_and_set_search_path(&mut env, &search_paths);
return Some(env);
return Some(create_unknown_env(resolved_env, fallback_kind));
}
}
None
}

/// Assume we found a .venv environment, generally these are specific to a workspace folder, i.e. they belong in a worksapce folder.
/// If thats the case then verify this by checking if the workspace folder is a parent of the prefix (.venv folder).
/// If it is, and there is not project set, then set the search_path to the workspace folder.
pub fn identify_and_set_search_path(env: &mut PythonEnvironment, search_path: &Vec<PathBuf>) {
if search_path.is_empty() || env.project.is_some() {
return;
}

// All other environments generally need to be found globally,
// If we end up with some env thats not found globally, but only found in a special folder for some reason,
// then thats a weird situation, either way, when we cache the result it will re-appear (however for all other workspaces as well)
// Thats fine for now (if users complain then we'll find out that there's a problem and we can fix it then).
// Else no need to try and identify/fix edge cases that may not exist.
if env.kind == Some(PythonEnvironmentKind::Conda)
|| env.kind == Some(PythonEnvironmentKind::Venv)
|| env.kind == Some(PythonEnvironmentKind::VirtualEnv)
{
if let Some(prefix) = &env.prefix {
for path in search_path {
if path.starts_with(prefix) {
env.search_path = Some(path.clone());
break;
}
}
}
}
}

fn create_unknown_env(
resolved_env: ResolvedPythonEnv,
fallback_category: Option<PythonEnvironmentKind>,
Expand Down
9 changes: 3 additions & 6 deletions crates/pet/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use pet_core::{
use pet_env_var_path::get_search_paths_from_env_variables;
use pet_python_utils::env::{PythonEnv, ResolvedPythonEnv};

use crate::locators::{identify_and_set_search_path, identify_python_environment_using_locators};
use crate::locators::identify_python_environment_using_locators;

#[derive(Debug)]
pub struct ResolvedEnvironment {
Expand All @@ -24,17 +24,15 @@ pub struct ResolvedEnvironment {
pub fn resolve_environment(
executable: &PathBuf,
locators: &Arc<Vec<Arc<dyn Locator>>>,
search_paths: Vec<PathBuf>,
os_environment: &dyn Environment,
) -> Option<ResolvedEnvironment> {
// First check if this is a known environment
let env = PythonEnv::new(executable.to_owned(), None, None);
let global_env_search_paths: Vec<PathBuf> = get_search_paths_from_env_variables(os_environment);

if let Some(mut env) =
identify_python_environment_using_locators(&env, locators, &global_env_search_paths, None)
if let Some(env) =
identify_python_environment_using_locators(&env, locators, &global_env_search_paths)
{
identify_and_set_search_path(&mut env, &search_paths);
// Ok we got the environment.
// Now try to resolve this fully, by spawning python.
if let Some(ref executable) = env.executable {
Expand Down Expand Up @@ -67,7 +65,6 @@ pub fn resolve_environment(
.name(env.name)
.prefix(prefix)
.project(env.project)
.search_path(env.search_path)
.symlinks(Some(symlinks))
.version(version)
.build();
Expand Down
23 changes: 9 additions & 14 deletions crates/pet/tests/ci_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,12 @@ fn verify_we_can_get_same_env_info_using_from_with_exe(
get_search_paths_from_env_variables(&os_environment);

let env = PythonEnv::new(executable.clone(), None, None);
let resolved = identify_python_environment_using_locators(
&env,
&locators,
&global_env_search_paths,
Some(workspace_dir.clone()),
)
.expect(format!("Failed to resolve environment using `resolve` for {environment:?}").as_str());
let resolved =
identify_python_environment_using_locators(&env, &locators, &global_env_search_paths)
.expect(
format!("Failed to resolve environment using `resolve` for {environment:?}")
.as_str(),
);
trace!(
"For exe {:?} we got Environment = {:?}, To compare against {:?}",
executable,
Expand Down Expand Up @@ -543,13 +542,9 @@ fn verify_we_can_get_same_env_info_using_resolve_with_exe(
locator.configure(&config);
}

let env = resolve_environment(
&executable,
&locators,
vec![workspace_dir.clone()],
&os_environment,
)
.expect(format!("Failed to resolve environment using `resolve` for {environment:?}").as_str());
let env = resolve_environment(&executable, &locators, &os_environment).expect(
format!("Failed to resolve environment using `resolve` for {environment:?}").as_str(),
);
trace!(
"For exe {:?} we got Environment = {:?}, To compare against {:?}",
executable,
Expand Down