mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-10-02 02:27:44 +00:00
fix(project): address atomic save review feedback
This commit is contained in:
@@ -31,6 +31,7 @@ describe("writeProjectFileAtomically", () => {
|
||||
code: "ENOENT",
|
||||
});
|
||||
await expectNoTemporaryArtifacts();
|
||||
await expectNoTemporaryArtifacts();
|
||||
});
|
||||
|
||||
it("removes a stale backup when the target has no previous generation", async () => {
|
||||
@@ -63,6 +64,7 @@ describe("writeProjectFileAtomically", () => {
|
||||
).rejects.toBeDefined();
|
||||
|
||||
await expect(fs.readFile(projectPath, "utf-8")).resolves.toBe('{"version":1,"name":"old"}');
|
||||
await expectNoTemporaryArtifacts();
|
||||
|
||||
await fs.rm(getProjectBackupPath(projectPath), { recursive: true });
|
||||
await writeProjectFileAtomically(projectPath, '{"version":1,"name":"retry"}');
|
||||
@@ -78,6 +80,7 @@ describe("writeProjectFileAtomically", () => {
|
||||
it("serializes overlapping writes to the same project", async () => {
|
||||
await writeProjectFileAtomically(projectPath, '{"revision":1}');
|
||||
|
||||
// Each call enters the queue synchronously before its first await, preserving invocation order.
|
||||
await Promise.all([
|
||||
writeProjectFileAtomically(projectPath, '{"revision":2}'),
|
||||
writeProjectFileAtomically(projectPath, '{"revision":3}'),
|
||||
@@ -91,13 +94,19 @@ describe("writeProjectFileAtomically", () => {
|
||||
});
|
||||
|
||||
it.skipIf(process.platform === "win32")(
|
||||
"preserves existing project permission bits on replacement",
|
||||
"preserves exact project permission bits despite the process umask",
|
||||
async () => {
|
||||
await fs.writeFile(projectPath, '{"revision":1}', { mode: 0o600 });
|
||||
await fs.writeFile(projectPath, '{"revision":1}', { mode: 0o666 });
|
||||
await fs.chmod(projectPath, 0o666);
|
||||
const previousUmask = process.umask(0o077);
|
||||
|
||||
await writeProjectFileAtomically(projectPath, '{"revision":2}');
|
||||
try {
|
||||
await writeProjectFileAtomically(projectPath, '{"revision":2}');
|
||||
} finally {
|
||||
process.umask(previousUmask);
|
||||
}
|
||||
|
||||
expect((await fs.stat(projectPath)).mode & 0o777).toBe(0o600);
|
||||
expect((await fs.stat(projectPath)).mode & 0o777).toBe(0o666);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -47,6 +47,9 @@ async function writeSyncedTemporaryFile(
|
||||
const handle = await fs.open(filePath, "wx", mode);
|
||||
try {
|
||||
await handle.writeFile(contents, "utf-8");
|
||||
if (mode !== undefined) {
|
||||
await handle.chmod(mode);
|
||||
}
|
||||
await handle.sync();
|
||||
} finally {
|
||||
await handle.close();
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
LEGACY_PROJECT_FILE_EXTENSIONS,
|
||||
PROJECT_FILE_EXTENSION,
|
||||
} from "../constants";
|
||||
import { writeProjectFileAtomically } from "../project/atomicSave";
|
||||
import { getProjectBackupPath, writeProjectFileAtomically } from "../project/atomicSave";
|
||||
import {
|
||||
getProjectsDir,
|
||||
getProjectThumbnailPath,
|
||||
@@ -432,6 +432,7 @@ export function registerProjectHandlers() {
|
||||
}
|
||||
})
|
||||
await fs.rm(getProjectThumbnailPath(activeProjectPath), { force: true }).catch(() => undefined)
|
||||
await fs.rm(getProjectBackupPath(activeProjectPath), { force: true }).catch(() => undefined)
|
||||
|
||||
const recentProjectPaths = await loadRecentProjectPaths()
|
||||
const filteredRecentProjectPaths: string[] = []
|
||||
|
||||
Reference in New Issue
Block a user