fix: make postinstall patcher idempotent
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# 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
|
## 2026.1.12-2
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
@@ -149,6 +149,26 @@ function writeFileLines(targetPath, lines, hadTrailingNewline) {
|
|||||||
|
|
||||||
function applyHunk(lines, hunk, offset) {
|
function applyHunk(lines, hunk, offset) {
|
||||||
let cursor = hunk.oldStart - 1 + 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) {
|
for (const raw of hunk.lines) {
|
||||||
const marker = raw[0];
|
const marker = raw[0];
|
||||||
|
|||||||
@@ -74,6 +74,52 @@ index 0000000..1111111 100644
|
|||||||
fs.rmSync(dir, { recursive: true, force: true });
|
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", () => {
|
it("handles multiple hunks with offsets", () => {
|
||||||
const dir = makeTempDir();
|
const dir = makeTempDir();
|
||||||
const filePath = path.join(dir, "file.txt");
|
const filePath = path.join(dir, "file.txt");
|
||||||
|
|||||||
Reference in New Issue
Block a user