summaryrefslogtreecommitdiff
path: root/cli/tools/jupyter/install.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/jupyter/install.rs')
-rw-r--r--cli/tools/jupyter/install.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/cli/tools/jupyter/install.rs b/cli/tools/jupyter/install.rs
new file mode 100644
index 000000000..d1777d92d
--- /dev/null
+++ b/cli/tools/jupyter/install.rs
@@ -0,0 +1,95 @@
+// Copyright 2018-2023 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::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");
+
+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") {
+ println!("✅ Deno kernel already installed");
+ return Ok(());
+ }
+ }
+ }
+
+ println!("â„šī¸ Deno kernel is not yet installed, run `deno jupyter --unstable --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(), "--unstable", "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(), "icon-32x32.png", DENO_ICON_32)?;
+ install_icon(temp_dir.path(), "icon-64x64.png", DENO_ICON_64)?;
+
+ let child_result = std::process::Command::new("jupyter")
+ .args([
+ "kernelspec",
+ "install",
+ "--user",
+ "--name",
+ "deno",
+ &temp_dir.path().to_string_lossy(),
+ ])
+ .spawn();
+
+ if let Ok(mut child) = child_result {
+ 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);
+ println!("✅ Deno kernelspec installed successfully.");
+ Ok(())
+}