fix(config): use r+ when fsyncing migrated temp file
Apply the Windows-safe open mode in migrateLegacyPluginEntry and add a regression test to assert the temp fd is opened with r+ before fsync. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -54,7 +54,7 @@ export function migrateLegacyPluginEntry(configPath: string): boolean {
|
|||||||
|
|
||||||
const tempPath = `${configPath}.tmp`
|
const tempPath = `${configPath}.tmp`
|
||||||
writeFileSync(tempPath, updated, "utf-8")
|
writeFileSync(tempPath, updated, "utf-8")
|
||||||
const tempFileDescriptor = openSync(tempPath, "r")
|
const tempFileDescriptor = openSync(tempPath, "r+")
|
||||||
try {
|
try {
|
||||||
fsyncSync(tempFileDescriptor)
|
fsyncSync(tempFileDescriptor)
|
||||||
} finally {
|
} 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("#given opencode.json contains pinned oh-my-opencode version", () => {
|
||||||
describe("#when migrating the config", () => {
|
describe("#when migrating the config", () => {
|
||||||
it("#then preserves the version pin", async () => {
|
it("#then preserves the version pin", async () => {
|
||||||
@@ -217,4 +252,4 @@ describe("migrateLegacyPluginEntry", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user