Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(add/install): Flag to add dev dependency to package.json #25495

Merged
merged 3 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 62 additions & 26 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl FileFlags {
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct AddFlags {
pub packages: Vec<String>,
pub dev: bool,
}

#[derive(Clone, Debug, Default, Eq, PartialEq)]
Expand Down Expand Up @@ -1585,6 +1586,15 @@ fn help_subcommand(app: &Command) -> Command {
}))
}

fn add_dev_arg() -> Arg {
Arg::new("dev")
nathanwhit marked this conversation as resolved.
Show resolved Hide resolved
.long("dev")
.short('D')
.help("Add as a dev dependency")
.long_help("Add the package as a dev dependency. Note: This only applies when adding to a `package.json` file.")
.action(ArgAction::SetTrue)
}

fn add_subcommand() -> Command {
command(
"add",
Expand All @@ -1598,13 +1608,15 @@ You can add multiple dependencies at once:
UnstableArgsConfig::None,
)
.defer(|cmd| {
cmd.arg(
Arg::new("packages")
.help("List of packages to add")
.required_unless_present("help")
.num_args(1..)
.action(ArgAction::Append),
)
cmd
.arg(
Arg::new("packages")
.help("List of packages to add")
.required_unless_present("help")
.num_args(1..)
.action(ArgAction::Append),
)
.arg(add_dev_arg())
})
}

Expand Down Expand Up @@ -2453,6 +2465,7 @@ These must be added to the path manually if required."), UnstableArgsConfig::Res
.help("Install dependents of the specified entrypoint(s)"),
)
.arg(env_file_arg())
.arg(add_dev_arg().conflicts_with("entrypoint").conflicts_with("global"))
})
}

Expand Down Expand Up @@ -4091,7 +4104,8 @@ fn add_parse_inner(
let packages = packages
.unwrap_or_else(|| matches.remove_many::<String>("packages").unwrap())
.collect();
AddFlags { packages }
let dev = matches.get_flag("dev");
AddFlags { packages, dev }
}

fn remove_parse(flags: &mut Flags, matches: &mut ArgMatches) {
Expand Down Expand Up @@ -10509,31 +10523,53 @@ mod tests {
}

#[test]
fn add_subcommand() {
fn add_or_install_subcommand() {
let r = flags_from_vec(svec!["deno", "add"]);
r.unwrap_err();
for cmd in ["add", "install"] {
let mk_flags = |flags: AddFlags| -> Flags {
match cmd {
"add" => Flags {
subcommand: DenoSubcommand::Add(flags),
..Flags::default()
},
"install" => Flags {
subcommand: DenoSubcommand::Install(InstallFlags {
kind: InstallKind::Local(InstallFlagsLocal::Add(flags)),
}),
..Flags::default()
},
_ => unreachable!(),
}
};

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

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

let r = flags_from_vec(svec!["deno", cmd, "--dev", "npm:chalk"]);
assert_eq!(
r.unwrap(),
mk_flags(AddFlags {
packages: svec!["npm:chalk"],
dev: true,
}),
..Flags::default()
}
);
);
}
}

#[test]
Expand Down
9 changes: 5 additions & 4 deletions cli/tools/registry/pm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ pub async fn add(
}
}

let dev = add_flags.dev;
for selected_package in selected_packages {
log::info!(
"Add {}{}{}",
Expand All @@ -512,14 +513,14 @@ pub async fn add(

if selected_package.package_name.starts_with("npm:") {
if let Some(npm) = &mut npm_config {
npm.add(selected_package, false);
npm.add(selected_package, dev);
} else {
deno_config.as_mut().unwrap().add(selected_package, false);
deno_config.as_mut().unwrap().add(selected_package, dev);
}
} else if let Some(deno) = &mut deno_config {
deno.add(selected_package, false);
deno.add(selected_package, dev);
} else {
npm_config.as_mut().unwrap().add(selected_package, false);
npm_config.as_mut().unwrap().add(selected_package, dev);
}
}

Expand Down
39 changes: 39 additions & 0 deletions tests/specs/add/dev/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"tempDir": true,
"tests": {
"package_json": {
"steps": [
{
"args": "add --dev npm:@denotest/esm-basic",
"output": "add.out"
},
{
"args": [
"eval",
"console.log(Deno.readTextFileSync('package.json').trim())"
],
"output": "package.json.out"
}
]
},
"deno_json": {
"steps": [
{
"args": ["eval", "Deno.removeSync('package.json')"],
"output": ""
},
{
"args": "add --dev npm:@denotest/esm-basic",
"output": "add.out"
},
{
"args": [
"eval",
"console.log(Deno.readTextFileSync('deno.json').trim())"
],
"output": "deno.json.out"
}
]
}
}
}
4 changes: 4 additions & 0 deletions tests/specs/add/dev/add.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add npm:@denotest/esm-basic@1.0.0
Download http://localhost:4260/@denotest/esm-basic
Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz
Initialize @denotest/esm-basic@1.0.0
3 changes: 3 additions & 0 deletions tests/specs/add/dev/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"nodeModulesDir": "manual"
}
6 changes: 6 additions & 0 deletions tests/specs/add/dev/deno.json.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"nodeModulesDir": "manual",
"imports": {
"@denotest/esm-basic": "npm:@denotest/esm-basic@^1.0.0"
}
}
3 changes: 3 additions & 0 deletions tests/specs/add/dev/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"devDependencies": { "@denotest/esm-basic": "^1.0.0" }
}
3 changes: 3 additions & 0 deletions tests/specs/add/dev/package.json.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"devDependencies": { "@denotest/esm-basic": "^1.0.0" }
}
16 changes: 16 additions & 0 deletions tests/specs/install/install_add_dev/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"tempDir": true,
"steps": [
{
"args": "install --dev npm:@denotest/esm-basic",
"output": "install.out"
},
{
"args": [
"eval",
"console.log(Deno.readTextFileSync('package.json').trim())"
],
"output": "package.json.out"
}
]
}
4 changes: 4 additions & 0 deletions tests/specs/install/install_add_dev/install.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add npm:@denotest/esm-basic@1.0.0
Download http://localhost:4260/@denotest/esm-basic
Download http://localhost:4260/@denotest/esm-basic/1.0.0.tgz
Initialize @denotest/esm-basic@1.0.0
3 changes: 3 additions & 0 deletions tests/specs/install/install_add_dev/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"devDependencies": { "@denotest/esm-basic": "^1.0.0" }
}
3 changes: 3 additions & 0 deletions tests/specs/install/install_add_dev/package.json.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"devDependencies": { "@denotest/esm-basic": "^1.0.0" }
}