From bf0760411336ce5ebb1c103f766c8154af478414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 16 Sep 2023 02:42:09 +0200 Subject: feat: Add "deno jupyter" subcommand (#20337) This commit adds "deno jupyter" subcommand which provides a Deno kernel for Jupyter notebooks. The implementation is mostly based on Deno's REPL and reuses large parts of it (though there's some clean up that needs to happen in follow up PRs). Not all functionality of Jupyter kernel is implemented and some message type are still not implemented (eg. "inspect_request") but the kernel is fully working and provides all the capatibilities that the Deno REPL has; including TypeScript transpilation and npm packages support. Closes https://github.com/denoland/deno/issues/13016 --------- Co-authored-by: Adam Powers Co-authored-by: Kyle Kelley --- cli/args/flags.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) (limited to 'cli/args') diff --git a/cli/args/flags.rs b/cli/args/flags.rs index b69f1ce8f..40aa7b8e3 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -158,6 +158,13 @@ pub struct InstallFlags { pub force: bool, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct JupyterFlags { + pub install: bool, + pub kernel: bool, + pub conn_file: Option, +} + #[derive(Clone, Debug, Eq, PartialEq)] pub struct UninstallFlags { pub name: String, @@ -276,6 +283,7 @@ pub enum DenoSubcommand { Init(InitFlags), Info(InfoFlags), Install(InstallFlags), + Jupyter(JupyterFlags), Uninstall(UninstallFlags), Lsp, Lint(LintFlags), @@ -678,7 +686,8 @@ impl Flags { std::env::current_dir().ok() } Bundle(_) | Completions(_) | Doc(_) | Fmt(_) | Init(_) | Install(_) - | Uninstall(_) | Lsp | Lint(_) | Types | Upgrade(_) | Vendor(_) => None, + | Uninstall(_) | Jupyter(_) | Lsp | Lint(_) | Types | Upgrade(_) + | Vendor(_) => None, } } @@ -818,6 +827,7 @@ pub fn flags_from_vec(args: Vec) -> clap::error::Result { "init" => init_parse(&mut flags, &mut m), "info" => info_parse(&mut flags, &mut m), "install" => install_parse(&mut flags, &mut m), + "jupyter" => jupyter_parse(&mut flags, &mut m), "lint" => lint_parse(&mut flags, &mut m), "lsp" => lsp_parse(&mut flags, &mut m), "repl" => repl_parse(&mut flags, &mut m), @@ -919,6 +929,7 @@ fn clap_root() -> Command { .subcommand(init_subcommand()) .subcommand(info_subcommand()) .subcommand(install_subcommand()) + .subcommand(jupyter_subcommand()) .subcommand(uninstall_subcommand()) .subcommand(lsp_subcommand()) .subcommand(lint_subcommand()) @@ -1613,6 +1624,33 @@ These must be added to the path manually if required.") ) } +fn jupyter_subcommand() -> Command { + Command::new("jupyter") + .arg( + Arg::new("install") + .long("install") + .help("Installs kernelspec, requires 'jupyter' command to be available.") + .conflicts_with("kernel") + .action(ArgAction::SetTrue) + ) + .arg( + Arg::new("kernel") + .long("kernel") + .help("Start the kernel") + .conflicts_with("install") + .requires("conn") + .action(ArgAction::SetTrue) + ) + .arg( + Arg::new("conn") + .long("conn") + .help("Path to JSON file describing connection parameters, provided by Jupyter") + .value_parser(value_parser!(PathBuf)) + .value_hint(ValueHint::FilePath) + .conflicts_with("install")) + .about("Deno kernel for Jupyter notebooks") +} + fn uninstall_subcommand() -> Command { Command::new("uninstall") .about("Uninstall a script previously installed with deno install") @@ -3166,6 +3204,18 @@ fn install_parse(flags: &mut Flags, matches: &mut ArgMatches) { }); } +fn jupyter_parse(flags: &mut Flags, matches: &mut ArgMatches) { + let conn_file = matches.remove_one::("conn"); + let kernel = matches.get_flag("kernel"); + let install = matches.get_flag("install"); + + flags.subcommand = DenoSubcommand::Jupyter(JupyterFlags { + install, + kernel, + conn_file, + }); +} + fn uninstall_parse(flags: &mut Flags, matches: &mut ArgMatches) { let root = matches.remove_one::("root"); @@ -7829,4 +7879,69 @@ mod tests { } ); } + + #[test] + fn jupyter() { + let r = flags_from_vec(svec!["deno", "jupyter", "--unstable"]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Jupyter(JupyterFlags { + install: false, + kernel: false, + conn_file: None, + }), + unstable: true, + ..Flags::default() + } + ); + + let r = flags_from_vec(svec!["deno", "jupyter", "--unstable", "--install"]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Jupyter(JupyterFlags { + install: true, + kernel: false, + conn_file: None, + }), + unstable: true, + ..Flags::default() + } + ); + + let r = flags_from_vec(svec![ + "deno", + "jupyter", + "--unstable", + "--kernel", + "--conn", + "path/to/conn/file" + ]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Jupyter(JupyterFlags { + install: false, + kernel: true, + conn_file: Some(PathBuf::from("path/to/conn/file")), + }), + unstable: true, + ..Flags::default() + } + ); + + let r = flags_from_vec(svec![ + "deno", + "jupyter", + "--install", + "--conn", + "path/to/conn/file" + ]); + r.unwrap_err(); + let r = flags_from_vec(svec!["deno", "jupyter", "--kernel",]); + r.unwrap_err(); + let r = flags_from_vec(svec!["deno", "jupyter", "--install", "--kernel",]); + r.unwrap_err(); + } } -- cgit v1.2.3