diff --git a/Cargo.toml b/Cargo.toml index 9f47ae59f5..6f7b2b8abc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,12 +184,53 @@ allow_branch = "main" unexpected_cfgs = { level = "warn", check-cfg = ['cfg(dylint_lib, values("perfectionist"))'] } [workspace.lints.clippy] -clone_on_ref_ptr = "warn" -if_then_some_else_none = "warn" -needless_collect = "warn" -or_fun_call = "warn" -redundant_clone = "warn" -unnecessary_lazy_evaluations = "warn" +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } + +doc_link_with_quotes = "allow" # false positive: matches markdown link titles +unreadable_literal = "allow" # false positive: octal file modes +case_sensitive_file_extension_comparisons = "allow" # extension checks are intentionally case-sensitive +implicit_hasher = "allow" # only matters across a public API +unnecessary_debug_formatting = "allow" # keeps the quoted `Path` output +option_option = "allow" # distinguishes missing from null +cast_possible_truncation = "allow" # deliberate numeric narrowing +cast_sign_loss = "allow" +cast_possible_wrap = "allow" +cast_precision_loss = "allow" +missing_errors_doc = "allow" # error enums are self-documenting (#[display] + #[diagnostic(code)]); a # Errors section would just restate them +missing_panics_doc = "allow" # deferred: refactor away / document / #[expect] each panic before enabling +too_many_lines = "allow" # pacquet mirrors pnpm's function decomposition +struct_excessive_bools = "allow" # option structs mirror pnpm's +fn_params_excessive_bools = "allow" # mirrors pnpm's option parameters +match_same_arms = "allow" # arms kept explicit to mirror pnpm's switch cases +unnecessary_wraps = "allow" +unused_async = "allow" # deferred: audit each async signature (trait/seam-required?) before enabling +similar_names = "allow" # names ported verbatim from pnpm +items_after_statements = "allow" +needless_continue = "allow" +many_single_char_names = "allow" # perfectionist's single_letter_* lints already cover this with finer per-position control + +# nursery-group opt-outs (the group is experimental; these lints are either +# false positives on this code or fight conventions the project keeps on purpose) +use_self = "allow" # spelling out the concrete type name over Self is left to author discretion +too_long_first_doc_paragraph = "allow" # doc comments deliberately open with a detailed pnpm-parity summary, not a one-line lede +missing_const_for_fn = "allow" # const-ness is a forward semver commitment and this nursery lint is noisy / churns as const-eval grows +option_if_let_else = "allow" # the suggested map_or_else closures read worse than the if-let they replace +significant_drop_tightening = "allow" # the flagged guards are held deliberately (atomic check-then-act); early-dropping is FP-prone and behavioral +redundant_pub_crate = "allow" # pub(crate) is kept to document intended visibility even where technically redundant +derive_partial_eq_without_eq = "allow" # deriving Eq is a forward semver commitment that all fields stay Eq +branches_sharing_code = "allow" # false-positive-prone: clippy itself flags its own suggestion as needing adjustment +useless_let_if_seq = "allow" # rewrites large init blocks into an awkward if-as-expression +single_option_map = "allow" # flags test helpers that exist precisely to dedupe a `.map` over an Option +iter_with_drain = "allow" # false positive: drain(..) reuses the batch Vec's allocation across loop iterations; into_iter() would consume it +literal_string_with_formatting_args = "allow" # false positive: `${VAR:-default}` strings are .npmrc / env-replace fixtures, not Rust format args +collection_is_never_read = "allow" # false positive: the flagged Vec owns sockets to keep them alive, it is never meant to be read + +# restriction lints opted into individually — not part of any default group or +# the nursery group, so these lines are what enable them (kept on purpose). +clone_on_ref_ptr = "warn" +if_then_some_else_none = "warn" +mod_module_files = "warn" # forbids mod.rs, enforcing the flat module.rs layout (see CODE_STYLE_GUIDE.md) [profile.release] opt-level = 3 diff --git a/pacquet/CODE_STYLE_GUIDE.md b/pacquet/CODE_STYLE_GUIDE.md index 7119d01bbd..2dcdfd4ff0 100644 --- a/pacquet/CODE_STYLE_GUIDE.md +++ b/pacquet/CODE_STYLE_GUIDE.md @@ -46,7 +46,7 @@ Follow [the Rust API guidelines](https://rust-lang.github.io/api-guidelines/nami ### Module Organization -- Use the flat file pattern (`module.rs`) rather than `module/mod.rs` for submodules. Enforced by [`perfectionist::flat_module_pattern`](https://github.com/KSXGitHub/perfectionist/blob/0.0.0-rc.17/rules/flat_module_pattern.md). +- Use the flat file pattern (`module.rs`) rather than `module/mod.rs` for submodules. Enforced by [`clippy::mod_module_files`](https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files), which bans `mod.rs` files. (`perfectionist::flat_module_pattern` covered this previously and is being retired in favor of the Clippy rule.) - List `pub mod` declarations first, then `pub use` re-exports, then private imports and items. - Use `pub use` to re-export key types at the module level for convenience. diff --git a/pacquet/crates/catalogs-protocol-parser/src/lib.rs b/pacquet/crates/catalogs-protocol-parser/src/lib.rs index 84ccc690ba..6d32e890cc 100644 --- a/pacquet/crates/catalogs-protocol-parser/src/lib.rs +++ b/pacquet/crates/catalogs-protocol-parser/src/lib.rs @@ -18,6 +18,7 @@ const CATALOG_PROTOCOL: &str = "catalog:"; /// /// Mirrors upstream's `parseCatalogProtocol` /// ([source](https://github.com/pnpm/pnpm/blob/a8a8cbce6d/catalogs/protocol-parser/src/parseCatalogProtocol.ts#L3-L16)). +#[must_use] pub fn parse_catalog_protocol(bare_specifier: &str) -> Option<&str> { let raw = bare_specifier.strip_prefix(CATALOG_PROTOCOL)?.trim(); Some(if raw.is_empty() { DEFAULT_CATALOG_NAME } else { raw }) diff --git a/pacquet/crates/catalogs-resolver/src/lib.rs b/pacquet/crates/catalogs-resolver/src/lib.rs index e34e5462d2..2670f6b79a 100644 --- a/pacquet/crates/catalogs-resolver/src/lib.rs +++ b/pacquet/crates/catalogs-resolver/src/lib.rs @@ -114,6 +114,7 @@ pub enum CatalogResolutionError { /// /// Mirrors upstream's `resolveFromCatalog` /// ([source](https://github.com/pnpm/pnpm/blob/a8a8cbce6d/catalogs/resolver/src/resolveFromCatalog.ts#L60-L130)). +#[must_use] pub fn resolve_from_catalog( catalogs: &Catalogs, wanted_dependency: &WantedDependency, diff --git a/pacquet/crates/cli/src/cli_args.rs b/pacquet/crates/cli/src/cli_args.rs index 0611fb20ef..84661399e5 100644 --- a/pacquet/crates/cli/src/cli_args.rs +++ b/pacquet/crates/cli/src/cli_args.rs @@ -313,8 +313,7 @@ impl CliArgs { let manifest = PackageManifest::from_path(manifest_path()) .wrap_err("getting the package.json in current directory")?; if let Some(script) = manifest.script("test", false)? { - execute_shell(script) - .wrap_err(format!("executing command: \"{0}\"", script))?; + execute_shell(script).wrap_err(format!("executing command: \"{script}\""))?; } } CliCommand::Run(args) => { @@ -343,7 +342,7 @@ impl CliArgs { let manifest = PackageManifest::from_path(manifest_path()) .wrap_err("getting the package.json in current directory")?; let command = manifest.script("start", true)?.unwrap_or("node server.js"); - execute_shell(command).wrap_err(format!("executing command: \"{0}\"", command))?; + execute_shell(command).wrap_err(format!("executing command: \"{command}\""))?; } CliCommand::Store(command) => command.run(|| config().map(|m| &*m))?, } diff --git a/pacquet/crates/cli/src/cli_args/add.rs b/pacquet/crates/cli/src/cli_args/add.rs index 5ee147b1e9..2279b67f3f 100644 --- a/pacquet/crates/cli/src/cli_args/add.rs +++ b/pacquet/crates/cli/src/cli_args/add.rs @@ -27,7 +27,6 @@ impl AddDependencyOptions { /// Whether to add entry to `"dependencies"`. /// /// **NOTE:** no `--save-*` flags implies save as prod. - #[inline(always)] fn save_prod(&self) -> bool { let &AddDependencyOptions { save_prod, save_dev, save_optional, save_peer } = self; save_prod || (!save_dev && !save_optional && !save_peer) @@ -36,20 +35,17 @@ impl AddDependencyOptions { /// Whether to add entry to `"devDependencies"`. /// /// **NOTE:** `--save-peer` without any other `--save-*` flags implies save as dev. - #[inline(always)] fn save_dev(&self) -> bool { let &AddDependencyOptions { save_prod, save_dev, save_optional, save_peer } = self; save_dev || (!save_prod && !save_optional && save_peer) } /// Whether to add entry to `"optionalDependencies"`. - #[inline(always)] fn save_optional(&self) -> bool { self.save_optional } /// Whether to add entry to `"peerDependencies"`. - #[inline(always)] fn save_peer(&self) -> bool { self.save_peer } @@ -104,7 +100,7 @@ pub struct AddArgs { /// is created. Mirrors pnpm's `--lockfile-only`. #[clap(long = "lockfile-only")] pub lockfile_only: bool, - /// The directory with links to the store (default is node_modules/.pacquet). + /// The directory with links to the store (default is `node_modules/.pacquet`). /// All direct and indirect dependencies of the project are linked into this directory #[clap(long = "virtual-store-dir", default_value = "node_modules/.pacquet")] pub virtual_store_dir: Option, // TODO: make use of this diff --git a/pacquet/crates/cli/src/cli_args/dlx.rs b/pacquet/crates/cli/src/cli_args/dlx.rs index 77a1ac59fd..82a4c86bd4 100644 --- a/pacquet/crates/cli/src/cli_args/dlx.rs +++ b/pacquet/crates/cli/src/cli_args/dlx.rs @@ -195,9 +195,10 @@ impl DlxArgs { .wrap_err("canonicalizing the dlx cache directory")?; let cache_link = dlx_command_cache_dir.join("pkg"); - let cached_dir = match get_valid_cache_dir(&cache_link, max_age, SystemTime::now()) { - Some(dir) => dir, - None => { + let cached_dir = + if let Some(dir) = get_valid_cache_dir(&cache_link, max_age, SystemTime::now()) { + dir + } else { let prepare_dir = get_prepare_dir(&dlx_command_cache_dir, SystemTime::now(), std::process::id()); if let Err(error) = install_into_cache::( @@ -221,8 +222,7 @@ impl DlxArgs { // ignore the failure and run from our own prepare dir. let _ = force_symlink_dir(&prepare_dir, &cache_link); prepare_dir - } - }; + }; let bins_dir = cached_dir.join("node_modules").join(".bin"); let bin_name = @@ -445,7 +445,7 @@ fn get_valid_cache_dir( /// prepared in. Ports `getPrepareDir` /// (). fn get_prepare_dir(cache_path: &Path, now: SystemTime, pid: u32) -> PathBuf { - let millis = now.duration_since(UNIX_EPOCH).map(|elapsed| elapsed.as_millis()).unwrap_or(0); + let millis = now.duration_since(UNIX_EPOCH).map_or(0, |elapsed| elapsed.as_millis()); cache_path.join(format!("{millis:x}-{pid:x}")) } @@ -503,7 +503,7 @@ fn read_json(path: &Path) -> Result { /// (dlx.ts:297-302). fn scopeless(pkg_name: &str) -> &str { if let Some(rest) = pkg_name.strip_prefix('@') { - rest.split_once('/').map(|(_, name)| name).unwrap_or(pkg_name) + rest.split_once('/').map_or(pkg_name, |(_, name)| name) } else { pkg_name } diff --git a/pacquet/crates/cli/src/cli_args/dlx/tests.rs b/pacquet/crates/cli/src/cli_args/dlx/tests.rs index dcbeef90e0..d7b9dbc5a0 100644 --- a/pacquet/crates/cli/src/cli_args/dlx/tests.rs +++ b/pacquet/crates/cli/src/cli_args/dlx/tests.rs @@ -177,10 +177,14 @@ fn get_valid_cache_dir_honors_max_age() { ); // Past the window: expired. - let past = mtime + Duration::from_secs(1440 * 60 + 60); + let past = mtime + Duration::from_mins(1441); assert!(get_valid_cache_dir(&link, 1440, past).is_none(), "an expired link must be rejected"); } +#[expect( + clippy::needless_pass_by_value, + reason = "test helper called from multiple sites with owned literals; by-value keeps the call sites clean" +)] fn write_pkg(dir: &std::path::Path, name: &str, manifest: serde_json::Value) { let pkg_dir = dir.join("node_modules").join(name); fs::create_dir_all(&pkg_dir).expect("create pkg dir"); diff --git a/pacquet/crates/cli/src/cli_args/install.rs b/pacquet/crates/cli/src/cli_args/install.rs index 35d35a04c9..39ca801363 100644 --- a/pacquet/crates/cli/src/cli_args/install.rs +++ b/pacquet/crates/cli/src/cli_args/install.rs @@ -37,13 +37,13 @@ impl NodeLinkerArg { #[derive(Debug, Args)] pub struct InstallDependencyOptions { /// pacquet will not install any package listed in devDependencies and will remove those insofar - /// they were already installed, if the NODE_ENV environment variable is set to production. - /// Use this flag to instruct pacquet to ignore NODE_ENV and take its production status from this + /// they were already installed, if the `NODE_ENV` environment variable is set to production. + /// Use this flag to instruct pacquet to ignore `NODE_ENV` and take its production status from this /// flag instead. #[arg(short = 'P', long)] prod: bool, /// Only devDependencies are installed and dependencies are removed insofar they were - /// already installed, regardless of the NODE_ENV. + /// already installed, regardless of the `NODE_ENV`. #[arg(short = 'D', long)] dev: bool, /// optionalDependencies are not installed. @@ -302,7 +302,7 @@ impl InstallArgs { // `--node-linker` flag (if passed) overrides the // yaml/npmrc value for this invocation. Mirrors pnpm's // override-on-explicit-flag semantics. - let node_linker = node_linker.map(NodeLinkerArg::into_config).unwrap_or(config.node_linker); + let node_linker = node_linker.map_or(config.node_linker, NodeLinkerArg::into_config); // The lockfile-verification gate keys its on-disk cache off // `/pnpm-lock.yaml`. Once workspace support // lands (pacquet#431), this becomes `workspace_root` to @@ -466,9 +466,10 @@ async fn install_via_pnpr( .map_err(|err| miette::miette!("failed to serialize overrides: {err}"))?; let benchmark_registry_override = PnprBenchmarkRegistryOverride::from_env(&state.config.registry); - let resolve_registry = benchmark_registry_override - .as_ref() - .map_or_else(|| state.config.registry.clone(), |registry| registry.resolve_registry()); + let resolve_registry = benchmark_registry_override.as_ref().map_or_else( + || state.config.registry.clone(), + PnprBenchmarkRegistryOverride::resolve_registry, + ); // Send the on-disk lockfile + the full client policy so the server // verifies the input lockfile under *our* policy before resolving; diff --git a/pacquet/crates/cli/src/cli_args/outdated.rs b/pacquet/crates/cli/src/cli_args/outdated.rs index efb7568065..3ab451ef28 100644 --- a/pacquet/crates/cli/src/cli_args/outdated.rs +++ b/pacquet/crates/cli/src/cli_args/outdated.rs @@ -438,7 +438,7 @@ fn change_priority(change: Change) -> u8 { fn sort_outdated(outdated: &mut [OutdatedPackage], sort_by: Option) { match sort_by { Some(SortBy::Name) => { - outdated.sort_by(|left, right| left.package_name.cmp(&right.package_name)) + outdated.sort_by(|left, right| left.package_name.cmp(&right.package_name)); } None => outdated.sort_by(|left, right| { let by_change = change_priority(classify(&left.current, &left.target)) diff --git a/pacquet/crates/cli/src/cli_args/run.rs b/pacquet/crates/cli/src/cli_args/run.rs index fc217339f5..59aab72590 100644 --- a/pacquet/crates/cli/src/cli_args/run.rs +++ b/pacquet/crates/cli/src/cli_args/run.rs @@ -8,6 +8,7 @@ use serde_json::Value; use std::{ collections::HashMap, env, + fmt::Write as _, path::{Path, PathBuf}, }; @@ -295,7 +296,7 @@ pub(super) fn run_stages( /// Run one lifecycle stage. Returns `Ok(None)` when pnpm's per-stage /// no-op guards apply (empty body, or `npx only-allow pnpm` with no /// args), so the caller can record "didn't actually run" without -/// inventing a synthetic ExitStatus. A non-success ExitStatus is +/// inventing a synthetic `ExitStatus`. A non-success `ExitStatus` is /// returned to the caller — single-project `RunArgs::run` exits with /// the code; recursive `run_recursive` records `Failure` and decides /// whether to bail. @@ -322,7 +323,7 @@ pub(super) fn run_stage( return Ok(None); } - let status = run_script(RunScript { + let status = run_script(&RunScript { manifest: ctx.manifest.value(), stage, script, @@ -443,16 +444,14 @@ fn render_project_commands(manifest: &Value) -> String { let mut output = String::new(); if !lifecycle.is_empty() { - output.push_str(&format!("Lifecycle scripts:\n{}", render_commands(&lifecycle))); + write!(output, "Lifecycle scripts:\n{}", render_commands(&lifecycle)).unwrap(); } if !other.is_empty() { if !output.is_empty() { output.push_str("\n\n"); } - output.push_str(&format!( - "Commands available via \"pnpm run\":\n{}", - render_commands(&other), - )); + write!(output, "Commands available via \"pnpm run\":\n{}", render_commands(&other)) + .unwrap(); } output } diff --git a/pacquet/crates/cli/src/cli_args/run/recursive.rs b/pacquet/crates/cli/src/cli_args/run/recursive.rs index a01bf610c6..b0ae433d04 100644 --- a/pacquet/crates/cli/src/cli_args/run/recursive.rs +++ b/pacquet/crates/cli/src/cli_args/run/recursive.rs @@ -12,7 +12,7 @@ //! Scope versus upstream: projects are sorted topologically (upstream's //! default) and run sequentially. `--no-sort`, `--reverse`, //! `--workspace-concurrency` parallelism, `--filter` narrowing of the -//! selected set, and the RegExp script selector are not ported yet — the +//! selected set, and the `RegExp` script selector are not ported yet — the //! selected set is every workspace project, matching pacquet's //! currently-unfiltered `install`. diff --git a/pacquet/crates/cli/src/config_overrides.rs b/pacquet/crates/cli/src/config_overrides.rs index 8215e26efd..5e3af3347a 100644 --- a/pacquet/crates/cli/src/config_overrides.rs +++ b/pacquet/crates/cli/src/config_overrides.rs @@ -55,7 +55,7 @@ impl ConfigOverrides { /// Mirrors pnpm 11's "CLI > yaml > .npmrc > defaults" precedence. pub fn apply(&self, config: &mut Config) { if let Some(registry) = &self.registry { - config.registry = registry.clone(); + config.registry.clone_from(registry); } } } diff --git a/pacquet/crates/cli/src/lib.rs b/pacquet/crates/cli/src/lib.rs index 8ab2924672..1a7bd913d8 100644 --- a/pacquet/crates/cli/src/lib.rs +++ b/pacquet/crates/cli/src/lib.rs @@ -70,8 +70,7 @@ fn configure_rayon_pool() { return; } let n = std::thread::available_parallelism() - .map(std::num::NonZeroUsize::get) - .unwrap_or(1) + .map_or(1, std::num::NonZeroUsize::get) .saturating_mul(2) // `.max(4)` is an intentional minimum: even on quota-limited // 1-2-CPU runners, dropping below 4 puts us back into the diff --git a/pacquet/crates/cli/tests/_utils.rs b/pacquet/crates/cli/tests/_utils.rs index fe69dba5e9..11edfa2b9d 100644 --- a/pacquet/crates/cli/tests/_utils.rs +++ b/pacquet/crates/cli/tests/_utils.rs @@ -25,9 +25,10 @@ pub fn enable_gvs_in_workspace_yaml(workspace: &Path, extra_yaml: &str) { /// Snapshot-friendly view of every row in `/v11/index.db`. /// -/// The outer key is the SQLite key (`"{integrity}\t{pkgId}"`). The inner +/// The outer key is the `SQLite` key (`"{integrity}\t{pkgId}"`). The inner /// map is the package's files — one entry per path inside the tarball. /// `checked_at` is scrubbed because its value depends on install time. +#[must_use] pub fn index_file_contents(store_dir: &Path) -> BTreeMap> { let store = StoreDir::new(store_dir); // open_readonly: we're just reading for snapshot assertions, so don't diff --git a/pacquet/crates/cli/tests/hoist.rs b/pacquet/crates/cli/tests/hoist.rs index 01c18943f8..ea1fe1daf5 100644 --- a/pacquet/crates/cli/tests/hoist.rs +++ b/pacquet/crates/cli/tests/hoist.rs @@ -61,6 +61,10 @@ fn write_workspace_yaml(workspace: &Path, extra: &str) { } /// Write a one-dependency `package.json` and return the manifest path. +#[expect( + clippy::needless_pass_by_value, + reason = "test helper called many times with json!(...) literals; owned arg keeps call sites clean" +)] fn write_manifest(workspace: &Path, deps: serde_json::Value) { let manifest = serde_json::json!({ "dependencies": deps }); fs::write(workspace.join("package.json"), manifest.to_string()).expect("write package.json"); @@ -409,7 +413,7 @@ fn public_hoist_bin_is_linked_via_root_bin_dir() { } /// Workspace install (pnpm/pacquet#431) lands per-importer -/// node_modules layouts; hoist must walk every importer's direct +/// `node_modules` layouts; hoist must walk every importer's direct /// deps, not just the root, so transitives unique to a workspace /// project still reach the shared `/node_modules` private /// hoist. Sets up a two-importer workspace where the workspace @@ -812,7 +816,7 @@ mod known_failures { } /// Upstream: [`hoist.ts:514` "should recreate node_modules with hoisting"](https://github.com/pnpm/pnpm/blob/94240bc046/installing/deps-installer/test/install/hoist.ts#L514). - /// Removes node_modules and re-installs from the lockfile — + /// Removes `node_modules` and re-installs from the lockfile — /// needs partial-install state for the rehoist comparison. #[test] fn should_recreate_node_modules_with_hoisting() { diff --git a/pacquet/crates/cli/tests/hoisted_node_linker.rs b/pacquet/crates/cli/tests/hoisted_node_linker.rs index 4efef68e7f..b7610226b4 100644 --- a/pacquet/crates/cli/tests/hoisted_node_linker.rs +++ b/pacquet/crates/cli/tests/hoisted_node_linker.rs @@ -41,6 +41,10 @@ fn write_workspace_yaml(workspace: &Path, extra: &str) { } /// Write a `package.json` with the given `dependencies` object. +#[expect( + clippy::needless_pass_by_value, + reason = "test helper called many times with json!(...) literals; owned arg keeps call sites clean" +)] fn write_manifest(workspace: &Path, deps: serde_json::Value) { let manifest = serde_json::json!({ "dependencies": deps }); fs::write(workspace.join("package.json"), manifest.to_string()).expect("write package.json"); diff --git a/pacquet/crates/cli/tests/install.rs b/pacquet/crates/cli/tests/install.rs index e3b28631a4..e6898a7c23 100644 --- a/pacquet/crates/cli/tests/install.rs +++ b/pacquet/crates/cli/tests/install.rs @@ -953,6 +953,10 @@ fn compatible_existing_peer_contexts_survive_writable_lockfile_regeneration() { drop((root, mock_instance)); // cleanup } +#[expect( + clippy::needless_pass_by_value, + reason = "test fixture; the value is embedded whole into a serde_json::json! object" +)] fn install_with_peer_alias_deps(dependencies: serde_json::Value) -> String { let CommandTempCwd { pacquet, root, workspace, npmrc_info, .. } = CommandTempCwd::init().add_mocked_registry(); diff --git a/pacquet/crates/cli/tests/outdated.rs b/pacquet/crates/cli/tests/outdated.rs index 69cc66aaca..551fd126ba 100644 --- a/pacquet/crates/cli/tests/outdated.rs +++ b/pacquet/crates/cli/tests/outdated.rs @@ -263,7 +263,7 @@ fn outdated_long_shows_deprecation_details() { } /// An npm-aliased dependency is reported under its real registry name, -/// not the alias. Ports pnpm's "outdated() aliased dependency". +/// not the alias. Ports pnpm's "`outdated()` aliased dependency". #[test] fn outdated_npm_alias_reports_real_name() { let (root, workspace, anchor) = setup(); diff --git a/pacquet/crates/cli/tests/run.rs b/pacquet/crates/cli/tests/run.rs index 1605474f07..d13804badb 100644 --- a/pacquet/crates/cli/tests/run.rs +++ b/pacquet/crates/cli/tests/run.rs @@ -45,9 +45,9 @@ fn run_executes_declared_script() { } /// Positional arguments after the script name flow through to the -/// spawned shell verbatim, joined by spaces. Mirrors `pnpm run -///