From da366cd7044edac212e4ce831097a7df65990366 Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 22:36:11 +0900 Subject: [PATCH 1/6] fix(pm): enforce package manager option compatibility Reject unsupported npm, pnpm, Yarn, and Bun options before execution. Use the supported Yarn script-skipping flags and preserve older Bun workspace filtering in interactive updates. Allow pnpm why finders without positional package names. Update existing resolver tests and CLI snapshots for the corrected behavior. --- .../snapshots/cli_helper_message.md | 6 +- .../snapshots/command_add_pnpm9.md | 3 +- .../command_add_pnpm9_with_workspace.md | 8 +-- .../snapshots/command_why_bun.md | 4 +- .../snapshots/command_why_pnpm10.global.md | 4 +- .../snapshots/command_why_pnpm10.local.md | 4 +- .../snapshots/command_why_pnpm11.md | 4 +- .../snapshots/npm_install_with_options.md | 2 +- .../snapshots/yarn_install_with_options.md | 2 +- .../vp_pm_cli/src/resolution/commands/add.rs | 22 ++++---- .../src/resolution/commands/install.rs | 32 +++++++---- .../vp_pm_cli/src/resolution/commands/list.rs | 8 +-- .../src/resolution/commands/outdated.rs | 4 +- .../vp_pm_cli/src/resolution/commands/pack.rs | 12 ++-- .../src/resolution/commands/publish.rs | 21 +++++-- .../src/resolution/commands/remove.rs | 14 ++--- .../src/resolution/commands/unlink.rs | 2 +- .../src/resolution/commands/update.rs | 55 +++++++++++-------- .../vp_pm_cli/src/resolution/commands/why.rs | 10 ++-- 19 files changed, 119 insertions(+), 98 deletions(-) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md index 79254b603c..fafb93fa88 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md @@ -117,7 +117,7 @@ Options: -f, --force Force reinstall all dependencies --ignore-scripts Do not run lifecycle scripts --no-lockfile Don't read or generate lockfile - --fix-lockfile Fix broken lockfile entries (pnpm and yarn@2+ only) + --fix-lockfile Fix broken lockfile entries (pnpm and yarn@4+ only) --shamefully-hoist Create flat `node_modules` (pnpm only) --resolution-only Re-run resolution for peer dependency analysis (pnpm only) --silent Suppress output (silent mode) @@ -349,12 +349,12 @@ show why help message ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] Show why a package is installed Arguments: - ... Package(s) to check + [PACKAGES]... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9/snapshots/command_add_pnpm9.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9/snapshots/command_add_pnpm9.md index a5df7fedb3..a0e7e921a1 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9/snapshots/command_add_pnpm9.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9/snapshots/command_add_pnpm9.md @@ -106,8 +106,7 @@ should error because allow-build is not supported at pnpm@9 **Exit code:** 1 ``` - ERROR  Unknown option: 'allow-build' -For help, run: pnpm help add +pnpm < 10.4.0 does not support --allow-build. ``` ## `vp install test-vite-plus-package@1.0.0 --save-peer` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md index 2e91b4d02a..b52e23a15e 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md @@ -203,9 +203,7 @@ should error because save-catalog-name is not supported at pnpm@9 **Exit code:** 1 ``` - ERROR  Unknown option: 'save-catalog-name' -Did you mean 'save-optional'? Use "--config.unknown=value" to force an unknown option. -For help, run: pnpm help add +pnpm < 10.12.0 does not support --save-catalog-name. ``` ## `vp add --filter=./packages/utils test-vite-plus-package-optional -O --save-catalog v2` @@ -215,7 +213,5 @@ should error because save-catalog is not supported at pnpm@9 **Exit code:** 1 ``` - ERROR  Unknown option: 'save-catalog' -Did you mean 'save-exact', or 'save-prod'? Use "--config.unknown=value" to force an unknown option. -For help, run: pnpm help add +pnpm < 10.12.0 does not support --save-catalog. ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md index c88115ad51..3c8d74cec6 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] Show why a package is installed Arguments: - ... Package(s) to check + [PACKAGES]... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md index 98e7f1bb66..e3aa8f400f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] Show why a package is installed Arguments: - ... Package(s) to check + [PACKAGES]... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md index 640cac2508..0ba979faa9 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md @@ -7,10 +7,10 @@ should show help ``` Show why a package is installed -Usage: vp why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] Arguments: - ... Package(s) to check + [PACKAGES]... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md index 94c8888a1f..7aac46dc18 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] ... [-- ...] +Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] Show why a package is installed Arguments: - ... Package(s) to check + [PACKAGES]... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md index 88393ea14b..2aad8cc979 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md @@ -25,7 +25,7 @@ Options: -f, --force Force reinstall all dependencies --ignore-scripts Do not run lifecycle scripts --no-lockfile Don't read or generate lockfile - --fix-lockfile Fix broken lockfile entries (pnpm and yarn@2+ only) + --fix-lockfile Fix broken lockfile entries (pnpm and yarn@4+ only) --shamefully-hoist Create flat `node_modules` (pnpm only) --resolution-only Re-run resolution for peer dependency analysis (pnpm only) --silent Suppress output (silent mode) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md index 9bd3373a98..ded964df8c 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md @@ -25,7 +25,7 @@ Options: -f, --force Force reinstall all dependencies --ignore-scripts Do not run lifecycle scripts --no-lockfile Don't read or generate lockfile - --fix-lockfile Fix broken lockfile entries (pnpm and yarn@2+ only) + --fix-lockfile Fix broken lockfile entries (pnpm and yarn@4+ only) --shamefully-hoist Create flat `node_modules` (pnpm only) --resolution-only Re-run resolution for peer dependency analysis (pnpm only) --silent Suppress output (silent mode) diff --git a/crates/vp_pm_cli/src/resolution/commands/add.rs b/crates/vp_pm_cli/src/resolution/commands/add.rs index f2518be19d..5d77e989a4 100644 --- a/crates/vp_pm_cli/src/resolution/commands/add.rs +++ b/crates/vp_pm_cli/src/resolution/commands/add.rs @@ -16,19 +16,19 @@ pub struct AddArgs { pub(crate) save_exact: bool, /// Save the new dependency to the specified catalog name - #[arg(long, value_name = "CATALOG_NAME", not_supported(npm, yarn, bun < "1.4"))] + #[arg(long, value_name = "CATALOG_NAME", not_supported(npm, pnpm < "10.12.0", yarn, bun < "1.4"))] pub(crate) save_catalog_name: Option, /// Save the new dependency to the default catalog - #[arg(long, not_supported(npm, yarn, bun < "1.4"))] + #[arg(long, not_supported(npm, pnpm < "10.12.0", yarn, bun < "1.4"))] pub(crate) save_catalog: bool, /// A list of package names allowed to run postinstall - #[arg(long, value_name = "NAMES", not_supported(npm, yarn, bun))] + #[arg(long, value_name = "NAMES", not_supported(npm, pnpm < "10.4.0", yarn, bun))] pub(crate) allow_build: Option, /// Do not run lifecycle scripts - #[arg(long)] + #[arg(long, not_supported(yarn >= "2" && < "3"))] pub(crate) ignore_scripts: bool, /// Do not install optionalDependencies @@ -82,11 +82,11 @@ pub struct AddArgs { pub(crate) silent: bool, /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN", not_supported(yarn < "2", bun < "1.4"))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn < "2", bun < "1.4"))] pub(crate) filter: Vec, /// Add to workspace root - #[arg(short = 'w', long, not_supported(yarn >= "2", bun))] + #[arg(short = 'w', long, not_supported(npm < "8.1.0", yarn >= "2", bun))] pub(crate) workspace_root: bool, /// Only add if package exists in workspace (pnpm-specific) @@ -293,7 +293,7 @@ impl Resolve for Yarn { } cmd.arg_if("--exact", args.save_exact); if self.is_berry() { - Self::apply_berry_install_mode(&mut cmd, args.lockfile_only, args.ignore_scripts, diag); + self.apply_berry_install_mode(&mut cmd, args.lockfile_only, args.ignore_scripts, diag); } else { cmd.arg_if("--frozen-lockfile", args.frozen_lockfile) .arg_if("--ignore-scripts", args.ignore_scripts) @@ -412,7 +412,7 @@ mod tests { let mut options = add_args(&["react"]); options.filter = vec!["app".to_string()]; options.save_catalog_name = Some("react18".to_string()); - let resolution = resolve(&pnpm("10.0.0"), options); + let resolution = resolve(&pnpm("10.12.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "pnpm"); @@ -427,7 +427,7 @@ mod tests { let mut options = add_args(&["react"]); options.filter = vec!["app".to_string()]; options.save_catalog_name = Some(String::new()); - let resolution = resolve(&pnpm("10.0.0"), options); + let resolution = resolve(&pnpm("10.12.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "pnpm"); @@ -439,7 +439,7 @@ mod tests { let mut options = add_args(&["react"]); options.filter = vec!["app".to_string()]; options.save_catalog = true; - let resolution = resolve(&pnpm("10.0.0"), options); + let resolution = resolve(&pnpm("10.12.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "pnpm"); @@ -653,7 +653,7 @@ mod tests { fn test_pnpm_add_with_allow_build() { let mut options = add_args(&["react"]); options.allow_build = Some("react,napi".to_string()); - let resolution = resolve(&pnpm("10.0.0"), options); + let resolution = resolve(&pnpm("10.4.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "pnpm"); diff --git a/crates/vp_pm_cli/src/resolution/commands/install.rs b/crates/vp_pm_cli/src/resolution/commands/install.rs index f2229b07be..f63e5f99d1 100644 --- a/crates/vp_pm_cli/src/resolution/commands/install.rs +++ b/crates/vp_pm_cli/src/resolution/commands/install.rs @@ -4,8 +4,9 @@ use super::parse_positive_usize; use crate::{ Error, PackageManager, resolution::{ - AddArgs, Bun, CommandBuilder, CommandResolution, DiagnosticKind, Diagnostics, Npm, Pnpm, - Resolution, Resolve, SaveDependencyArgs, Yarn, resolve_for_manager, + AddArgs, Bun, CommandBuilder, CommandResolution, DiagnosticKind, Diagnostics, Npm, + PackageManagerDialect, Pnpm, Resolution, Resolve, SaveDependencyArgs, Yarn, + resolve_for_manager, }, }; @@ -51,15 +52,15 @@ pub struct InstallArgs { pub(crate) force: bool, /// Do not run lifecycle scripts - #[arg(long)] + #[arg(long, not_supported(yarn >= "2" && < "2.4.0"))] pub(crate) ignore_scripts: bool, /// Don't read or generate lockfile #[arg(long, not_supported(yarn >= "2", bun))] pub(crate) no_lockfile: bool, - /// Fix broken lockfile entries (pnpm and yarn@2+ only) - #[arg(long, not_supported(npm, bun, yarn < "2"))] + /// Fix broken lockfile entries (pnpm and yarn@4+ only) + #[arg(long, not_supported(npm, bun, yarn < "4.0.0"))] pub(crate) fix_lockfile: bool, /// Create flat `node_modules` (pnpm only) @@ -75,11 +76,11 @@ pub struct InstallArgs { pub(crate) silent: bool, /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN", not_supported(yarn < "2"))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn < "2"))] pub(crate) filter: Vec, /// Install in workspace root only - #[arg(short = 'w', long, not_supported(yarn, bun))] + #[arg(short = 'w', long, not_supported(npm < "8.1.0", yarn, bun))] pub(crate) workspace_root: bool, /// Save exact version (only when adding packages) @@ -262,7 +263,7 @@ impl Resolve for Npm { impl Resolve for Yarn { fn resolve(&self, args: &InstallArgs, diag: &mut Diagnostics) -> CommandResolution { if self.is_berry() { - Yarn::resolve_berry_install(args, diag) + self.resolve_berry_install(args, diag) } else { Yarn::resolve_v1_install(args, diag) } @@ -291,7 +292,11 @@ impl Yarn { cmd.into() } - fn resolve_berry_install(args: &InstallArgs, diag: &mut Diagnostics) -> CommandResolution { + fn resolve_berry_install( + &self, + args: &InstallArgs, + diag: &mut Diagnostics, + ) -> CommandResolution { let mut cmd = CommandBuilder::new("yarn"); if !args.filter.is_empty() { cmd.arg("workspaces").arg("foreach").arg("-A"); @@ -303,7 +308,7 @@ impl Yarn { } else { cmd.arg_if("--immutable", args.frozen_lockfile); } - Self::apply_berry_install_mode(&mut cmd, args.lockfile_only, args.ignore_scripts, diag); + self.apply_berry_install_mode(&mut cmd, args.lockfile_only, args.ignore_scripts, diag); if args.prod { diag.warn( DiagnosticKind::BehaviorChange, @@ -315,6 +320,7 @@ impl Yarn { } pub(super) fn apply_berry_install_mode( + &self, cmd: &mut CommandBuilder, lockfile_only: bool, ignore_scripts: bool, @@ -329,7 +335,11 @@ impl Yarn { ); } } else if ignore_scripts { - cmd.arg("--mode").arg("skip-build"); + if self.version().is_some_and(|version| version.major == 2) { + cmd.arg("--skip-builds"); + } else { + cmd.arg("--mode").arg("skip-build"); + } } } } diff --git a/crates/vp_pm_cli/src/resolution/commands/list.rs b/crates/vp_pm_cli/src/resolution/commands/list.rs index 9bf6ddfe15..d2ca54016b 100644 --- a/crates/vp_pm_cli/src/resolution/commands/list.rs +++ b/crates/vp_pm_cli/src/resolution/commands/list.rs @@ -47,15 +47,15 @@ pub struct ListArgs { pub(crate) only_projects: bool, /// Use a finder function - #[arg(long, value_name = "FINDER_NAME", not_supported(npm, yarn, bun))] + #[arg(long, value_name = "FINDER_NAME", not_supported(npm, pnpm < "10.16.0", yarn, bun))] pub(crate) find_by: Option, /// List across all workspaces - #[arg(short = 'r', long, not_supported(yarn, bun))] + #[arg(short = 'r', long, not_supported(npm < "7.14.0", yarn, bun))] pub(crate) recursive: bool, /// Filter packages in monorepo - #[arg(long, value_name = "PATTERN", not_supported(yarn, bun))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn, bun))] pub(crate) filter: Vec, /// List global packages @@ -550,7 +550,7 @@ mod tests { fn test_pnpm_list_find_by() { let command = expect_run( resolve( - &pnpm("10.0.0"), + &pnpm("10.16.0"), ListArgs { find_by: Some("customFinder".to_string()), ..Default::default() }, ) .outcome, diff --git a/crates/vp_pm_cli/src/resolution/commands/outdated.rs b/crates/vp_pm_cli/src/resolution/commands/outdated.rs index 304df51699..d5dc701f96 100644 --- a/crates/vp_pm_cli/src/resolution/commands/outdated.rs +++ b/crates/vp_pm_cli/src/resolution/commands/outdated.rs @@ -64,11 +64,11 @@ pub struct OutdatedArgs { pub(crate) recursive: bool, /// Filter packages in monorepo - #[arg(long, value_name = "PATTERN", not_supported(yarn))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn))] pub(crate) filter: Vec, /// Include workspace root - #[arg(short = 'w', long, not_supported(yarn, bun))] + #[arg(short = 'w', long, not_supported(npm < "8.1.0", yarn, bun))] pub(crate) workspace_root: bool, /// Only production and optional dependencies diff --git a/crates/vp_pm_cli/src/resolution/commands/pack.rs b/crates/vp_pm_cli/src/resolution/commands/pack.rs index 2b0fd357b0..cb197165d1 100644 --- a/crates/vp_pm_cli/src/resolution/commands/pack.rs +++ b/crates/vp_pm_cli/src/resolution/commands/pack.rs @@ -8,11 +8,11 @@ use crate::resolution::{ #[derive(clap::Args, Clone, Debug, Default, PartialEq, Eq)] pub struct PackArgs { /// Pack all workspace packages - #[arg(short = 'r', long, not_supported(yarn < "2", bun))] + #[arg(short = 'r', long, not_supported(npm < "7.9.0", pnpm < "10.11.0", yarn < "2", bun))] pub(crate) recursive: bool, /// Filter packages to pack - #[arg(long, value_name = "PATTERN", not_supported(yarn < "2", bun))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.9.0", pnpm < "10.11.0", yarn < "2", bun))] pub(crate) filter: Vec, /// Output path for the tarball @@ -20,7 +20,7 @@ pub struct PackArgs { pub(crate) out: Option, /// Directory where the tarball will be saved - #[arg(long, not_supported(yarn))] + #[arg(long, not_supported(npm < "7.18.0", yarn))] pub(crate) pack_destination: Option, /// Gzip compression level (0-9) @@ -128,7 +128,7 @@ mod tests { #[test] fn test_pnpm_pack_recursive() { let command = expect_run( - resolve(&pnpm("10.0.0"), PackArgs { recursive: true, ..Default::default() }).outcome, + resolve(&pnpm("10.11.0"), PackArgs { recursive: true, ..Default::default() }).outcome, ); assert_eq!(command.args, vec!["pack", "--recursive"]); @@ -194,7 +194,7 @@ mod tests { fn test_pnpm_pack_with_filter() { let command = expect_run( resolve( - &pnpm("10.0.0"), + &pnpm("10.11.0"), PackArgs { filter: vec!["app".to_string()], ..Default::default() }, ) .outcome, @@ -207,7 +207,7 @@ mod tests { fn test_pnpm_pack_with_multiple_filters() { let command = expect_run( resolve( - &pnpm("10.0.0"), + &pnpm("10.11.0"), PackArgs { filter: vec!["app".to_string(), "web".to_string()], ..Default::default() diff --git a/crates/vp_pm_cli/src/resolution/commands/publish.rs b/crates/vp_pm_cli/src/resolution/commands/publish.rs index 5f1e4481bf..fb219115eb 100644 --- a/crates/vp_pm_cli/src/resolution/commands/publish.rs +++ b/crates/vp_pm_cli/src/resolution/commands/publish.rs @@ -1,7 +1,8 @@ use vp_pm_cli_macros::pm_args; use crate::resolution::{ - Bun, CommandBuilder, CommandResolution, Diagnostics, Npm, Pnpm, Resolve, Yarn, + Bun, CommandBuilder, CommandResolution, Diagnostics, Npm, PackageManagerDialect, Pnpm, Resolve, + Yarn, }; #[pm_args] @@ -12,7 +13,8 @@ pub struct PublishArgs { pub(crate) target: Option, /// Preview without publishing - #[arg(long, not_supported(yarn < "4.9.3"))] + // npm 5.8 ignores this flag and publishes; stable 5.10 supports previews. + #[arg(long, not_supported(npm < "5.10.0", yarn < "4.9.3"))] pub(crate) dry_run: bool, /// Publish tag @@ -40,7 +42,7 @@ pub struct PublishArgs { pub(crate) report_summary: bool, /// Publish with provenance - #[arg(long, not_supported(yarn < "4.9.0", bun))] + #[arg(long, not_supported(npm < "9.5.0", yarn < "4.9.0", bun))] pub(crate) provenance: bool, /// Force publish @@ -48,15 +50,17 @@ pub struct PublishArgs { pub(crate) force: bool, /// Output in JSON format - #[arg(long, not_supported(yarn >= "2" && < "4.9.3", bun))] + // pnpm 11's native publish dropped JSON output until 11.0.7 restored it. + // https://github.com/pnpm/pnpm/releases/tag/v11.0.7 + #[arg(long, not_supported(pnpm >= "11.0.0" && < "11.0.7", yarn >= "2" && < "4.9.3", bun))] pub(crate) json: bool, /// Publish all workspace packages - #[arg(short = 'r', long, not_supported(yarn, bun))] + #[arg(short = 'r', long, not_supported(npm < "7.13.0", yarn, bun))] pub(crate) recursive: bool, /// Filter packages in monorepo - #[arg(long, value_name = "PATTERN", not_supported(yarn, bun))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.13.0", yarn, bun))] pub(crate) filter: Option>, /// Additional arguments @@ -102,6 +106,11 @@ impl Npm { impl Resolve for Npm { fn resolve(&self, args: &PublishArgs, _diag: &mut Diagnostics) -> CommandResolution { + if self.version().is_none() && (args.dry_run || args.provenance) { + return CommandResolution::InvalidArgument( + "A known npm version is required for --dry-run and --provenance.".into(), + ); + } Self::resolve_publish(args) } } diff --git a/crates/vp_pm_cli/src/resolution/commands/remove.rs b/crates/vp_pm_cli/src/resolution/commands/remove.rs index 81f0ef8dfa..d55e6d2059 100644 --- a/crates/vp_pm_cli/src/resolution/commands/remove.rs +++ b/crates/vp_pm_cli/src/resolution/commands/remove.rs @@ -20,15 +20,15 @@ pub struct RemoveArgs { pub(crate) save_prod: bool, /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN", not_supported(bun < "1.4"))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", bun < "1.4"))] pub(crate) filter: Vec, /// Remove from workspace root - #[arg(short = 'w', long, not_supported(yarn, bun))] + #[arg(short = 'w', long, not_supported(npm < "8.1.0", yarn, bun))] pub(crate) workspace_root: bool, /// Remove recursively from all workspace packages - #[arg(short = 'r', long, not_supported(yarn < "2", bun))] + #[arg(short = 'r', long, not_supported(npm < "8.1.0", yarn < "2", bun))] pub(crate) recursive: bool, /// Remove global packages @@ -374,7 +374,7 @@ mod tests { fn test_npm_remove_with_workspace() { let mut options = remove_args(&["lodash"]); options.filter = vec!["app".to_string()]; - let resolution = resolve(&npm("1.0.0"), options); + let resolution = resolve(&npm("7.14.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "npm"); @@ -385,7 +385,7 @@ mod tests { fn test_npm_remove_workspace_root() { let mut options = remove_args(&["typescript"]); options.workspace_root = true; - let resolution = resolve(&npm("1.0.0"), options); + let resolution = resolve(&npm("8.1.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "npm"); @@ -396,7 +396,7 @@ mod tests { fn test_npm_remove_recursive() { let mut options = remove_args(&["lodash"]); options.recursive = true; - let resolution = resolve(&npm("1.0.0"), options); + let resolution = resolve(&npm("8.1.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "npm"); @@ -410,7 +410,7 @@ mod tests { fn test_npm_remove_multiple_workspaces() { let mut options = remove_args(&["lodash"]); options.filter = vec!["app".to_string(), "web".to_string()]; - let resolution = resolve(&npm("1.0.0"), options); + let resolution = resolve(&npm("7.14.0"), options); let command = expect_run(resolution.outcome); assert_eq!(command.program, "npm"); diff --git a/crates/vp_pm_cli/src/resolution/commands/unlink.rs b/crates/vp_pm_cli/src/resolution/commands/unlink.rs index 4573234db4..3ccc6aa2a8 100644 --- a/crates/vp_pm_cli/src/resolution/commands/unlink.rs +++ b/crates/vp_pm_cli/src/resolution/commands/unlink.rs @@ -14,7 +14,7 @@ pub struct UnlinkArgs { /// Unlink in every workspace package // Berry added unlink, including --all, in Yarn 3. Classic has no recursive unlink. // https://github.com/yarnpkg/berry/blob/01586a88806a2bebd7edb28d1bee3581b1fd3762/CHANGELOG.md#300 - #[arg(short = 'r', long, not_supported(yarn < "3", bun))] + #[arg(short = 'r', long, not_supported(npm < "8.1.0", yarn < "3", bun))] pub(crate) recursive: bool, /// Arguments to pass to package manager diff --git a/crates/vp_pm_cli/src/resolution/commands/update.rs b/crates/vp_pm_cli/src/resolution/commands/update.rs index 1aca6ee7ab..3b58c251f8 100644 --- a/crates/vp_pm_cli/src/resolution/commands/update.rs +++ b/crates/vp_pm_cli/src/resolution/commands/update.rs @@ -29,15 +29,15 @@ pub struct UpdateArgs { pub(crate) ignore_node_mismatch: bool, /// Update recursively in all workspace packages - #[arg(short = 'r', long, not_supported(yarn < "2"))] + #[arg(short = 'r', long, not_supported(npm < "8.1.0", yarn < "2"))] pub(crate) recursive: bool, /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN", not_supported(bun < "1.4", yarn >= "2"))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn >= "2"))] pub(crate) filter: Vec, /// Include workspace root - #[arg(short = 'w', long, not_supported(yarn, bun))] + #[arg(short = 'w', long, not_supported(npm < "8.1.0", yarn, bun))] pub(crate) workspace_root: bool, /// Update devDependencies @@ -45,7 +45,7 @@ pub struct UpdateArgs { pub(crate) dev: bool, /// Update dependencies (production) - #[arg(short = 'P', long, not_supported(yarn >= "2"))] + #[arg(short = 'P', long, not_supported(yarn >= "2", bun < "1.4"))] pub(crate) prod: bool, /// Interactive mode @@ -53,7 +53,7 @@ pub struct UpdateArgs { pub(crate) interactive: bool, /// Exclude optionalDependencies - #[arg(long, not_supported(yarn >= "2"))] + #[arg(long, not_supported(yarn >= "2", bun < "1.4"))] pub(crate) no_optional: bool, /// Update lockfile only, don't modify package.json @@ -162,6 +162,20 @@ impl Yarn { impl Resolve for Bun { fn resolve(&self, args: &UpdateArgs, _diag: &mut Diagnostics) -> CommandResolution { + if !self.supports_v1_4_commands() && !args.interactive { + for (option, active) in + [("--recursive", args.recursive), ("--filter", !args.filter.is_empty())] + { + if active { + return CommandResolution::InvalidArgument( + vt_str::format!( + "bun < 1.4 does not support {option} without --interactive." + ) + .to_string(), + ); + } + } + } let mut cmd = CommandBuilder::new("bun"); cmd.arg("update") .repeated("--filter", args.filter.iter()) @@ -169,14 +183,8 @@ impl Resolve for Bun { .arg_if("--dev", args.dev) .arg_if("--interactive", args.interactive) .arg_if("--production", args.prod); - if args.no_optional { - if self.supports_v1_4_commands() { - cmd.arg("--no-optional"); - } else { - cmd.arg("--omit").arg("optional"); - } - } - cmd.arg_if("--no-save", args.no_save) + cmd.arg_if("--no-optional", args.no_optional) + .arg_if("--no-save", args.no_save) .arg_if("--recursive", args.recursive) .extend(args.pass_through_args.iter()) .extend(args.packages.iter()); @@ -795,25 +803,21 @@ mod tests { expect_unsupported( resolve(&bun("1.3.14"), args), &[ - "bun < 1.4 does not support --filter.", "bun does not support --workspace-root.", "bun < 1.4 does not support --dev.", + "bun < 1.4 does not support --prod.", + "bun < 1.4 does not support --no-optional.", ], ); } #[test] fn test_bun_update_prod_and_optional_selection() { - for version in ["1.3.14", "1.4.0-beta.1", "1.4.0"] { - let optional_flags = - if version == "1.4.0" { vec!["--no-optional"] } else { vec!["--omit", "optional"] }; + for version in ["1.4.0", "1.4.1"] { for (flags, expected) in [ (vec!["-P"], vec!["update", "--production"]), - (vec!["--no-optional"], [vec!["update"], optional_flags.clone()].concat()), - ( - vec!["-P", "--no-optional"], - [vec!["update", "--production"], optional_flags].concat(), - ), + (vec!["--no-optional"], vec!["update", "--no-optional"]), + (vec!["-P", "--no-optional"], vec!["update", "--production", "--no-optional"]), ] { let args = parse_args::(flags).unwrap(); let resolution = resolve(&bun(version), args); @@ -835,7 +839,7 @@ mod tests { #[test] fn test_bun_update_recursive() { - for version in ["1.3.11", "1.4.0"] { + for version in ["1.4.0", "1.4.1"] { let options = UpdateArgs { recursive: true, ..Default::default() }; let resolution = resolve(&bun(version), options); assert!(resolution.diagnostics.is_empty()); @@ -860,6 +864,9 @@ mod tests { fn test_bun_update_rejects_filter_before_1_4() { let options = UpdateArgs { filter: vec!["web".to_string()], ..Default::default() }; let resolution = resolve(&bun("1.3.11"), options); - expect_unsupported(resolution, &["bun < 1.4 does not support --filter."]); + expect_unsupported( + resolution, + &["bun < 1.4 does not support --filter without --interactive."], + ); } } diff --git a/crates/vp_pm_cli/src/resolution/commands/why.rs b/crates/vp_pm_cli/src/resolution/commands/why.rs index 8aab65f427..e617e924c4 100644 --- a/crates/vp_pm_cli/src/resolution/commands/why.rs +++ b/crates/vp_pm_cli/src/resolution/commands/why.rs @@ -8,7 +8,7 @@ use crate::resolution::{ #[derive(clap::Args, Clone, Debug, Default, PartialEq, Eq)] pub struct WhyArgs { /// Package(s) to check - #[arg(required = true)] + #[arg(required_unless_present = "find_by")] pub(crate) packages: Vec, /// Output in JSON format @@ -24,11 +24,11 @@ pub struct WhyArgs { pub(crate) parseable: bool, /// Check recursively across all workspaces - #[arg(short = 'r', long, not_supported(yarn < "2", bun))] + #[arg(short = 'r', long, not_supported(npm < "7.14.0", yarn < "2", bun))] pub(crate) recursive: bool, /// Filter packages in monorepo - #[arg(long, value_name = "PATTERN", not_supported(yarn, bun))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn, bun))] pub(crate) filter: Vec, /// Check in workspace root @@ -56,7 +56,7 @@ pub struct WhyArgs { pub(crate) exclude_peers: bool, /// Use a finder function defined in .pnpmfile.cjs - #[arg(long, value_name = "FINDER_NAME", not_supported(npm, yarn, bun))] + #[arg(long, value_name = "FINDER_NAME", not_supported(npm, pnpm < "10.16.0", yarn, bun))] pub(crate) find_by: Option, /// Additional arguments to pass through to the package manager @@ -275,7 +275,7 @@ mod tests { fn test_pnpm_why_with_find_by() { let mut options = why_args(&["react"]); options.find_by = Some("customFinder".to_string()); - let command = expect_run(resolve(&pnpm("10.0.0"), options).outcome); + let command = expect_run(resolve(&pnpm("10.16.0"), options).outcome); assert_eq!(command.program, "pnpm"); assert_eq!(command.args, vec!["why", "--find-by", "customFinder", "react"]); From adb8f7b2515b32ac344d6baf7a7ab3f667884f7f Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 22:36:32 +0900 Subject: [PATCH 2/6] test(pm): cover option version guards in both CLI flavors Add local and global regression snapshots for unsupported options and the pnpm publish JSON regression. Keep the publish fixture private. --- .../pm_option_version_guards/package.json | 5 ++ .../pm_option_version_guards/snapshots.toml | 53 +++++++++++++++ .../bun_option_version_guards.global.md | 35 ++++++++++ .../bun_option_version_guards.local.md | 35 ++++++++++ .../npm_option_version_guards.global.md | 55 ++++++++++++++++ .../npm_option_version_guards.local.md | 55 ++++++++++++++++ .../pnpm_option_version_guards.global.md | 55 ++++++++++++++++ .../pnpm_option_version_guards.local.md | 65 +++++++++++++++++++ .../pnpm_publish_json_regression.global.md | 11 ++++ .../pnpm_publish_json_regression.local.md | 25 +++++++ .../yarn_option_version_guards.global.md | 21 ++++++ .../yarn_option_version_guards.local.md | 21 ++++++ 12 files changed, 436 insertions(+) create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md create mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json new file mode 100644 index 0000000000..210bb8f59c --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json @@ -0,0 +1,5 @@ +{ + "name": "pm-option-version-guards", + "version": "1.0.0", + "private": true +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml new file mode 100644 index 0000000000..6dcd36b99b --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml @@ -0,0 +1,53 @@ +[[case]] +name = "npm_option_version_guards" +vp = ["local", "global"] +env = { VP_PACKAGE_MANAGER = "npm@5.8.0" } +steps = [ + { argv = ["vp", "pm", "publish", "--dry-run"], comment = "Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety.", continue-on-failure = true }, + { argv = ["vp", "pm", "publish", "--provenance"], continue-on-failure = true }, + { argv = ["vp", "pm", "pack", "--filter", "app"], continue-on-failure = true }, + { argv = ["vp", "pm", "pack", "--pack-destination", "dist"], continue-on-failure = true }, + { argv = ["vp", "install", "--filter", "app"], continue-on-failure = true }, + { argv = ["vp", "install", "--workspace-root"], continue-on-failure = true }, +] + +[[case]] +name = "pnpm_option_version_guards" +vp = ["local", "global"] +env = { VP_PACKAGE_MANAGER = "pnpm@10.3.0" } +steps = [ + { argv = ["vp", "add", "testnpm2", "--allow-build", "testnpm2"], continue-on-failure = true }, + { argv = ["vp", "add", "testnpm2", "--save-catalog-name", "web"], continue-on-failure = true }, + { argv = ["vp", "install", "testnpm2", "--save-catalog"], comment = "The install alias must use the add support checks.", continue-on-failure = true }, + { argv = ["vp", "pm", "pack", "--recursive"], continue-on-failure = true }, + { argv = ["vp", "pm", "list", "--find-by", "finder"], continue-on-failure = true }, + { argv = ["vp", "why", "--find-by", "finder"], comment = "A finder replaces package names, but still requires a supported pnpm version.", continue-on-failure = true }, +] + +[[case]] +name = "pnpm_publish_json_regression" +vp = ["local", "global"] +env = { VP_PACKAGE_MANAGER = "pnpm@11.0.6" } +steps = [ + { argv = ["vp", "pm", "publish", "--dry-run", "--json"], comment = "Reject the release range that silently omitted JSON output." }, +] + +[[case]] +name = "yarn_option_version_guards" +vp = ["local", "global"] +env = { VP_PACKAGE_MANAGER = "yarn@2.4.2" } +steps = [ + { argv = ["vp", "install", "--fix-lockfile"], continue-on-failure = true }, + { argv = ["vp", "add", "testnpm2", "--ignore-scripts"], comment = "Yarn 2 supports skip-builds for install, but not for add.", continue-on-failure = true }, +] + +[[case]] +name = "bun_option_version_guards" +vp = ["local", "global"] +env = { VP_PACKAGE_MANAGER = "bun@1.3.14" } +steps = [ + { argv = ["vp", "update", "--prod"], continue-on-failure = true }, + { argv = ["vp", "update", "--no-optional"], continue-on-failure = true }, + { argv = ["vp", "update", "--recursive"], continue-on-failure = true }, + { argv = ["vp", "update", "--filter", "app"], comment = "Older Bun supports filters only in interactive update.", continue-on-failure = true }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md new file mode 100644 index 0000000000..978d25c622 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md @@ -0,0 +1,35 @@ +# bun_option_version_guards + +## `vp update --prod` + +**Exit code:** 1 + +``` +bun < 1.4 does not support --prod. +``` + +## `vp update --no-optional` + +**Exit code:** 1 + +``` +bun < 1.4 does not support --no-optional. +``` + +## `vp update --recursive` + +**Exit code:** 1 + +``` +bun < 1.4 does not support --recursive without --interactive. +``` + +## `vp update --filter app` + +Older Bun supports filters only in interactive update. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --filter without --interactive. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md new file mode 100644 index 0000000000..2eb865677f --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md @@ -0,0 +1,35 @@ +# bun_option_version_guards + +## `vp update --prod` + +``` +Already up to date + +Done in using pnpm +``` + +## `vp update --no-optional` + +``` +Already up to date + +Done in using pnpm +``` + +## `vp update --recursive` + +``` +Already up to date + +Done in using pnpm +``` + +## `vp update --filter app` + +Older Bun supports filters only in interactive update. + +``` +Scope: 0 of 1 workspace projects + +Done in using pnpm +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md new file mode 100644 index 0000000000..b046932af1 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md @@ -0,0 +1,55 @@ +# npm_option_version_guards + +## `vp pm publish --dry-run` + +Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety. + +**Exit code:** 1 + +``` +npm < 5.10.0 does not support --dry-run. +``` + +## `vp pm publish --provenance` + +**Exit code:** 1 + +``` +npm < 9.5.0 does not support --provenance. +``` + +## `vp pm pack --filter app` + +**Exit code:** 1 + +``` +npm < 7.9.0 does not support --filter. +``` + +## `vp pm pack --pack-destination dist` + +**Exit code:** 1 + +``` +npm < 7.18.0 does not support --pack-destination. +``` + +## `vp install --filter app` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +npm < 7.14.0 does not support --filter. +``` + +## `vp install --workspace-root` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +npm < 8.1.0 does not support --workspace-root. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md new file mode 100644 index 0000000000..0e0a09cc84 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md @@ -0,0 +1,55 @@ +# npm_option_version_guards + +## `vp pm publish --dry-run` + +Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety. + +``` +📦 pm-option-version-guards@1.0.0 → http://127.0.0.1:/ +[WARN] Skip publishing pm-option-version-guards@1.0.0 (dry run) +``` + +## `vp pm publish --provenance` + +**Exit code:** 1 + +``` +📦 pm-option-version-guards@1.0.0 → http://127.0.0.1:/ +Error: ERR_PNPM_PRIVATE_PACKAGE + + x This package has been marked as private + help: Remove the 'private' field from the package.json to publish it. +``` + +## `vp pm pack --filter app` + +``` +``` + +## `vp pm pack --pack-destination dist` + +``` +package: pm-option-version-guards@1.0.0 +Tarball Contents +package.json +Tarball Details +/dist/pm-option-version-guards-1.0.0.tgz +``` + +## `vp install --filter app` + +``` +Scope: 0 of 1 workspace projects + +Done in using pnpm +``` + +## `vp install --workspace-root` + +**Exit code:** 1 + +``` +Error: ERR_PNPM_NOT_IN_WORKSPACE + + x --workspace-root may only be used inside a workspace +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md new file mode 100644 index 0000000000..0bcc4b3f96 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md @@ -0,0 +1,55 @@ +# pnpm_option_version_guards + +## `vp add testnpm2 --allow-build testnpm2` + +**Exit code:** 1 + +``` +pnpm < 10.4.0 does not support --allow-build. +``` + +## `vp add testnpm2 --save-catalog-name web` + +**Exit code:** 1 + +``` +pnpm < 10.12.0 does not support --save-catalog-name. +``` + +## `vp install testnpm2 --save-catalog` + +The install alias must use the add support checks. + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +pnpm < 10.12.0 does not support --save-catalog. +``` + +## `vp pm pack --recursive` + +**Exit code:** 1 + +``` +pnpm < 10.11.0 does not support --recursive. +``` + +## `vp pm list --find-by finder` + +**Exit code:** 1 + +``` +pnpm < 10.16.0 does not support --find-by. +``` + +## `vp why --find-by finder` + +A finder replaces package names, but still requires a supported pnpm version. + +**Exit code:** 1 + +``` +pnpm < 10.16.0 does not support --find-by. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md new file mode 100644 index 0000000000..b39ea0dc44 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md @@ -0,0 +1,65 @@ +# pnpm_option_version_guards + +## `vp add testnpm2 --allow-build testnpm2` + +``` + +dependencies: + testnpm2 1.0.1 + +Done in using pnpm +``` + +## `vp add testnpm2 --save-catalog-name web` + +``` +✓ Lockfile passes supply-chain policies (verified ago) +Already up to date + +Done in using pnpm +``` + +## `vp install testnpm2 --save-catalog` + +The install alias must use the add support checks. + +``` +[WARN] Replaced "testnpm2" ("catalog:web") with "testnpm2" from a different source. +✓ Lockfile passes supply-chain policies (verified ago) +Lockfile is up to date, resolution step is skipped + +Done in using pnpm +``` + +## `vp pm pack --recursive` + +``` +package: pm-option-version-guards@1.0.0 +Tarball Contents +package.json +pnpm-workspace.yaml +Tarball Details +pm-option-version-guards-1.0.0.tgz +``` + +## `vp pm list --find-by finder` + +**Exit code:** 1 + +``` +Error: ERR_PNPM_FINDER_NOT_FOUND + + x No finder with name finder is found +``` + +## `vp why --find-by finder` + +A finder replaces package names, but still requires a supported pnpm version. + +**Exit code:** 1 + +``` +Error: ERR_PNPM_FINDER_NOT_FOUND + + x No finder with name finder is found +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md new file mode 100644 index 0000000000..d4acf97e52 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md @@ -0,0 +1,11 @@ +# pnpm_publish_json_regression + +## `vp pm publish --dry-run --json` + +Reject the release range that silently omitted JSON output. + +**Exit code:** 1 + +``` +pnpm >= 11.0.0 && < 11.0.7 does not support --json. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md new file mode 100644 index 0000000000..fdf0dff9c9 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md @@ -0,0 +1,25 @@ +# pnpm_publish_json_regression + +## `vp pm publish --dry-run --json` + +Reject the release range that silently omitted JSON output. + +``` +{ + "id": "pm-option-version-guards@1.0.0", + "name": "pm-option-version-guards", + "version": "1.0.0", + "size": 158, + "unpackedSize": 81, + "shasum": "224d7315b27d0ed1a65a32a7f471d74117433c00", + "integrity": "sha512-LQ4iYVOyHdkxXnP7UyE6qi3yXzVCVAcuAyzCU1NFveWNzCUhyJ28a7nxfut8gSrr01qBOB9kIMlENnWmP6Vyag==", + "filename": "pm-option-version-guards-1.0.0.tgz", + "files": [ + { + "path": "package.json" + } + ], + "entryCount": 1, + "bundled": [] +} +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md new file mode 100644 index 0000000000..3270cb6067 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md @@ -0,0 +1,21 @@ +# yarn_option_version_guards + +## `vp install --fix-lockfile` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +yarn < 4.0.0 does not support --fix-lockfile. +``` + +## `vp add testnpm2 --ignore-scripts` + +Yarn 2 supports skip-builds for install, but not for add. + +**Exit code:** 1 + +``` +yarn >= 2 && < 3 does not support --ignore-scripts. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md new file mode 100644 index 0000000000..82ff88486a --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md @@ -0,0 +1,21 @@ +# yarn_option_version_guards + +## `vp install --fix-lockfile` + +``` +Already up to date + +Done in using pnpm +``` + +## `vp add testnpm2 --ignore-scripts` + +Yarn 2 supports skip-builds for install, but not for add. + +``` + +dependencies: + testnpm2 1.0.1 + +Done in using pnpm +``` From d33169bd28256b12d2eaf10bdb09c161c843a78d Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 22:50:00 +0900 Subject: [PATCH 3/6] fix(pm): keep package names required for why Remove the pnpm-only exception for --find-by from the shared argument parser. Restore the required positional argument in help output and cover the rejection in CLI snapshots. --- .../snapshots/cli_helper_message.md | 4 ++-- .../snapshots/command_why_bun.md | 4 ++-- .../snapshots/command_why_pnpm10.global.md | 4 ++-- .../snapshots/command_why_pnpm10.local.md | 4 ++-- .../snapshots/command_why_pnpm11.md | 4 ++-- .../pm_option_version_guards/snapshots.toml | 3 ++- .../pnpm_option_version_guards.global.md | 19 ++++++++++++++++--- .../pnpm_option_version_guards.local.md | 19 ++++++++++++++++--- .../vp_pm_cli/src/resolution/commands/why.rs | 2 +- 9 files changed, 45 insertions(+), 18 deletions(-) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md index fafb93fa88..1829c4ad14 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/cli_helper_message/snapshots/cli_helper_message.md @@ -349,12 +349,12 @@ show why help message ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Show why a package is installed Arguments: - [PACKAGES]... Package(s) to check + ... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md index 3c8d74cec6..c88115ad51 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_bun/snapshots/command_why_bun.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Show why a package is installed Arguments: - [PACKAGES]... Package(s) to check + ... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md index e3aa8f400f..98e7f1bb66 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Show why a package is installed Arguments: - [PACKAGES]... Package(s) to check + ... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md index 0ba979faa9..640cac2508 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md @@ -7,10 +7,10 @@ should show help ``` Show why a package is installed -Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Arguments: - [PACKAGES]... Package(s) to check + ... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md index 7aac46dc18..94c8888a1f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm11/snapshots/command_why_pnpm11.md @@ -7,12 +7,12 @@ should show help ``` VITE+ - The Unified Toolchain for the Web -Usage: vp why [OPTIONS] [PACKAGES]... [-- ...] +Usage: vp why [OPTIONS] ... [-- ...] Show why a package is installed Arguments: - [PACKAGES]... Package(s) to check + ... Package(s) to check [PASS_THROUGH_ARGS]... Additional arguments to pass through to the package manager Options: diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml index 6dcd36b99b..bb443a8467 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml @@ -21,7 +21,8 @@ steps = [ { argv = ["vp", "install", "testnpm2", "--save-catalog"], comment = "The install alias must use the add support checks.", continue-on-failure = true }, { argv = ["vp", "pm", "pack", "--recursive"], continue-on-failure = true }, { argv = ["vp", "pm", "list", "--find-by", "finder"], continue-on-failure = true }, - { argv = ["vp", "why", "--find-by", "finder"], comment = "A finder replaces package names, but still requires a supported pnpm version.", continue-on-failure = true }, + { argv = ["vp", "why", "testnpm2", "--find-by", "finder"], continue-on-failure = true }, + { argv = ["vp", "why", "--find-by", "finder"], comment = "Package names remain required even when a finder is supplied.", continue-on-failure = true }, ] [[case]] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md index 0bcc4b3f96..39bab7f512 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md @@ -44,12 +44,25 @@ pnpm < 10.11.0 does not support --recursive. pnpm < 10.16.0 does not support --find-by. ``` -## `vp why --find-by finder` - -A finder replaces package names, but still requires a supported pnpm version. +## `vp why testnpm2 --find-by finder` **Exit code:** 1 ``` pnpm < 10.16.0 does not support --find-by. ``` + +## `vp why --find-by finder` + +Package names remain required even when a finder is supplied. + +**Exit code:** 2 + +``` +error: the following required arguments were not provided: + ... + +Usage: vp why --find-by ... [-- ...] + +For more information, try '--help'. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md index b39ea0dc44..7f86dee7d7 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md @@ -52,9 +52,7 @@ Error: ERR_PNPM_FINDER_NOT_FOUND x No finder with name finder is found ``` -## `vp why --find-by finder` - -A finder replaces package names, but still requires a supported pnpm version. +## `vp why testnpm2 --find-by finder` **Exit code:** 1 @@ -63,3 +61,18 @@ Error: ERR_PNPM_FINDER_NOT_FOUND x No finder with name finder is found ``` + +## `vp why --find-by finder` + +Package names remain required even when a finder is supplied. + +**Exit code:** 2 + +``` +error: the following required arguments were not provided: + ... + +Usage: vp why --find-by ... [-- ...] + +For more information, try '--help'. +``` diff --git a/crates/vp_pm_cli/src/resolution/commands/why.rs b/crates/vp_pm_cli/src/resolution/commands/why.rs index e617e924c4..2b05107a90 100644 --- a/crates/vp_pm_cli/src/resolution/commands/why.rs +++ b/crates/vp_pm_cli/src/resolution/commands/why.rs @@ -8,7 +8,7 @@ use crate::resolution::{ #[derive(clap::Args, Clone, Debug, Default, PartialEq, Eq)] pub struct WhyArgs { /// Package(s) to check - #[arg(required_unless_present = "find_by")] + #[arg(required = true)] pub(crate) packages: Vec, /// Output in JSON format From afcb64edd27e5b9a5f1807a77339f7a48004978f Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 22:55:32 +0900 Subject: [PATCH 4/6] test(pm): move version guards into existing command snapshots Extend the related command fixtures instead of maintaining a separate version-guard fixture. Reuse existing pnpm add coverage and set packageManager in temporary manifests so local and global commands use the intended versions. Keep the npm publication probes private and cover why's required package names in its existing snapshots. --- .../snapshots.toml | 1 + .../command_add_pnpm9_with_workspace.md | 12 +++ .../fixtures/command_add_yarn4/snapshots.toml | 2 + .../snapshots/command_add_yarn4.md | 13 ++++ .../command_list_pnpm10/snapshots.toml | 2 + .../snapshots/command_list_pnpm10.md | 13 ++++ .../command_pack_npm10/snapshots.toml | 4 + .../snapshots/command_pack_npm10.md | 26 +++++++ .../command_pack_pnpm10/snapshots.toml | 2 + .../snapshots/command_pack_pnpm10.md | 13 ++++ .../command_publish_npm10/snapshots.toml | 5 ++ .../snapshots/command_publish_npm10.md | 29 +++++++ .../command_publish_pnpm11/snapshots.toml | 1 + .../snapshots/command_publish_pnpm11.md | 10 +++ .../command_update_bun/snapshots.toml | 5 ++ .../snapshots/command_update_bun.md | 43 ++++++++++ .../command_why_pnpm10/snapshots.toml | 3 + .../snapshots/command_why_pnpm10.global.md | 28 +++++++ .../snapshots/command_why_pnpm10.local.md | 28 +++++++ .../npm_install_with_options/snapshots.toml | 4 + .../snapshots/npm_install_with_options.md | 26 +++++++ .../pm_option_version_guards/package.json | 5 -- .../pm_option_version_guards/snapshots.toml | 54 ------------- .../bun_option_version_guards.global.md | 35 --------- .../bun_option_version_guards.local.md | 35 --------- .../npm_option_version_guards.global.md | 55 ------------- .../npm_option_version_guards.local.md | 55 ------------- .../pnpm_option_version_guards.global.md | 68 ---------------- .../pnpm_option_version_guards.local.md | 78 ------------------- .../pnpm_publish_json_regression.global.md | 11 --- .../pnpm_publish_json_regression.local.md | 25 ------ .../yarn_option_version_guards.global.md | 21 ----- .../yarn_option_version_guards.local.md | 21 ----- .../yarn_install_with_options/snapshots.toml | 2 + .../snapshots/yarn_install_with_options.md | 13 ++++ 35 files changed, 285 insertions(+), 463 deletions(-) delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md delete mode 100644 crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots.toml index 039b65d4ce..47a680bde4 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots.toml @@ -18,4 +18,5 @@ steps = [ { argv = ["vpt", "print-file", "package.json", "packages/app/package.json", "packages/utils/package.json", "pnpm-workspace.yaml"], continue-on-failure = true }, { argv = ["vp", "add", "--filter", "app", "test-vite-plus-package-optional", "--save-catalog-name", "v1"], comment = "should error because save-catalog-name is not supported at pnpm@9", continue-on-failure = true }, { argv = ["vp", "add", "--filter=./packages/utils", "test-vite-plus-package-optional", "-O", "--save-catalog", "v2"], comment = "should error because save-catalog is not supported at pnpm@9", continue-on-failure = true }, + { argv = ["vp", "install", "testnpm2", "--save-catalog"], comment = "The install alias must apply the add catalog version guard.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md index b52e23a15e..c8dc55132e 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_pnpm9_with_workspace/snapshots/command_add_pnpm9_with_workspace.md @@ -215,3 +215,15 @@ should error because save-catalog is not supported at pnpm@9 ``` pnpm < 10.12.0 does not support --save-catalog. ``` + +## `vp install testnpm2 --save-catalog` + +The install alias must apply the add catalog version guard. + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +pnpm < 10.12.0 does not support --save-catalog. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots.toml index 525840ac3b..ada66c9031 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots.toml @@ -14,4 +14,6 @@ steps = [ { argv = ["vpt", "print-file", "package.json"], continue-on-failure = true }, { argv = ["vp", "add", "test-vite-plus-package-optional", "--", "--tilde"], comment = "support pass through arguments" }, { argv = ["vpt", "print-file", "package.json"], continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "yarn@2.4.2"], snapshot = false }, + { argv = ["vp", "add", "testnpm2", "--ignore-scripts"], comment = "Yarn 2 supports skip-builds for install, but not for add.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots/command_add_yarn4.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots/command_add_yarn4.md index 4d8a43084d..4f7f3f217f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots/command_add_yarn4.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_add_yarn4/snapshots/command_add_yarn4.md @@ -201,3 +201,16 @@ support pass through arguments } } ``` + +## `vpt json-edit package.json packageManager yarn@2.4.2` + + +## `vp add testnpm2 --ignore-scripts` + +Yarn 2 supports skip-builds for install, but not for add. + +**Exit code:** 1 + +``` +yarn >= 2 && < 3 does not support --ignore-scripts. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots.toml index 1e1d19f7fb..ce7de0451f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots.toml @@ -19,4 +19,6 @@ steps = [ { argv = ["vp", "pm", "list", "--find-by", "customFinder"], comment = "should use custom finder (pnpm-specific)", continue-on-failure = true }, { argv = ["vp", "pm", "list", "--recursive"], comment = "should list packages recursively in workspace", continue-on-failure = true }, { argv = ["vp", "pm", "list", "--", "--loglevel=warn"], comment = "should support pass through arguments", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "pnpm@10.15.1"], snapshot = false }, + { argv = ["vp", "pm", "list", "--find-by", "customFinder"], comment = "Reject finders before pnpm 10.16.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots/command_list_pnpm10.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots/command_list_pnpm10.md index ad2ec991a5..75f3d6e9a3 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots/command_list_pnpm10.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_list_pnpm10/snapshots/command_list_pnpm10.md @@ -279,3 +279,16 @@ testnpm2 1.0.1 devDependencies: test-vite-plus-package 1.0.0 ``` + +## `vpt json-edit package.json packageManager pnpm@10.15.1` + + +## `vp pm list --find-by customFinder` + +Reject finders before pnpm 10.16.0. + +**Exit code:** 1 + +``` +pnpm < 10.16.0 does not support --find-by. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots.toml index 191e5e12db..10f080176b 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots.toml @@ -9,4 +9,8 @@ steps = [ { argv = ["vpt", "rm", "-rf", "./dist"], continue-on-failure = true }, { argv = ["vp", "pm", "pack", "--json", "--", "--loglevel=warn"], comment = "should support pass through arguments" }, { argv = ["vpt", "rm", "-f", "command-pack-npm10-1.0.0.tgz"], snapshot = false, continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@7.8.0"], snapshot = false }, + { argv = ["vp", "pm", "pack", "--filter", "app"], comment = "Reject workspace selection before npm 7.9.0.", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@7.17.0"], snapshot = false }, + { argv = ["vp", "pm", "pack", "--pack-destination", "dist"], comment = "Reject pack-destination before npm 7.18.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots/command_pack_npm10.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots/command_pack_npm10.md index 149406c4b6..266389c253 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots/command_pack_npm10.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_npm10/snapshots/command_pack_npm10.md @@ -94,3 +94,29 @@ should support pass through arguments ## `vpt rm -f command-pack-npm10-1.0.0.tgz` + +## `vpt json-edit package.json packageManager npm@7.8.0` + + +## `vp pm pack --filter app` + +Reject workspace selection before npm 7.9.0. + +**Exit code:** 1 + +``` +npm < 7.9.0 does not support --filter. +``` + +## `vpt json-edit package.json packageManager npm@7.17.0` + + +## `vp pm pack --pack-destination dist` + +Reject pack-destination before npm 7.18.0. + +**Exit code:** 1 + +``` +npm < 7.18.0 does not support --pack-destination. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots.toml index 2b493ddf64..66fa500bc1 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots.toml @@ -16,4 +16,6 @@ steps = [ { argv = ["vpt", "rm", "-f", "command-pack-pnpm10-1.0.0.tgz"], snapshot = false, continue-on-failure = true }, { argv = ["vp", "pm", "pack", "--", "--loglevel=warn"], comment = "should support pass through arguments" }, { argv = ["vpt", "rm", "-f", "command-pack-pnpm10-1.0.0.tgz"], snapshot = false, continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "pnpm@10.10.0"], snapshot = false }, + { argv = ["vp", "pm", "pack", "--recursive"], comment = "Reject recursive pack before pnpm 10.11.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots/command_pack_pnpm10.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots/command_pack_pnpm10.md index ea912f13ab..f997f0cb06 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots/command_pack_pnpm10.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_pack_pnpm10/snapshots/command_pack_pnpm10.md @@ -129,3 +129,16 @@ command-pack-pnpm10-1.0.0.tgz ## `vpt rm -f command-pack-pnpm10-1.0.0.tgz` + +## `vpt json-edit package.json packageManager pnpm@10.10.0` + + +## `vp pm pack --recursive` + +Reject recursive pack before pnpm 10.11.0. + +**Exit code:** 1 + +``` +pnpm < 10.11.0 does not support --recursive. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots.toml index f2fd17bdf5..9c069bf4e3 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots.toml @@ -6,4 +6,9 @@ steps = [ { argv = ["vp", "pm", "publish", "--help"], comment = "should show help", continue-on-failure = true }, { argv = ["vp", "pm", "publish", "--dry-run", "--", "--loglevel", "error"], comment = "should preview publish without actually publishing (uses npm publish --dry-run)", continue-on-failure = true }, { argv = ["vp", "pm", "publish", "--dry-run", "--json", "--", "--ignore-scripts", "--loglevel", "error"], comment = "should preserve JSON output without publishing", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "private", "true"], snapshot = false }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@5.8.0"], snapshot = false }, + { argv = ["vp", "pm", "publish", "--dry-run"], comment = "Reject npm versions that publish despite dry-run. The package is private for safety.", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@9.4.2"], snapshot = false }, + { argv = ["vp", "pm", "publish", "--dry-run", "--provenance"], comment = "Reject provenance before npm 9.5.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots/command_publish_npm10.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots/command_publish_npm10.md index 7eeabb6e92..de92bf6d16 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots/command_publish_npm10.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_npm10/snapshots/command_publish_npm10.md @@ -66,3 +66,32 @@ should preserve JSON output without publishing "bundled": [] } ``` + +## `vpt json-edit package.json private true` + + +## `vpt json-edit package.json packageManager npm@5.8.0` + + +## `vp pm publish --dry-run` + +Reject npm versions that publish despite dry-run. The package is private for safety. + +**Exit code:** 1 + +``` +npm < 5.10.0 does not support --dry-run. +``` + +## `vpt json-edit package.json packageManager npm@9.4.2` + + +## `vp pm publish --dry-run --provenance` + +Reject provenance before npm 9.5.0. + +**Exit code:** 1 + +``` +npm < 9.5.0 does not support --provenance. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots.toml index b32d6965e8..96fae24da3 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots.toml @@ -4,4 +4,5 @@ vp = "global" steps = [ { argv = ["vp", "pm", "publish", "--help"], comment = "should show help", continue-on-failure = true }, { argv = ["vp", "pm", "publish", "--dry-run", "--", "--loglevel", "error"], comment = "should preview publish without actually publishing (uses pnpm publish --dry-run)", continue-on-failure = true }, + { argv = ["vp", "pm", "publish", "--dry-run", "--json"], comment = "Reject pnpm 11.0.6, which silently omitted JSON output.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots/command_publish_pnpm11.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots/command_publish_pnpm11.md index da143dac83..4439e77175 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots/command_publish_pnpm11.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_publish_pnpm11/snapshots/command_publish_pnpm11.md @@ -39,3 +39,13 @@ should preview publish without actually publishing (uses pnpm publish --dry-run) ``` ``` + +## `vp pm publish --dry-run --json` + +Reject pnpm 11.0.6, which silently omitted JSON output. + +**Exit code:** 1 + +``` +pnpm >= 11.0.0 && < 11.0.7 does not support --json. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml index bd7ece4147..58c2732672 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml @@ -8,4 +8,9 @@ steps = [ { argv = ["vpt", "print-file", "package.json"], continue-on-failure = true }, { argv = ["vp", "up", "testnpm2", "--latest"], comment = "should update to absolute latest version" }, { argv = ["vpt", "print-file", "package.json"], continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "bun@1.3.14"], snapshot = false }, + { argv = ["vp", "update", "--prod"], comment = "Reject production dependency selection before Bun 1.4.", continue-on-failure = true }, + { argv = ["vp", "update", "--no-optional"], comment = "Reject optional dependency exclusion before Bun 1.4.", continue-on-failure = true }, + { argv = ["vp", "update", "--recursive"], comment = "Reject noninteractive recursive updates before Bun 1.4.", continue-on-failure = true }, + { argv = ["vp", "update", "--filter", "app"], comment = "Older Bun supports filters only in interactive update.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md index 5205d4bd40..a1c9645e7c 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md @@ -97,3 +97,46 @@ installed testnpm2@1.0.1 "packageManager": "bun@1.3.11" } ``` + +## `vpt json-edit package.json packageManager bun@1.3.14` + + +## `vp update --prod` + +Reject production dependency selection before Bun 1.4. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --prod. +``` + +## `vp update --no-optional` + +Reject optional dependency exclusion before Bun 1.4. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --no-optional. +``` + +## `vp update --recursive` + +Reject noninteractive recursive updates before Bun 1.4. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --recursive without --interactive. +``` + +## `vp update --filter app` + +Older Bun supports filters only in interactive update. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --filter without --interactive. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots.toml index f6a6e5eb4c..874784c34f 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots.toml @@ -18,4 +18,7 @@ steps = [ { argv = ["vp", "why", "test-vite-plus-package-optional", "--no-optional"], comment = "should exclude optional dependencies", continue-on-failure = true }, { argv = ["vp", "why", "testnpm2", "--find-by", "customFinder"], comment = "should support find-by option (pnpm-specific)", continue-on-failure = true }, { argv = ["vp", "why", "testnpm2", "--", "--reporter=silent"], comment = "should support pass through arguments", continue-on-failure = true }, + { argv = ["vp", "why", "--find-by", "customFinder"], comment = "Package names remain required even when a finder is supplied.", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "pnpm@10.15.1"], snapshot = false }, + { argv = ["vp", "why", "testnpm2", "--find-by", "customFinder"], comment = "Reject finders before pnpm 10.16.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md index 98e7f1bb66..d67398c145 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.global.md @@ -221,3 +221,31 @@ command-why-pnpm10@1.0.0 dependencies: testnpm2 1.0.1 ``` + +## `vp why --find-by customFinder` + +Package names remain required even when a finder is supplied. + +**Exit code:** 2 + +``` +error: the following required arguments were not provided: + ... + +Usage: vp why --find-by ... [-- ...] + +For more information, try '--help'. +``` + +## `vpt json-edit package.json packageManager pnpm@10.15.1` + + +## `vp why testnpm2 --find-by customFinder` + +Reject finders before pnpm 10.16.0. + +**Exit code:** 1 + +``` +pnpm < 10.16.0 does not support --find-by. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md index 640cac2508..f0e039cf1c 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_why_pnpm10/snapshots/command_why_pnpm10.local.md @@ -216,3 +216,31 @@ command-why-pnpm10@1.0.0 dependencies: testnpm2 1.0.1 ``` + +## `vp why --find-by customFinder` + +Package names remain required even when a finder is supplied. + +**Exit code:** 2 + +``` +error: the following required arguments were not provided: + ... + +Usage: vp why --find-by ... [-- ...] + +For more information, try '--help'. +``` + +## `vpt json-edit package.json packageManager pnpm@10.15.1` + + +## `vp why testnpm2 --find-by customFinder` + +Reject finders before pnpm 10.16.0. + +**Exit code:** 1 + +``` +pnpm < 10.16.0 does not support --find-by. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots.toml index 29ba0391a2..027b75ae75 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots.toml @@ -8,4 +8,8 @@ steps = [ { argv = ["vpt", "list-dir", "node_modules"], continue-on-failure = true }, { argv = ["vp", "run", "install"], comment = "install again hit cache", continue-on-failure = true }, { argv = ["vp", "run", "--last-details"], continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@7.13.0"], snapshot = false }, + { argv = ["vp", "install", "--filter", "app"], comment = "Reject workspace selection before npm 7.14.0.", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "npm@8.0.0"], snapshot = false }, + { argv = ["vp", "install", "--workspace-root"], comment = "Reject workspace root inclusion before npm 8.1.0.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md index 2aad8cc979..e08a013060 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/npm_install_with_options/snapshots/npm_install_with_options.md @@ -81,3 +81,29 @@ Task Details: → Cache disabled in task configuration ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` + +## `vpt json-edit package.json packageManager npm@7.13.0` + + +## `vp install --filter app` + +Reject workspace selection before npm 7.14.0. + +**Exit code:** 1 + +``` +npm < 7.14.0 does not support --filter. +``` + +## `vpt json-edit package.json packageManager npm@8.0.0` + + +## `vp install --workspace-root` + +Reject workspace root inclusion before npm 8.1.0. + +**Exit code:** 1 + +``` +npm < 8.1.0 does not support --workspace-root. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json deleted file mode 100644 index 210bb8f59c..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "pm-option-version-guards", - "version": "1.0.0", - "private": true -} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml deleted file mode 100644 index bb443a8467..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots.toml +++ /dev/null @@ -1,54 +0,0 @@ -[[case]] -name = "npm_option_version_guards" -vp = ["local", "global"] -env = { VP_PACKAGE_MANAGER = "npm@5.8.0" } -steps = [ - { argv = ["vp", "pm", "publish", "--dry-run"], comment = "Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety.", continue-on-failure = true }, - { argv = ["vp", "pm", "publish", "--provenance"], continue-on-failure = true }, - { argv = ["vp", "pm", "pack", "--filter", "app"], continue-on-failure = true }, - { argv = ["vp", "pm", "pack", "--pack-destination", "dist"], continue-on-failure = true }, - { argv = ["vp", "install", "--filter", "app"], continue-on-failure = true }, - { argv = ["vp", "install", "--workspace-root"], continue-on-failure = true }, -] - -[[case]] -name = "pnpm_option_version_guards" -vp = ["local", "global"] -env = { VP_PACKAGE_MANAGER = "pnpm@10.3.0" } -steps = [ - { argv = ["vp", "add", "testnpm2", "--allow-build", "testnpm2"], continue-on-failure = true }, - { argv = ["vp", "add", "testnpm2", "--save-catalog-name", "web"], continue-on-failure = true }, - { argv = ["vp", "install", "testnpm2", "--save-catalog"], comment = "The install alias must use the add support checks.", continue-on-failure = true }, - { argv = ["vp", "pm", "pack", "--recursive"], continue-on-failure = true }, - { argv = ["vp", "pm", "list", "--find-by", "finder"], continue-on-failure = true }, - { argv = ["vp", "why", "testnpm2", "--find-by", "finder"], continue-on-failure = true }, - { argv = ["vp", "why", "--find-by", "finder"], comment = "Package names remain required even when a finder is supplied.", continue-on-failure = true }, -] - -[[case]] -name = "pnpm_publish_json_regression" -vp = ["local", "global"] -env = { VP_PACKAGE_MANAGER = "pnpm@11.0.6" } -steps = [ - { argv = ["vp", "pm", "publish", "--dry-run", "--json"], comment = "Reject the release range that silently omitted JSON output." }, -] - -[[case]] -name = "yarn_option_version_guards" -vp = ["local", "global"] -env = { VP_PACKAGE_MANAGER = "yarn@2.4.2" } -steps = [ - { argv = ["vp", "install", "--fix-lockfile"], continue-on-failure = true }, - { argv = ["vp", "add", "testnpm2", "--ignore-scripts"], comment = "Yarn 2 supports skip-builds for install, but not for add.", continue-on-failure = true }, -] - -[[case]] -name = "bun_option_version_guards" -vp = ["local", "global"] -env = { VP_PACKAGE_MANAGER = "bun@1.3.14" } -steps = [ - { argv = ["vp", "update", "--prod"], continue-on-failure = true }, - { argv = ["vp", "update", "--no-optional"], continue-on-failure = true }, - { argv = ["vp", "update", "--recursive"], continue-on-failure = true }, - { argv = ["vp", "update", "--filter", "app"], comment = "Older Bun supports filters only in interactive update.", continue-on-failure = true }, -] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md deleted file mode 100644 index 978d25c622..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.global.md +++ /dev/null @@ -1,35 +0,0 @@ -# bun_option_version_guards - -## `vp update --prod` - -**Exit code:** 1 - -``` -bun < 1.4 does not support --prod. -``` - -## `vp update --no-optional` - -**Exit code:** 1 - -``` -bun < 1.4 does not support --no-optional. -``` - -## `vp update --recursive` - -**Exit code:** 1 - -``` -bun < 1.4 does not support --recursive without --interactive. -``` - -## `vp update --filter app` - -Older Bun supports filters only in interactive update. - -**Exit code:** 1 - -``` -bun < 1.4 does not support --filter without --interactive. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md deleted file mode 100644 index 2eb865677f..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/bun_option_version_guards.local.md +++ /dev/null @@ -1,35 +0,0 @@ -# bun_option_version_guards - -## `vp update --prod` - -``` -Already up to date - -Done in using pnpm -``` - -## `vp update --no-optional` - -``` -Already up to date - -Done in using pnpm -``` - -## `vp update --recursive` - -``` -Already up to date - -Done in using pnpm -``` - -## `vp update --filter app` - -Older Bun supports filters only in interactive update. - -``` -Scope: 0 of 1 workspace projects - -Done in using pnpm -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md deleted file mode 100644 index b046932af1..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.global.md +++ /dev/null @@ -1,55 +0,0 @@ -# npm_option_version_guards - -## `vp pm publish --dry-run` - -Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety. - -**Exit code:** 1 - -``` -npm < 5.10.0 does not support --dry-run. -``` - -## `vp pm publish --provenance` - -**Exit code:** 1 - -``` -npm < 9.5.0 does not support --provenance. -``` - -## `vp pm pack --filter app` - -**Exit code:** 1 - -``` -npm < 7.9.0 does not support --filter. -``` - -## `vp pm pack --pack-destination dist` - -**Exit code:** 1 - -``` -npm < 7.18.0 does not support --pack-destination. -``` - -## `vp install --filter app` - -**Exit code:** 1 - -``` -VITE+ - The Unified Toolchain for the Web - -npm < 7.14.0 does not support --filter. -``` - -## `vp install --workspace-root` - -**Exit code:** 1 - -``` -VITE+ - The Unified Toolchain for the Web - -npm < 8.1.0 does not support --workspace-root. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md deleted file mode 100644 index 0e0a09cc84..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/npm_option_version_guards.local.md +++ /dev/null @@ -1,55 +0,0 @@ -# npm_option_version_guards - -## `vp pm publish --dry-run` - -Reject preview before an npm version that would publish despite dry-run. The fixture is also private for safety. - -``` -📦 pm-option-version-guards@1.0.0 → http://127.0.0.1:/ -[WARN] Skip publishing pm-option-version-guards@1.0.0 (dry run) -``` - -## `vp pm publish --provenance` - -**Exit code:** 1 - -``` -📦 pm-option-version-guards@1.0.0 → http://127.0.0.1:/ -Error: ERR_PNPM_PRIVATE_PACKAGE - - x This package has been marked as private - help: Remove the 'private' field from the package.json to publish it. -``` - -## `vp pm pack --filter app` - -``` -``` - -## `vp pm pack --pack-destination dist` - -``` -package: pm-option-version-guards@1.0.0 -Tarball Contents -package.json -Tarball Details -/dist/pm-option-version-guards-1.0.0.tgz -``` - -## `vp install --filter app` - -``` -Scope: 0 of 1 workspace projects - -Done in using pnpm -``` - -## `vp install --workspace-root` - -**Exit code:** 1 - -``` -Error: ERR_PNPM_NOT_IN_WORKSPACE - - x --workspace-root may only be used inside a workspace -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md deleted file mode 100644 index 39bab7f512..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.global.md +++ /dev/null @@ -1,68 +0,0 @@ -# pnpm_option_version_guards - -## `vp add testnpm2 --allow-build testnpm2` - -**Exit code:** 1 - -``` -pnpm < 10.4.0 does not support --allow-build. -``` - -## `vp add testnpm2 --save-catalog-name web` - -**Exit code:** 1 - -``` -pnpm < 10.12.0 does not support --save-catalog-name. -``` - -## `vp install testnpm2 --save-catalog` - -The install alias must use the add support checks. - -**Exit code:** 1 - -``` -VITE+ - The Unified Toolchain for the Web - -pnpm < 10.12.0 does not support --save-catalog. -``` - -## `vp pm pack --recursive` - -**Exit code:** 1 - -``` -pnpm < 10.11.0 does not support --recursive. -``` - -## `vp pm list --find-by finder` - -**Exit code:** 1 - -``` -pnpm < 10.16.0 does not support --find-by. -``` - -## `vp why testnpm2 --find-by finder` - -**Exit code:** 1 - -``` -pnpm < 10.16.0 does not support --find-by. -``` - -## `vp why --find-by finder` - -Package names remain required even when a finder is supplied. - -**Exit code:** 2 - -``` -error: the following required arguments were not provided: - ... - -Usage: vp why --find-by ... [-- ...] - -For more information, try '--help'. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md deleted file mode 100644 index 7f86dee7d7..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_option_version_guards.local.md +++ /dev/null @@ -1,78 +0,0 @@ -# pnpm_option_version_guards - -## `vp add testnpm2 --allow-build testnpm2` - -``` - -dependencies: - testnpm2 1.0.1 - -Done in using pnpm -``` - -## `vp add testnpm2 --save-catalog-name web` - -``` -✓ Lockfile passes supply-chain policies (verified ago) -Already up to date - -Done in using pnpm -``` - -## `vp install testnpm2 --save-catalog` - -The install alias must use the add support checks. - -``` -[WARN] Replaced "testnpm2" ("catalog:web") with "testnpm2" from a different source. -✓ Lockfile passes supply-chain policies (verified ago) -Lockfile is up to date, resolution step is skipped - -Done in using pnpm -``` - -## `vp pm pack --recursive` - -``` -package: pm-option-version-guards@1.0.0 -Tarball Contents -package.json -pnpm-workspace.yaml -Tarball Details -pm-option-version-guards-1.0.0.tgz -``` - -## `vp pm list --find-by finder` - -**Exit code:** 1 - -``` -Error: ERR_PNPM_FINDER_NOT_FOUND - - x No finder with name finder is found -``` - -## `vp why testnpm2 --find-by finder` - -**Exit code:** 1 - -``` -Error: ERR_PNPM_FINDER_NOT_FOUND - - x No finder with name finder is found -``` - -## `vp why --find-by finder` - -Package names remain required even when a finder is supplied. - -**Exit code:** 2 - -``` -error: the following required arguments were not provided: - ... - -Usage: vp why --find-by ... [-- ...] - -For more information, try '--help'. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md deleted file mode 100644 index d4acf97e52..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.global.md +++ /dev/null @@ -1,11 +0,0 @@ -# pnpm_publish_json_regression - -## `vp pm publish --dry-run --json` - -Reject the release range that silently omitted JSON output. - -**Exit code:** 1 - -``` -pnpm >= 11.0.0 && < 11.0.7 does not support --json. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md deleted file mode 100644 index fdf0dff9c9..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/pnpm_publish_json_regression.local.md +++ /dev/null @@ -1,25 +0,0 @@ -# pnpm_publish_json_regression - -## `vp pm publish --dry-run --json` - -Reject the release range that silently omitted JSON output. - -``` -{ - "id": "pm-option-version-guards@1.0.0", - "name": "pm-option-version-guards", - "version": "1.0.0", - "size": 158, - "unpackedSize": 81, - "shasum": "224d7315b27d0ed1a65a32a7f471d74117433c00", - "integrity": "sha512-LQ4iYVOyHdkxXnP7UyE6qi3yXzVCVAcuAyzCU1NFveWNzCUhyJ28a7nxfut8gSrr01qBOB9kIMlENnWmP6Vyag==", - "filename": "pm-option-version-guards-1.0.0.tgz", - "files": [ - { - "path": "package.json" - } - ], - "entryCount": 1, - "bundled": [] -} -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md deleted file mode 100644 index 3270cb6067..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.global.md +++ /dev/null @@ -1,21 +0,0 @@ -# yarn_option_version_guards - -## `vp install --fix-lockfile` - -**Exit code:** 1 - -``` -VITE+ - The Unified Toolchain for the Web - -yarn < 4.0.0 does not support --fix-lockfile. -``` - -## `vp add testnpm2 --ignore-scripts` - -Yarn 2 supports skip-builds for install, but not for add. - -**Exit code:** 1 - -``` -yarn >= 2 && < 3 does not support --ignore-scripts. -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md deleted file mode 100644 index 82ff88486a..0000000000 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/pm_option_version_guards/snapshots/yarn_option_version_guards.local.md +++ /dev/null @@ -1,21 +0,0 @@ -# yarn_option_version_guards - -## `vp install --fix-lockfile` - -``` -Already up to date - -Done in using pnpm -``` - -## `vp add testnpm2 --ignore-scripts` - -Yarn 2 supports skip-builds for install, but not for add. - -``` - -dependencies: - testnpm2 1.0.1 - -Done in using pnpm -``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots.toml index 11a8ef123d..65d95c9c76 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots.toml @@ -8,4 +8,6 @@ steps = [ { argv = ["vp", "run", "install"], continue-on-failure = true }, { argv = ["vpt", "list-dir", "node_modules"], continue-on-failure = true }, { argv = ["vp", "run", "install"], comment = "install again hit cache", continue-on-failure = true }, + { argv = ["vpt", "json-edit", "package.json", "packageManager", "yarn@2.4.2"], snapshot = false }, + { argv = ["vp", "install", "--fix-lockfile"], comment = "Reject lockfile refresh before Yarn 4.", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md index ded964df8c..92994e3a01 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md @@ -75,3 +75,16 @@ success Already up-to-date. Done in . ``` + +## `vpt json-edit package.json packageManager yarn@2.4.2` + + +## `vp install --fix-lockfile` + +Reject lockfile refresh before Yarn 4. + +**Exit code:** 1 + +``` +yarn < 4.0.0 does not support --fix-lockfile. +``` From 3bc8c22d5812e5e3e5575f2a32d83db6332104da Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 22:59:43 +0900 Subject: [PATCH 5/6] fix(pm): require Bun 1.4 for workspace updates Apply the same minimum version to recursive and filtered updates in both interactive and noninteractive modes. Remove the interactive exception and use the shared option guards. Cover stable and prerelease rejection in resolver tests and update the existing Bun command snapshots. Reference: https://bun.com/blog/bun-v1.4 --- .../command_update_bun/snapshots.toml | 6 ++- .../snapshots/command_update_bun.md | 26 +++++++++++-- .../src/resolution/commands/update.rs | 39 ++++++++----------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml index 58c2732672..ebd374f6f1 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots.toml @@ -11,6 +11,8 @@ steps = [ { argv = ["vpt", "json-edit", "package.json", "packageManager", "bun@1.3.14"], snapshot = false }, { argv = ["vp", "update", "--prod"], comment = "Reject production dependency selection before Bun 1.4.", continue-on-failure = true }, { argv = ["vp", "update", "--no-optional"], comment = "Reject optional dependency exclusion before Bun 1.4.", continue-on-failure = true }, - { argv = ["vp", "update", "--recursive"], comment = "Reject noninteractive recursive updates before Bun 1.4.", continue-on-failure = true }, - { argv = ["vp", "update", "--filter", "app"], comment = "Older Bun supports filters only in interactive update.", continue-on-failure = true }, + { argv = ["vp", "update", "--recursive"], comment = "Reject recursive updates before Bun 1.4.", continue-on-failure = true }, + { argv = ["vp", "update", "--filter", "app"], comment = "Reject filtered updates before Bun 1.4.", continue-on-failure = true }, + { argv = ["vp", "update", "--interactive", "--recursive"], comment = "Interactive updates use the same Bun version requirement.", continue-on-failure = true }, + { argv = ["vp", "update", "--interactive", "--filter", "app"], continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md index a1c9645e7c..705ae9d795 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_bun/snapshots/command_update_bun.md @@ -123,20 +123,38 @@ bun < 1.4 does not support --no-optional. ## `vp update --recursive` -Reject noninteractive recursive updates before Bun 1.4. +Reject recursive updates before Bun 1.4. **Exit code:** 1 ``` -bun < 1.4 does not support --recursive without --interactive. +bun < 1.4 does not support --recursive. ``` ## `vp update --filter app` -Older Bun supports filters only in interactive update. +Reject filtered updates before Bun 1.4. **Exit code:** 1 ``` -bun < 1.4 does not support --filter without --interactive. +bun < 1.4 does not support --filter. +``` + +## `vp update --interactive --recursive` + +Interactive updates use the same Bun version requirement. + +**Exit code:** 1 + +``` +bun < 1.4 does not support --recursive. +``` + +## `vp update --interactive --filter app` + +**Exit code:** 1 + +``` +bun < 1.4 does not support --filter. ``` diff --git a/crates/vp_pm_cli/src/resolution/commands/update.rs b/crates/vp_pm_cli/src/resolution/commands/update.rs index 3b58c251f8..16104a71e0 100644 --- a/crates/vp_pm_cli/src/resolution/commands/update.rs +++ b/crates/vp_pm_cli/src/resolution/commands/update.rs @@ -29,11 +29,11 @@ pub struct UpdateArgs { pub(crate) ignore_node_mismatch: bool, /// Update recursively in all workspace packages - #[arg(short = 'r', long, not_supported(npm < "8.1.0", yarn < "2"))] + #[arg(short = 'r', long, not_supported(npm < "8.1.0", yarn < "2", bun < "1.4"))] pub(crate) recursive: bool, /// Filter packages in monorepo (can be used multiple times) - #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn >= "2"))] + #[arg(long, value_name = "PATTERN", not_supported(npm < "7.14.0", yarn >= "2", bun < "1.4"))] pub(crate) filter: Vec, /// Include workspace root @@ -162,20 +162,6 @@ impl Yarn { impl Resolve for Bun { fn resolve(&self, args: &UpdateArgs, _diag: &mut Diagnostics) -> CommandResolution { - if !self.supports_v1_4_commands() && !args.interactive { - for (option, active) in - [("--recursive", args.recursive), ("--filter", !args.filter.is_empty())] - { - if active { - return CommandResolution::InvalidArgument( - vt_str::format!( - "bun < 1.4 does not support {option} without --interactive." - ) - .to_string(), - ); - } - } - } let mut cmd = CommandBuilder::new("bun"); cmd.arg("update") .repeated("--filter", args.filter.iter()) @@ -803,6 +789,7 @@ mod tests { expect_unsupported( resolve(&bun("1.3.14"), args), &[ + "bun < 1.4 does not support --filter.", "bun does not support --workspace-root.", "bun < 1.4 does not support --dev.", "bun < 1.4 does not support --prod.", @@ -861,12 +848,18 @@ mod tests { } #[test] - fn test_bun_update_rejects_filter_before_1_4() { - let options = UpdateArgs { filter: vec!["web".to_string()], ..Default::default() }; - let resolution = resolve(&bun("1.3.11"), options); - expect_unsupported( - resolution, - &["bun < 1.4 does not support --filter without --interactive."], - ); + fn test_bun_update_rejects_workspace_selection_before_1_4() { + for version in ["1.3.11", "1.3.14", "1.4.0-beta.1"] { + for interactive in [false, true] { + for (argv, message) in [ + (vec!["--recursive"], "bun < 1.4 does not support --recursive."), + (vec!["--filter", "web"], "bun < 1.4 does not support --filter."), + ] { + let mut args = parse_args::(argv).unwrap(); + args.interactive = interactive; + expect_unsupported(resolve(&bun(version), args), &[message]); + } + } + } } } From e412e7d56c5e77fa1a8d3c42d6ce9ccfb5de9b98 Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Mon, 19 Oct 2026 23:19:47 +0900 Subject: [PATCH 6/6] refactor(pm): shorten Yarn lockfile refresh version bound --- .../snapshots/yarn_install_with_options.md | 2 +- crates/vp_pm_cli/src/resolution/commands/install.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md index 92994e3a01..e8afc63b7c 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/yarn_install_with_options/snapshots/yarn_install_with_options.md @@ -86,5 +86,5 @@ Reject lockfile refresh before Yarn 4. **Exit code:** 1 ``` -yarn < 4.0.0 does not support --fix-lockfile. +yarn < 4 does not support --fix-lockfile. ``` diff --git a/crates/vp_pm_cli/src/resolution/commands/install.rs b/crates/vp_pm_cli/src/resolution/commands/install.rs index f63e5f99d1..bc9d5c7af3 100644 --- a/crates/vp_pm_cli/src/resolution/commands/install.rs +++ b/crates/vp_pm_cli/src/resolution/commands/install.rs @@ -60,7 +60,7 @@ pub struct InstallArgs { pub(crate) no_lockfile: bool, /// Fix broken lockfile entries (pnpm and yarn@4+ only) - #[arg(long, not_supported(npm, bun, yarn < "4.0.0"))] + #[arg(long, not_supported(npm, bun, yarn < "4"))] pub(crate) fix_lockfile: bool, /// Create flat `node_modules` (pnpm only)