1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00
denoland-deno/cli/tools/jupyter/install.rs
David Sherret 47f7bed677
chore: enable clippy::print_stdout and clippy::print_stderr (#23732)
1. Generally we should prefer to use the `log` crate.
2. I very often accidentally commit `eprintln`s.

When we should use `println` or `eprintln`, it's not too bad to be a bit
more verbose and ignore the lint rule.
2024-05-08 22:45:06 -04:00

113 lines
3.4 KiB
Rust
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
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")?;
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(());
}
}
}
log::warn!(" Deno kernel is not yet installed, run `deno jupyter --install` to set it up");
Ok(())
}
fn install_icon(
dir_path: &Path,
filename: &str,
icon_data: &[u8],
) -> Result<(), AnyError> {
let path = dir_path.join(filename);
let mut file = std::fs::File::create(path)?;
file.write_all(icon_data)?;
Ok(())
}
pub fn install() -> Result<(), AnyError> {
let temp_dir = TempDir::new().unwrap();
let kernel_json_path = temp_dir.path().join("kernel.json");
// TODO(bartlomieju): add remaining fields as per
// https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs
// FIXME(bartlomieju): replace `current_exe` before landing?
let json_data = json!({
"argv": [current_exe().unwrap().to_string_lossy(), "jupyter", "--kernel", "--conn", "{connection_file}"],
"display_name": "Deno",
"language": "typescript",
});
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);
}
}
let _ = std::fs::remove_dir(temp_dir);
log::info!("✅ Deno kernelspec installed successfully.");
Ok(())
}