Use safe file writing pattern (#421)

Write new file contents to a temporary file and then rename over the
target file to avoid data loss in the unlikely event there's an error
writing the new file contents or the process is interrupted.

Resolves #416.
This commit is contained in:
Hornwitser authored and GitHub committed 2021-11-03 16:14:18 +01:00
1 parent 9e7a7a602f
commit e23d07e965
15 files changed
+94 -35

No files matched your search

+18
View File
@@ -10,6 +10,8 @@ describe("lib/file_ops", function() {
async function setupTestingEnv() {
await fs.ensureDir(path.join(baseDir, "test", "folder"));
await fs.ensureDir(path.join(baseDir, "test", "another folder"));
await fs.remove(path.join(baseDir, "safe"));
await fs.ensureDir(path.join(baseDir, "safe"));
await fs.outputFile(path.join(baseDir, "test", "file.txt"), "contents");
await fs.outputFile(path.join(baseDir, "test", "another file.txt"), "more contents");
@@ -66,4 +68,20 @@ describe("lib/file_ops", function() {
}
});
});
describe("safeOutputFile()", function() {
it("should write new target file", async function() {
let target = path.join(baseDir, "safe", "simple.txt");
await libFileOps.safeOutputFile(target, "a text file", "utf8");
assert(!await fs.pathExists(`${target}.tmp`), "temporary was left behind");
assert.equal(await fs.readFile(target, "utf8"), "a text file");
});
it("should overwrite existing target file", async function() {
let target = path.join(baseDir, "safe", "exists.txt");
await fs.outputFile(target, "previous", "utf8");
await libFileOps.safeOutputFile(target, "current", "utf8");
assert(!await fs.pathExists(`${target}.tmp`), "temporary was left behind");
assert.equal(await fs.readFile(target, "utf8"), "current");
});
});
});