Skip to content

Commit 5026e30

Browse files
committed
fix(core): append legacy patch additions after blank content lines
Signed-off-by: icearia0219 <[email protected]>
1 parent 5c51e6f commit 5026e30

3 files changed

Lines changed: 34 additions & 5 deletions

File tree

‎packages/core/test/patch.test.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@ import { describe, expect, test } from "bun:test"
22
import { Patch } from "@opencode-ai/core/patch"
33

44
describe("Patch", () => {
5+
test.each([
6+
["", "added\n"],
7+
["\n", "\nadded\n"],
8+
["before", "before\nadded\n"],
9+
["before\n", "before\nadded\n"],
10+
["before\n\n", "before\n\nadded\n"],
11+
["before\n\n\n", "before\n\n\nadded\n"],
12+
])("appends pure additions after all content lines in %j", (original, expected) => {
13+
expect(Patch.derive("update.txt", [{ oldLines: [], newLines: ["added"] }], original).content).toBe(expected)
14+
})
15+
516
test.each(["\n", "\n\n", "\n\n\n"])("preserves an unchanged trailing %j", (ending) => {
617
expect(Patch.derive("update.txt", [{ oldLines: ["old"], newLines: ["new"] }], `\uFEFFold${ending}`)).toEqual({
718
content: `new${ending}`,

‎packages/opencode/src/patch/index.ts‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,8 @@ function computeReplacements(
360360

361361
// Handle pure addition (no old lines)
362362
if (chunk.old_lines.length === 0) {
363-
const insertionIdx =
364-
originalLines.length > 0 && originalLines[originalLines.length - 1] === ""
365-
? originalLines.length - 1
366-
: originalLines.length
367-
replacements.push([insertionIdx, 0, chunk.new_lines])
363+
// The split sentinel was already removed; any remaining blank lines are content.
364+
replacements.push([originalLines.length, 0, chunk.new_lines])
368365
continue
369366
}
370367

‎packages/opencode/test/patch/patch.test.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,27 @@ PATCH`
140140
})
141141

142142
describe("applyPatch", () => {
143+
for (const [original, expected] of [
144+
["", "added\n"],
145+
["\n", "\nadded\n"],
146+
["before", "before\nadded\n"],
147+
["before\n", "before\nadded\n"],
148+
["before\n\n", "before\n\nadded\n"],
149+
["before\n\n\n", "before\n\n\nadded\n"],
150+
]) {
151+
it.live(`appends pure additions after all content lines in ${JSON.stringify(original)}`, () =>
152+
Effect.gen(function* () {
153+
const target = path.join(tempDir, "append.txt")
154+
yield* Effect.promise(() => fs.writeFile(target, original))
155+
const result = yield* Patch.applyPatch(
156+
`*** Begin Patch\n*** Update File: ${target}\n@@\n+added\n*** End Patch`,
157+
)
158+
expect(result.modified).toEqual([target])
159+
expect(yield* Effect.promise(() => fs.readFile(target, "utf8"))).toBe(expected)
160+
}),
161+
)
162+
}
163+
143164
it.live("preserves trailing blank lines across repeated updates", () =>
144165
Effect.gen(function* () {
145166
const target = path.join(tempDir, "trailing.txt")

0 commit comments

Comments
 (0)