From 7cd0d20bb27e49354187cacce3fdd4ae090127f2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 4 Nov 2024 12:14:00 +1100 Subject: [PATCH] fix: headless install crash when modules dir disabled and patches listed (#8727) close #8726 --- .changeset/orange-flies-hammer.md | 5 + .changeset/rotten-olives-visit.md | 5 + pkg-manager/headless/src/index.ts | 2 +- .../fixtures/simple-with-patch/package.json | 19 +++ .../patches/is-positive.patch | 10 ++ .../fixtures/simple-with-patch/pnpm-lock.yaml | 133 ++++++++++++++++++ pkg-manager/headless/test/index.ts | 11 ++ 7 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 .changeset/orange-flies-hammer.md create mode 100644 .changeset/rotten-olives-visit.md create mode 100644 pkg-manager/headless/test/fixtures/simple-with-patch/package.json create mode 100644 pkg-manager/headless/test/fixtures/simple-with-patch/patches/is-positive.patch create mode 100644 pkg-manager/headless/test/fixtures/simple-with-patch/pnpm-lock.yaml diff --git a/.changeset/orange-flies-hammer.md b/.changeset/orange-flies-hammer.md new file mode 100644 index 0000000000..c7911c819e --- /dev/null +++ b/.changeset/orange-flies-hammer.md @@ -0,0 +1,5 @@ +--- +"@pnpm/core": patch +--- + +Fix for headless install crashing when modules directory disabled (`enable-modules-dir` set to `false`) and patched dependencies are present [#8727](https://github.com/pnpm/pnpm/pull/8727). diff --git a/.changeset/rotten-olives-visit.md b/.changeset/rotten-olives-visit.md new file mode 100644 index 0000000000..d088254b5b --- /dev/null +++ b/.changeset/rotten-olives-visit.md @@ -0,0 +1,5 @@ +--- +"@pnpm/headless": patch +--- + +Don't attempt to apply patches when modules directory disabled (`enable-modules-dir` set to `false`) [#8727](https://github.com/pnpm/pnpm/pull/8727). diff --git a/pkg-manager/headless/src/index.ts b/pkg-manager/headless/src/index.ts index 221982f2b3..ff82470ab1 100644 --- a/pkg-manager/headless/src/index.ts +++ b/pkg-manager/headless/src/index.ts @@ -498,7 +498,7 @@ export async function headlessInstall (opts: HeadlessOptions): Promise depPath) ) } - if (!opts.ignoreScripts || Object.keys(opts.patchedDependencies ?? {}).length > 0) { + if ((!opts.ignoreScripts || Object.keys(opts.patchedDependencies ?? {}).length > 0) && opts.enableModulesDir !== false) { const directNodes = new Set() for (const id of union(importerIds, ['.'])) { const directDependencies = directDependenciesByImporterId[id] diff --git a/pkg-manager/headless/test/fixtures/simple-with-patch/package.json b/pkg-manager/headless/test/fixtures/simple-with-patch/package.json new file mode 100644 index 0000000000..8b64466d17 --- /dev/null +++ b/pkg-manager/headless/test/fixtures/simple-with-patch/package.json @@ -0,0 +1,19 @@ +{ + "name": "simple", + "version": "1.0.0", + "dependencies": { + "is-positive": "^1.0.0", + "rimraf": "^2.6.2" + }, + "devDependencies": { + "is-negative": "^2.1.0" + }, + "optionalDependencies": { + "colors": "1.2.0" + }, + "pnpm": { + "patchedDependencies": { + "is-positive": "patches/is-positive.patch" + } + } +} diff --git a/pkg-manager/headless/test/fixtures/simple-with-patch/patches/is-positive.patch b/pkg-manager/headless/test/fixtures/simple-with-patch/patches/is-positive.patch new file mode 100644 index 0000000000..02261cc2e4 --- /dev/null +++ b/pkg-manager/headless/test/fixtures/simple-with-patch/patches/is-positive.patch @@ -0,0 +1,10 @@ +diff --git a/index.js b/index.js +index 8e020cac3320e72cb40e66b4c4573cc51c55e1e4..8be55d95c50a2a28e021e586ce5b928d9fea140e 100644 +--- a/index.js ++++ b/index.js +@@ -7,3 +7,5 @@ module.exports = function (n) { + + return n >= 0; + }; ++ ++// a change diff --git a/pkg-manager/headless/test/fixtures/simple-with-patch/pnpm-lock.yaml b/pkg-manager/headless/test/fixtures/simple-with-patch/pnpm-lock.yaml new file mode 100644 index 0000000000..c64f169a9e --- /dev/null +++ b/pkg-manager/headless/test/fixtures/simple-with-patch/pnpm-lock.yaml @@ -0,0 +1,133 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +patchedDependencies: + is-positive: + hash: 2mxqxzgazgkaqoljbgoadrshgq + path: patches/is-positive.patch + +importers: + + .: + dependencies: + is-positive: + specifier: ^1.0.0 + version: 1.0.0(patch_hash=2mxqxzgazgkaqoljbgoadrshgq) + rimraf: + specifier: ^2.6.2 + version: 2.7.1 + optionalDependencies: + colors: + specifier: 1.2.0 + version: 1.2.0 + devDependencies: + is-negative: + specifier: ^2.1.0 + version: 2.1.0 + +packages: + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + colors@1.2.0: + resolution: {integrity: sha512-lweugcX5nailCqZBttArTojZZpHGWhmFJX78KJHlxwhM8tLAy5QCgRgRxrubrksdvA+2Y3inWG5TToyyjL82BQ==} + engines: {node: '>=0.1.90'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-negative@2.1.0: + resolution: {integrity: sha512-+iCKT4ZcvjRnjkHnQjZ8/qfciLLGD8BFKS0GNR5VjDU6jEiwh899R0GSMkaYcuTNd7fEKXb3Qib0webe6HczNw==} + engines: {node: '>=0.10.0'} + + is-positive@1.0.0: + resolution: {integrity: sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==} + engines: {node: '>=0.10.0'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + +snapshots: + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + colors@1.2.0: + optional: true + + concat-map@0.0.1: {} + + fs.realpath@1.0.0: {} + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-negative@2.1.0: {} + + is-positive@1.0.0(patch_hash=2mxqxzgazgkaqoljbgoadrshgq): {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + path-is-absolute@1.0.1: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + wrappy@1.0.2: {} diff --git a/pkg-manager/headless/test/index.ts b/pkg-manager/headless/test/index.ts index 060d470811..3e31dc416e 100644 --- a/pkg-manager/headless/test/index.ts +++ b/pkg-manager/headless/test/index.ts @@ -789,6 +789,17 @@ test('installing with no modules directory', async () => { expect(fs.existsSync(path.join(prefix, 'node_modules'))).toBeFalsy() }) +test('installing with no modules directory and a patched dependency', async () => { + const prefix = f.prepare('simple-with-patch') + + await headlessInstall(await testDefaults({ + enableModulesDir: false, + lockfileDir: prefix, + })) + + expect(fs.existsSync(path.join(prefix, 'node_modules'))).toBeFalsy() +}) + test('installing with node-linker=hoisted', async () => { const prefix = f.prepare('has-several-versions-of-same-pkg')