Skip to content

Commit

Permalink
feat(unstable): deno add subcommand (#22520)
Browse files Browse the repository at this point in the history
This commit adds "deno add" subcommand that has a basic support for
adding "jsr:" packages to "deno.json" file. 

This currently doesn't support "npm:" specifiers and specifying version
constraints.
  • Loading branch information
bartlomieju committed Feb 29, 2024
1 parent a9aef0d commit fb31ae7
Show file tree
Hide file tree
Showing 16 changed files with 492 additions and 17 deletions.
71 changes: 68 additions & 3 deletions cli/args/flags.rs
Expand Up @@ -35,6 +35,11 @@ pub struct FileFlags {
pub include: Vec<String>,
}

#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct AddFlags {
pub packages: Vec<String>,
}

#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BenchFlags {
pub files: FileFlags,
Expand Down Expand Up @@ -307,6 +312,7 @@ pub struct PublishFlags {

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DenoSubcommand {
Add(AddFlags),
Bench(BenchFlags),
Bundle(BundleFlags),
Cache(CacheFlags),
Expand Down Expand Up @@ -760,9 +766,9 @@ impl Flags {
| Test(_) | Bench(_) | Repl(_) | Compile(_) | Publish(_) => {
std::env::current_dir().ok()
}
Bundle(_) | Completions(_) | Doc(_) | Fmt(_) | Init(_) | Install(_)
| Uninstall(_) | Jupyter(_) | Lsp | Lint(_) | Types | Upgrade(_)
| Vendor(_) => None,
Add(_) | Bundle(_) | Completions(_) | Doc(_) | Fmt(_) | Init(_)
| Install(_) | Uninstall(_) | Jupyter(_) | Lsp | Lint(_) | Types
| Upgrade(_) | Vendor(_) => None,
}
}

Expand Down Expand Up @@ -923,6 +929,7 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::error::Result<Flags> {

if let Some((subcommand, mut m)) = matches.remove_subcommand() {
match subcommand.as_str() {
"add" => add_parse(&mut flags, &mut m),
"bench" => bench_parse(&mut flags, &mut m),
"bundle" => bundle_parse(&mut flags, &mut m),
"cache" => cache_parse(&mut flags, &mut m),
Expand Down Expand Up @@ -1078,6 +1085,7 @@ fn clap_root() -> Command {
.subcommand(run_subcommand())
.defer(|cmd| {
cmd
.subcommand(add_subcommand())
.subcommand(bench_subcommand())
.subcommand(bundle_subcommand())
.subcommand(cache_subcommand())
Expand Down Expand Up @@ -1107,6 +1115,30 @@ fn clap_root() -> Command {
.after_help(ENV_VARIABLES_HELP)
}

fn add_subcommand() -> Command {
Command::new("add")
.about("Add dependencies")
.long_about(
"Add dependencies to the configuration file.
deno add @std/path
You can add multiple dependencies at once:
deno add @std/path @std/assert
",
)
.defer(|cmd| {
cmd.arg(
Arg::new("packages")
.help("List of packages to add")
.required(true)
.num_args(1..)
.action(ArgAction::Append),
)
})
}

fn bench_subcommand() -> Command {
Command::new("bench")
.about("Run benchmarks")
Expand Down Expand Up @@ -3218,6 +3250,11 @@ fn unsafely_ignore_certificate_errors_arg() -> Arg {
.value_parser(flags_net::validator)
}

fn add_parse(flags: &mut Flags, matches: &mut ArgMatches) {
let packages = matches.remove_many::<String>("packages").unwrap().collect();
flags.subcommand = DenoSubcommand::Add(AddFlags { packages });
}

fn bench_parse(flags: &mut Flags, matches: &mut ArgMatches) {
flags.type_check_mode = TypeCheckMode::Local;

Expand Down Expand Up @@ -8599,4 +8636,32 @@ mod tests {
}
);
}

#[test]
fn add_subcommand() {
let r = flags_from_vec(svec!["deno", "add"]);
r.unwrap_err();

let r = flags_from_vec(svec!["deno", "add", "@david/which"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Add(AddFlags {
packages: svec!["@david/which"],
}),
..Flags::default()
}
);

let r = flags_from_vec(svec!["deno", "add", "@david/which", "@luca/hello"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Add(AddFlags {
packages: svec!["@david/which", "@luca/hello"],
}),
..Flags::default()
}
);
}
}
4 changes: 2 additions & 2 deletions cli/lsp/mod.rs
Expand Up @@ -21,7 +21,7 @@ mod completions;
mod config;
mod diagnostics;
mod documents;
mod jsr;
pub mod jsr;
pub mod language_server;
mod logging;
mod lsp_custom;
Expand All @@ -32,7 +32,7 @@ mod performance;
mod refactor;
mod registries;
mod repl;
mod search;
pub mod search;
mod semantic_tokens;
mod testing;
mod text;
Expand Down
3 changes: 3 additions & 0 deletions cli/main.rs
Expand Up @@ -88,6 +88,9 @@ fn spawn_subcommand<F: Future<Output = T> + 'static, T: SubcommandOutput>(

async fn run_subcommand(flags: Flags) -> Result<i32, AnyError> {
let handle = match flags.subcommand.clone() {
DenoSubcommand::Add(add_flags) => spawn_subcommand(async {
tools::registry::add(flags, add_flags).await
}),
DenoSubcommand::Bench(bench_flags) => spawn_subcommand(async {
if bench_flags.watch.is_some() {
tools::bench::run_benchmarks_with_watch(flags, bench_flags).await
Expand Down
2 changes: 2 additions & 0 deletions cli/tools/registry/mod.rs
Expand Up @@ -50,13 +50,15 @@ mod auth;
mod diagnostics;
mod graph;
mod paths;
mod pm;
mod provenance;
mod publish_order;
mod tar;
mod unfurl;

use auth::get_auth_method;
use auth::AuthMethod;
pub use pm::add;
use publish_order::PublishOrderGraph;
pub use unfurl::deno_json_deps;
use unfurl::SpecifierUnfurler;
Expand Down

0 comments on commit fb31ae7

Please sign in to comment.