diff options
author | Kyle Kelley <rgbkrk@gmail.com> | 2024-05-21 13:35:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-21 22:35:21 +0200 |
commit | 8698e80304815353ec52be1b16f96483ebe559a0 (patch) | |
tree | 9abd53d5b656cd8cc0c1aa3940684f3ce1d9c8ef /cli/tools/jupyter/install.rs | |
parent | cc8c0609ebec9f101a1739a0c42c91718ca2abba (diff) |
refactor(jupyter): use runtimelib for Jupyter structures and directory paths (#23826)
This brings in [`runtimelib`](https://github.com/runtimed/runtimed) to
use:
## Fully typed structs for Jupyter Messages
```rust
let msg = connection.read().await?;
self
.send_iopub(
runtimelib::Status::busy().as_child_of(msg),
)
.await?;
```
## Jupyter paths
Jupyter paths are implemented in Rust, allowing the Deno kernel to be
installed completely via Deno without a requirement on Python or
Jupyter. Deno users will be able to install and use the kernel with just
VS Code or other editors that support Jupyter.
```rust
pub fn status() -> Result<(), AnyError> {
let user_data_dir = user_data_dir()?;
let kernel_spec_dir_path = user_data_dir.join("kernels").join("deno");
let kernel_spec_path = kernel_spec_dir_path.join("kernel.json");
if kernel_spec_path.exists() {
log::info!("✅ Deno kernel already installed");
Ok(())
} else {
log::warn!("ℹ️ Deno kernel is not yet installed, run `deno jupyter --install` to set it up");
Ok(())
}
}
```
Closes https://github.com/denoland/deno/issues/21619
Diffstat (limited to 'cli/tools/jupyter/install.rs')
-rw-r--r-- | cli/tools/jupyter/install.rs | 88 |
1 files changed, 21 insertions, 67 deletions
diff --git a/cli/tools/jupyter/install.rs b/cli/tools/jupyter/install.rs index 69a75837e..40f21d3c1 100644 --- a/cli/tools/jupyter/install.rs +++ b/cli/tools/jupyter/install.rs @@ -1,40 +1,31 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_core::anyhow::bail; -use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::serde_json; use deno_core::serde_json::json; use std::env::current_exe; -use std::io::ErrorKind; use std::io::Write; use std::path::Path; -use tempfile::TempDir; + +use runtimelib::dirs::user_data_dir; const DENO_ICON_32: &[u8] = include_bytes!("./resources/deno-logo-32x32.png"); const DENO_ICON_64: &[u8] = include_bytes!("./resources/deno-logo-64x64.png"); const DENO_ICON_SVG: &[u8] = include_bytes!("./resources/deno-logo-svg.svg"); pub fn status() -> Result<(), AnyError> { - let output = std::process::Command::new("jupyter") - .args(["kernelspec", "list", "--json"]) - .output() - .context("Failed to get list of installed kernelspecs")?; - let json_output: serde_json::Value = - serde_json::from_slice(&output.stdout) - .context("Failed to parse JSON from kernelspec list")?; + let user_data_dir = user_data_dir()?; - if let Some(specs) = json_output.get("kernelspecs") { - if let Some(specs_obj) = specs.as_object() { - if specs_obj.contains_key("deno") { - log::info!("✅ Deno kernel already installed"); - return Ok(()); - } - } - } + let kernel_spec_dir_path = user_data_dir.join("kernels").join("deno"); + let kernel_spec_path = kernel_spec_dir_path.join("kernel.json"); - log::warn!("ℹ️ Deno kernel is not yet installed, run `deno jupyter --install` to set it up"); - Ok(()) + if kernel_spec_path.exists() { + log::info!("✅ Deno kernel already installed"); + Ok(()) + } else { + log::warn!("ℹ️ Deno kernel is not yet installed, run `deno jupyter --install` to set it up"); + Ok(()) + } } fn install_icon( @@ -49,8 +40,12 @@ fn install_icon( } pub fn install() -> Result<(), AnyError> { - let temp_dir = TempDir::new().unwrap(); - let kernel_json_path = temp_dir.path().join("kernel.json"); + let user_data_dir = user_data_dir()?; + let kernel_dir = user_data_dir.join("kernels").join("deno"); + + std::fs::create_dir_all(&kernel_dir)?; + + let kernel_json_path = kernel_dir.join("kernel.json"); // TODO(bartlomieju): add remaining fields as per // https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs @@ -63,51 +58,10 @@ pub fn install() -> Result<(), AnyError> { let f = std::fs::File::create(kernel_json_path)?; serde_json::to_writer_pretty(f, &json_data)?; - install_icon(temp_dir.path(), "logo-32x32.png", DENO_ICON_32)?; - install_icon(temp_dir.path(), "logo-64x64.png", DENO_ICON_64)?; - install_icon(temp_dir.path(), "logo-svg.svg", DENO_ICON_SVG)?; - - let child_result = std::process::Command::new("jupyter") - .args([ - "kernelspec", - "install", - "--user", - "--name", - "deno", - &temp_dir.path().to_string_lossy(), - ]) - .spawn(); - let mut child = match child_result { - Ok(child) => child, - Err(err) - if matches!( - err.kind(), - ErrorKind::NotFound | ErrorKind::PermissionDenied - ) => - { - return Err(err).context(concat!( - "Failed to spawn 'jupyter' command. Is JupyterLab installed ", - "(https://jupyter.org/install) and available on the PATH?" - )); - } - Err(err) => { - return Err(err).context("Failed to spawn 'jupyter' command."); - } - }; - - let wait_result = child.wait(); - match wait_result { - Ok(status) => { - if !status.success() { - bail!("Failed to install kernelspec, try again."); - } - } - Err(err) => { - bail!("Failed to install kernelspec: {}", err); - } - } + install_icon(&user_data_dir, "logo-32x32.png", DENO_ICON_32)?; + install_icon(&user_data_dir, "logo-64x64.png", DENO_ICON_64)?; + install_icon(&user_data_dir, "logo-svg.svg", DENO_ICON_SVG)?; - let _ = std::fs::remove_dir(temp_dir); log::info!("✅ Deno kernelspec installed successfully."); Ok(()) } |