fix: make postinstall patcher idempotent

This commit is contained in:
Peter Steinberger
2026-01-13 23:12:27 +00:00
parent 45c314fbe6
commit 4c932edabc
3 changed files with 71 additions and 0 deletions

View File

@@ -1,5 +1,10 @@
# Changelog
## 2026.1.13 (Unreleased)
### Fixes
- Postinstall: treat already-applied pnpm patches as no-ops to avoid npm/bun install failures.
## 2026.1.12-2
### Fixes

View File

@@ -149,6 +149,26 @@ function writeFileLines(targetPath, lines, hadTrailingNewline) {
function applyHunk(lines, hunk, offset) {
let cursor = hunk.oldStart - 1 + offset;
const expected = [];
for (const raw of hunk.lines) {
const marker = raw[0];
if (marker === " " || marker === "+") {
expected.push(raw.slice(1));
}
}
if (cursor >= 0 && cursor + expected.length <= lines.length) {
let alreadyApplied = true;
for (let i = 0; i < expected.length; i += 1) {
if (lines[cursor + i] !== expected[i]) {
alreadyApplied = false;
break;
}
}
if (alreadyApplied) {
const delta = hunk.newLines - hunk.oldLines;
return offset + delta;
}
}
for (const raw of hunk.lines) {
const marker = raw[0];

View File

@@ -74,6 +74,52 @@ index 0000000..1111111 100644
fs.rmSync(dir, { recursive: true, force: true });
});
it("treats already-applied hunks as no-ops", () => {
const dir = makeTempDir();
const target = path.join(dir, "lib");
fs.mkdirSync(target);
const filePath = path.join(target, "main.js");
const original = `${[
"var QRCode = require('./../vendor/QRCode'),",
" QRErrorCorrectLevel = require('./../vendor/QRCode/QRErrorCorrectLevel'),",
' black = "\\033[40m \\033[0m",',
' white = "\\033[47m \\033[0m",',
" toCell = function (isBlack) {",
].join("\n")}\n`;
fs.writeFileSync(filePath, original, "utf-8");
const patchText = `diff --git a/lib/main.js b/lib/main.js
index 0000000..1111111 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,5 +1,5 @@
-var QRCode = require('./../vendor/QRCode'),
- QRErrorCorrectLevel = require('./../vendor/QRCode/QRErrorCorrectLevel'),
+var QRCode = require('./../vendor/QRCode/index.js'),
+ QRErrorCorrectLevel = require('./../vendor/QRCode/QRErrorCorrectLevel.js'),
black = "\\033[40m \\033[0m",
white = "\\033[47m \\033[0m",
toCell = function (isBlack) {
`;
applyPatchSet({ patchText, targetDir: dir });
applyPatchSet({ patchText, targetDir: dir });
const updated = fs.readFileSync(filePath, "utf-8");
expect(updated).toBe(
`${[
"var QRCode = require('./../vendor/QRCode/index.js'),",
" QRErrorCorrectLevel = require('./../vendor/QRCode/QRErrorCorrectLevel.js'),",
' black = "\\033[40m \\033[0m",',
' white = "\\033[47m \\033[0m",',
" toCell = function (isBlack) {",
].join("\n")}\n`,
);
fs.rmSync(dir, { recursive: true, force: true });
});
it("handles multiple hunks with offsets", () => {
const dir = makeTempDir();
const filePath = path.join(dir, "file.txt");