diff --git a/crates/pet-conda/src/lib.rs b/crates/pet-conda/src/lib.rs index f599ec73..fcd0ea01 100644 --- a/crates/pet-conda/src/lib.rs +++ b/crates/pet-conda/src/lib.rs @@ -14,13 +14,14 @@ use pet_core::{ Locator, LocatorResult, }; use pet_python_utils::env::PythonEnv; +use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, path::{Path, PathBuf}, sync::{Arc, Mutex}, thread, }; -use telemetry::report_missing_envs; +use telemetry::{get_conda_rcs_and_env_dirs, report_missing_envs}; use utils::{is_conda_env, is_conda_install}; mod conda_info; @@ -40,7 +41,17 @@ pub trait CondaLocator: Send + Sync { reporter: &dyn Reporter, conda_executable: Option, ) -> Option<()>; + fn get_info_for_telemetry(&self, conda_executable: Option) -> CondaTelemetryInfo; } + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CondaTelemetryInfo { + pub can_spawn_conda: bool, + pub conda_rcs: Vec, + pub env_dirs: Vec, +} + pub struct Conda { /// Directories where conda environments are found (env_dirs returned from `conda info --json`) pub env_dirs: Arc>>, @@ -108,6 +119,20 @@ impl CondaLocator for Conda { Some(()) } + fn get_info_for_telemetry(&self, conda_executable: Option) -> CondaTelemetryInfo { + let can_spawn_conda = CondaInfo::from(conda_executable).is_some(); + let environments = self.environments.lock().unwrap().clone(); + let environments = environments + .into_values() + .collect::>(); + let (conda_rcs, env_dirs) = get_conda_rcs_and_env_dirs(&self.env_vars, &environments); + CondaTelemetryInfo { + can_spawn_conda, + conda_rcs, + env_dirs, + } + } + fn find_in(&self, conda_dir: &Path) -> Option { if !is_conda_install(conda_dir) { return None; diff --git a/crates/pet-conda/src/telemetry.rs b/crates/pet-conda/src/telemetry.rs index 5b368b20..8b80da82 100644 --- a/crates/pet-conda/src/telemetry.rs +++ b/crates/pet-conda/src/telemetry.rs @@ -188,6 +188,23 @@ pub fn report_missing_envs( Some(()) } +pub fn get_conda_rcs_and_env_dirs( + env_vars: &EnvVariables, + known_envs: &[PythonEnvironment], +) -> (Vec, Vec) { + let known_conda_rcs = get_all_known_conda_rc(env_vars, known_envs); + let discovered_conda_rcs = known_conda_rcs + .iter() + .flat_map(|rc| rc.files.clone().into_iter()) + .collect(); + let discovered_env_dirs = known_conda_rcs + .iter() + .flat_map(|rc| rc.env_dirs.clone().into_iter()) + .collect(); + + (discovered_conda_rcs, discovered_env_dirs) +} + fn log_and_find_missing_envs( possibly_missing_envs: &[PathBuf], known_envs: &[PythonEnvironment], diff --git a/crates/pet/src/jsonrpc.rs b/crates/pet/src/jsonrpc.rs index 0523bc21..d5f69016 100644 --- a/crates/pet/src/jsonrpc.rs +++ b/crates/pet/src/jsonrpc.rs @@ -60,6 +60,7 @@ pub fn start_jsonrpc_server() { handlers.add_request_handler("configure", handle_configure); handlers.add_request_handler("refresh", handle_refresh); handlers.add_request_handler("resolve", handle_resolve); + handlers.add_request_handler("condaInfo", handle_conda_telemetry); start_server(&handlers) } @@ -249,3 +250,17 @@ pub fn handle_resolve(context: Arc, id: u32, params: Value) { } } } + +pub fn handle_conda_telemetry(context: Arc, id: u32, _params: Value) { + thread::spawn(move || { + let conda_locator = context.conda_locator.clone(); + let conda_executable = context + .configuration + .read() + .unwrap() + .conda_executable + .clone(); + let info = conda_locator.get_info_for_telemetry(conda_executable); + send_reply(id, info.into()); + }); +}