refactor: make workspace repository strictly read only

This commit is contained in:
2026-08-14 16:20:08 +02:00
parent 3a50c447c3
commit 42e02f8b1c
4 changed files with 38 additions and 570 deletions
+11 -17
View File
@@ -1,5 +1,5 @@
import { execFile } from "node:child_process";
import { existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { existsSync, mkdtempSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { promisify } from "node:util";
@@ -92,6 +92,16 @@ function config(root: string, remoteUrl: string): WorkspaceRegistryConfig {
};
}
test("does not expose repository mutation or publication operations", async () => {
const fixture = await temporaryRemote();
const repository = new GitWorkspaceRepository(config(join(fixture.root, "registry"), fixture.remote));
expect(repository).not.toHaveProperty("createRegistryFile");
expect(repository).not.toHaveProperty("writeRegistryFile");
expect(repository).not.toHaveProperty("removeRegistryFile");
expect(repository).not.toHaveProperty("commitAndPush");
});
test("bootstraps a persistent checkout from a local bare repository", async () => {
const fixture = await temporaryRemote();
const repository = new GitWorkspaceRepository(config(join(fixture.root, "registry"), fixture.remote));
@@ -300,19 +310,3 @@ test("parallel contenders recover a stale lock file without overlapping critical
expect(results.filter((result) => result.status === "rejected")).toHaveLength(1);
expect(maximum).toBe(1);
});
test("creates a descriptor only when the exact curator path is absent", async () => {
const fixture = await temporaryRemote();
const repository = new GitWorkspaceRepository(config(join(fixture.root, "registry"), fixture.remote));
await repository.bootstrap();
const descriptorPath = "new-workspace/workspace.yaml";
const descriptor = "curator descriptor\n";
await expect(repository.createRegistryFile(descriptorPath, descriptor)).resolves.toBeUndefined();
expect(readFileSync(join(fixture.root, "registry", "repo", descriptorPath), "utf8")).toBe(descriptor);
await expect(repository.createRegistryFile(descriptorPath, "overwrite\n"))
.rejects.toMatchObject({ code: "workspace_curator_owned" });
expect(readFileSync(join(fixture.root, "registry", "repo", descriptorPath), "utf8")).toBe(descriptor);
await expect(repository.createRegistryFile("workspace-docs/workspace.yaml", descriptor))
.rejects.toMatchObject({ code: "workspace_invalid" });
});