Merge pull request #3910 from code-yeongyu/fix/config-migration-repeated-bak

fix(config): use r+ mode for fsync on Windows to prevent migration retry loop
This commit is contained in:
YeonGyu-Kim
2026-05-11 09:05:12 +09:00
committed by GitHub
3 changed files with 38 additions and 3 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ export function migrateLegacyPluginEntry(configPath: string): boolean {
const tempPath = `${configPath}.tmp`
writeFileSync(tempPath, updated, "utf-8")
const tempFileDescriptor = openSync(tempPath, "r")
const tempFileDescriptor = openSync(tempPath, "r+")
try {
fsyncSync(tempFileDescriptor)
} finally {
+1 -1
View File
@@ -16,7 +16,7 @@ export function writeFileAtomically(
): void {
const tempPath = `${filePath}.tmp`
writeFileSync(tempPath, content, "utf-8")
const tempFileDescriptor = openSync(tempPath, "r")
const tempFileDescriptor = openSync(tempPath, "r+")
try {
tolerantFsyncSync(tempFileDescriptor, `writeFileAtomically:${filePath}`, deps.fsyncSync)
} finally {
@@ -96,6 +96,41 @@ describe("migrateLegacyPluginEntry", () => {
})
})
describe("#given migration writes a temp file for fsync", () => {
describe("#when opening the temp file descriptor", () => {
it("#then uses r+ mode to satisfy FlushFileBuffers requirements on Windows", async () => {
const configPath = join(testDir, "opencode.json")
writeFileSync(configPath, JSON.stringify({ plugin: ["oh-my-opencode@latest"] }, null, 2))
const fs = await import("node:fs")
const originalOpenSync = fs.openSync
const openSyncCalls: string[] = []
mock.module("node:fs", () => ({
...fs,
openSync: (path: Parameters<typeof fs.openSync>[0], flags: Parameters<typeof fs.openSync>[1]) => {
openSyncCalls.push(String(flags))
return originalOpenSync(path, flags)
},
}))
try {
const { migrateLegacyPluginEntry } = await importFreshMigrationModule()
const result = migrateLegacyPluginEntry(configPath)
expect(result).toBe(true)
expect(openSyncCalls).toContain("r+")
} finally {
mock.module("node:fs", () => ({
...fs,
openSync: originalOpenSync,
}))
}
})
})
})
describe("#given opencode.json contains pinned oh-my-opencode version", () => {
describe("#when migrating the config", () => {
it("#then preserves the version pin", async () => {
@@ -217,4 +252,4 @@ describe("migrateLegacyPluginEntry", () => {
})
})
})
})
})