fix(config-migration): always apply migration in-memory and track backup success

Migration changes were only applied to rawConfig if file write succeeded,
leaving the running process on stale config. Also stops logging backup
path when the backup copy itself failed.
This commit is contained in:
YeonGyu-Kim 2026-02-11 00:44:45 +09:00
parent 3553ab79e1
commit af7733f89f

View File

@ -8,7 +8,6 @@ export function migrateConfigFile(
configPath: string, configPath: string,
rawConfig: Record<string, unknown> rawConfig: Record<string, unknown>
): boolean { ): boolean {
// Work on a deep copy — only apply changes to rawConfig if file write succeeds
const copy = structuredClone(rawConfig) const copy = structuredClone(rawConfig)
let needsWrite = false let needsWrite = false
@ -98,28 +97,36 @@ export function migrateConfigFile(
} }
if (needsWrite) { if (needsWrite) {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-")
const backupPath = `${configPath}.bak.${timestamp}`
let backupSucceeded = false
try { try {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-") fs.copyFileSync(configPath, backupPath)
const backupPath = `${configPath}.bak.${timestamp}` backupSucceeded = true
try { } catch {
fs.copyFileSync(configPath, backupPath) // Original file may not exist yet — skip backup
} catch { }
// Original file may not exist yet — skip backup
} let writeSucceeded = false
try {
fs.writeFileSync(configPath, JSON.stringify(copy, null, 2) + "\n", "utf-8") fs.writeFileSync(configPath, JSON.stringify(copy, null, 2) + "\n", "utf-8")
log(`Migrated config file: ${configPath} (backup: ${backupPath})`) writeSucceeded = true
} catch (err) { } catch (err) {
log(`Failed to write migrated config to ${configPath}:`, err) log(`Failed to write migrated config to ${configPath}:`, err)
// File write failed — rawConfig is untouched, preserving user's original values
return false
} }
// File write succeeded — apply changes to the original rawConfig
for (const key of Object.keys(rawConfig)) { for (const key of Object.keys(rawConfig)) {
delete rawConfig[key] delete rawConfig[key]
} }
Object.assign(rawConfig, copy) Object.assign(rawConfig, copy)
if (writeSucceeded) {
const backupMessage = backupSucceeded ? ` (backup: ${backupPath})` : ""
log(`Migrated config file: ${configPath}${backupMessage}`)
} else {
const backupMessage = backupSucceeded ? ` (backup: ${backupPath})` : ""
log(`Applied migrated config in-memory for: ${configPath}${backupMessage}`)
}
} }
return needsWrite return needsWrite