diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 39db12b5f1b855..5d98b9c18b2231 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -221,6 +221,7 @@ impl FmtFlags { #[derive(Clone, Debug, Eq, PartialEq)] pub struct InitFlags { + pub package: Option, pub dir: Option, pub lib: bool, pub serve: bool, @@ -4652,6 +4653,8 @@ fn fmt_parse( fn init_parse(flags: &mut Flags, matches: &mut ArgMatches) { flags.subcommand = DenoSubcommand::Init(InitFlags { + // TODO: + package: None, dir: matches.remove_one::("dir"), lib: matches.get_flag("lib"), serve: matches.get_flag("serve"), @@ -10600,6 +10603,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: None, lib: false, serve: false, @@ -10613,6 +10617,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: Some(String::from("foo")), lib: false, serve: false, @@ -10626,6 +10631,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: None, lib: false, serve: false, @@ -10640,6 +10646,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: None, lib: true, serve: false, @@ -10653,6 +10660,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: None, lib: false, serve: true, @@ -10666,6 +10674,7 @@ mod tests { r.unwrap(), Flags { subcommand: DenoSubcommand::Init(InitFlags { + package: None, dir: Some(String::from("foo")), lib: true, serve: false, @@ -10673,6 +10682,26 @@ mod tests { ..Flags::default() } ); + + let r = flags_from_vec(svec!["deno", "init", "npm:vite", "--lib"]); + assert!(r.is_err()); + + let r = flags_from_vec(svec!["deno", "init", "npm:vite", "--serve"]); + assert!(r.is_err()); + + let r = flags_from_vec(svec!["deno", "init", "npm:vite", "new_dir"]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Init(InitFlags { + package: Some("npm:vite".to_string()), + dir: Some(String::from("new_dir")), + lib: true, + serve: false, + }), + ..Flags::default() + } + ); } #[test] diff --git a/cli/args/mod.rs b/cli/args/mod.rs index ec75d7a100b157..0649f7c017a578 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -1621,8 +1621,9 @@ impl CliOptions { DenoSubcommand::Install(_) | DenoSubcommand::Add(_) | DenoSubcommand::Remove(_) + | DenoSubcommand::Init(_) ) { - // For `deno install/add/remove` we want to force the managed resolver so it can set up `node_modules/` directory. + // For `deno install/add/remove/init` we want to force the managed resolver so it can set up `node_modules/` directory. return false; } if self.node_modules_dir().ok().flatten().is_none() diff --git a/cli/main.rs b/cli/main.rs index 7d3ef0e6a0563a..80230d463f5098 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -35,7 +35,11 @@ use crate::util::display; use crate::util::v8::get_v8_flags_from_env; use crate::util::v8::init_v8_flags; +use args::PackagesAllowedScripts; +use args::PermissionFlags; +use args::RunFlags; use args::TaskFlags; +use deno_core::anyhow::bail; use deno_resolver::npm::ByonmResolvePkgFolderFromDenoReqError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::WorkerExecutionMode; @@ -143,6 +147,14 @@ async fn run_subcommand(flags: Arc) -> Result { ) } DenoSubcommand::Init(init_flags) => { + if let Some(dir) = &init_flags.dir { + if dir.starts_with("jsr:") { + bail!("Initializing project from a jsr package is currently not supported."); + } else if dir.starts_with("npm:") { + return tools::init::init_npm(dir).await; + } + } + spawn_subcommand(async { // make compiler happy since init_project is sync tokio::task::yield_now().await; diff --git a/cli/tools/init/mod.rs b/cli/tools/init/mod.rs index 4e4a686c5f2d7b..5ed1538cb6af83 100644 --- a/cli/tools/init/mod.rs +++ b/cli/tools/init/mod.rs @@ -1,10 +1,16 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use crate::args::DenoSubcommand; +use crate::args::Flags; use crate::args::InitFlags; +use crate::args::PackagesAllowedScripts; +use crate::args::PermissionFlags; +use crate::args::RunFlags; use crate::colors; use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::serde_json::json; +use deno_runtime::WorkerExecutionMode; use log::info; use std::io::Write; use std::path::Path; @@ -238,6 +244,33 @@ Deno.test(function addTest() { Ok(()) } +pub async fn init_npm(name: &str) -> Result { + // TODO: do prompt + let script_name = + format!("npm:create-{}", name.strip_prefix("npm:").unwrap()); + + let new_flags = Flags { + permissions: PermissionFlags { + allow_all: true, + ..Default::default() + }, + allow_scripts: PackagesAllowedScripts::All, + // TODO: + argv: vec![], + subcommand: DenoSubcommand::Run(RunFlags { + script: script_name, + ..Default::default() + }), + ..Default::default() + }; + crate::tools::run::run_script( + WorkerExecutionMode::Run, + new_flags.into(), + None, + ) + .await +} + fn create_json_file( dir: &Path, filename: &str,