mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 17:27:09 +00:00
fix(cli): init creates its files where hard links are refused, with no Developer Mode needed (#6463)
This commit is contained in:
@@ -12,7 +12,11 @@ import {
|
||||
|
||||
vi.mock("node:fs", async (importOriginal) => {
|
||||
const original = await importOriginal<typeof fs>();
|
||||
return { ...original, readFileSync: vi.fn(original.readFileSync) };
|
||||
return {
|
||||
...original,
|
||||
readFileSync: vi.fn(original.readFileSync),
|
||||
linkSync: vi.fn(original.linkSync),
|
||||
};
|
||||
});
|
||||
|
||||
const dirs: string[] = [];
|
||||
@@ -43,6 +47,18 @@ describe("project config creation", () => {
|
||||
expect(JSON.parse(fs.readFileSync(path, "utf-8"))).toEqual(updated);
|
||||
});
|
||||
|
||||
it("creates the config on a volume or sandbox that refuses hard links (EPERM)", () => {
|
||||
const dir = project();
|
||||
vi.mocked(fs.linkSync).mockImplementationOnce(() => {
|
||||
throw Object.assign(new Error("operation not permitted"), { code: "EPERM" });
|
||||
});
|
||||
createProjectConfig(dir);
|
||||
expect(JSON.parse(fs.readFileSync(projectConfigPath(dir), "utf-8"))).toEqual(
|
||||
DEFAULT_PROJECT_CONFIG,
|
||||
);
|
||||
expect(fs.readdirSync(dir)).toEqual(["hyperframes.json"]);
|
||||
});
|
||||
|
||||
it("preserves a config created after the skill seed reads ENOENT", () => {
|
||||
const dir = project();
|
||||
const path = projectConfigPath(dir);
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
import { linkSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { createFileAtomically } from "@hyperframes/core/atomic-file";
|
||||
|
||||
/** Publish complete content without replacing or following an existing destination entry. */
|
||||
export function writeNewFileSync(filePath: string, content: string): void {
|
||||
const stagingDir = mkdtempSync(join(dirname(filePath), ".hf-create-"));
|
||||
try {
|
||||
const stagedPath = join(stagingDir, "content");
|
||||
writeFileSync(stagedPath, content, { encoding: "utf-8", flag: "wx" });
|
||||
try {
|
||||
linkSync(stagedPath, filePath);
|
||||
} catch (err) {
|
||||
if (!(err instanceof Error && "code" in err && err.code === "EEXIST")) throw err;
|
||||
}
|
||||
} finally {
|
||||
rmSync(stagingDir, { recursive: true, force: true });
|
||||
createFileAtomically(filePath, content);
|
||||
} catch (err) {
|
||||
if (!(err instanceof Error && "code" in err && err.code === "EEXIST")) throw err;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user