repl: Detect Conda and Python environments with their own kernel specs (#15047)

Kyle Kelley created

Detect kernels in conda and python environments.

Release Notes:

- N/A

Change summary

crates/repl/src/kernels.rs | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)

Detailed changes

crates/repl/src/kernels.rs 🔗

@@ -13,6 +13,7 @@ use runtimelib::{
 };
 use smol::{net::TcpListener, process::Command};
 use std::{
+    env,
     fmt::Debug,
     net::{IpAddr, Ipv4Addr, SocketAddr},
     path::PathBuf,
@@ -374,7 +375,33 @@ async fn read_kernels_dir(path: PathBuf, fs: &dyn Fs) -> Result<Vec<KernelSpecif
 }
 
 pub async fn kernel_specifications(fs: Arc<dyn Fs>) -> Result<Vec<KernelSpecification>> {
-    let data_dirs = dirs::data_dirs();
+    let mut data_dirs = dirs::data_dirs();
+
+    // Pick up any kernels from conda or conda environment
+    if let Ok(conda_prefix) = env::var("CONDA_PREFIX") {
+        let conda_prefix = PathBuf::from(conda_prefix);
+        let conda_data_dir = conda_prefix.join("share").join("jupyter");
+        data_dirs.push(conda_data_dir);
+    }
+
+    // Search for kernels inside the base python environment
+    let command = Command::new("python")
+        .arg("-c")
+        .arg("import sys; print(sys.prefix)")
+        .output()
+        .await;
+
+    if let Ok(command) = command {
+        if command.status.success() {
+            let python_prefix = String::from_utf8(command.stdout);
+            if let Ok(python_prefix) = python_prefix {
+                let python_prefix = PathBuf::from(python_prefix.trim());
+                let python_data_dir = python_prefix.join("share").join("jupyter");
+                data_dirs.push(python_data_dir);
+            }
+        }
+    }
+
     let kernel_dirs = data_dirs
         .iter()
         .map(|dir| dir.join("kernels"))