test(cli): pin --force against the repeat-install fast path (#15095)
A forced install re-materializes every slot, so the fast path must not short-circuit it on an unchanged workspace. Nothing named that gate: it was caught only incidentally, by a global-virtual-store test that would have failed on stale bytes rather than on the reason for them. Assert the observable signal instead — a forced install does not report "Already up to date". Verified by removing the gate, which fails the new test on its own assertion. `install.rs` rather than `repeat_install.rs` so the case also runs on Windows; the latter is `#![cfg(unix)]`. The one-line note on `Config::force` replaces a sentence that described the frozen path's skip discard as though it were the whole rule. Related to pnpm/pnpm#15094
This commit is contained in:
1 parent
6ea6aaf72c
commit
ea9f3bf4a0
2 files changed
+47
-4
No files matched your search
@@ -738,6 +738,50 @@ fn set_dir_modes(path: &std::path::Path, mode: u32) {
|
||||
fs::set_permissions(path, fs::Permissions::from_mode(mode)).expect("set directory mode");
|
||||
}
|
||||
|
||||
/// The gate exists because `--force` re-materializes every slot, not only
|
||||
/// because it bypasses the platform checks.
|
||||
#[test]
|
||||
fn force_defeats_the_up_to_date_fast_path() {
|
||||
let CommandTempCwd {
|
||||
pacquet,
|
||||
root,
|
||||
workspace,
|
||||
npmrc_info,
|
||||
..
|
||||
} = CommandTempCwd::init().add_mocked_registry();
|
||||
let AddMockedRegistry { mock_instance, .. } = npmrc_info;
|
||||
fs::write(
|
||||
workspace.join("package.json"),
|
||||
serde_json::json!({ "dependencies": { "@foo/no-deps": "1.0.0" } }).to_string(),
|
||||
)
|
||||
.expect("write package.json");
|
||||
|
||||
let run_install = |args: &[&str]| {
|
||||
let assert = pacquet_in(&workspace)
|
||||
.with_env("PNPM_CONFIG_REGISTRY", mock_instance.url())
|
||||
.with_args(args)
|
||||
.assert()
|
||||
.success();
|
||||
String::from_utf8_lossy(&assert.get_output().stdout).into_owned()
|
||||
};
|
||||
|
||||
pacquet
|
||||
.with_env("PNPM_CONFIG_REGISTRY", mock_instance.url())
|
||||
.with_arg("install")
|
||||
.assert()
|
||||
.success();
|
||||
assert!(
|
||||
run_install(&["install"]).contains("Already up to date"),
|
||||
"an unchanged repeat install must take the fast path",
|
||||
);
|
||||
assert!(
|
||||
!run_install(&["install", "--force"]).contains("Already up to date"),
|
||||
"--force must defeat the fast path even though nothing changed",
|
||||
);
|
||||
|
||||
drop((root, mock_instance));
|
||||
}
|
||||
|
||||
/// Trust/policy settings key the lockfile-verification gate, which is
|
||||
/// why pnpm records `trustPolicy*` in the workspace state.
|
||||
#[test]
|
||||
|
||||
@@ -849,12 +849,11 @@ pub struct Config {
|
||||
/// instead of skipped, mirroring pnpm's `!opts.force &&
|
||||
/// packageIsInstallable(...)` gate in its dep-graph builders.
|
||||
///
|
||||
/// It also re-materializes every slot, changed or not.
|
||||
///
|
||||
/// CLI-only (merged from `--force` on `pnpm install` / `pnpm add` /
|
||||
/// `pnpm deploy` at the dispatch, like `ignoreScripts`); not a
|
||||
/// `pnpm-workspace.yaml` / `.npmrc` setting. On the frozen path it
|
||||
/// also discards the previous install's per-snapshot skip decision,
|
||||
/// mirroring pnpm's `lockfileToDepGraph(…, opts.force ? null :
|
||||
/// currentLockfile)`, so already-materialized packages are relinked.
|
||||
/// `pnpm-workspace.yaml` / `.npmrc` setting.
|
||||
pub force: bool,
|
||||
|
||||
/// Whether to consult the side-effects cache
|
||||
|
||||
Reference in new issue
Block a user