mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-05 14:21:32 +00:00
117 lines
4.2 KiB
TypeScript
117 lines
4.2 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { findGitRoot, resolveGitHeadPath } from "./git-root.js";
|
|
|
|
async function makeTempDir(label: string): Promise<string> {
|
|
return fs.mkdtemp(path.join(os.tmpdir(), `openclaw-${label}-`));
|
|
}
|
|
|
|
async function expectGitRootResolution(params: {
|
|
label: string;
|
|
setup: (
|
|
temp: string,
|
|
) => Promise<{ startPath: string; expectedRoot: string | null; expectedHead: string | null }>;
|
|
}): Promise<void> {
|
|
const temp = await makeTempDir(params.label);
|
|
const { startPath, expectedRoot, expectedHead } = await params.setup(temp);
|
|
expect(findGitRoot(startPath)).toBe(expectedRoot);
|
|
expect(resolveGitHeadPath(startPath)).toBe(expectedHead);
|
|
}
|
|
|
|
describe("git-root", () => {
|
|
it.each([
|
|
{
|
|
name: "starting at the repo root itself",
|
|
label: "git-root-self",
|
|
setup: async (temp: string) => {
|
|
const repoRoot = path.join(temp, "repo");
|
|
await fs.mkdir(path.join(repoRoot, ".git"), { recursive: true });
|
|
return {
|
|
startPath: repoRoot,
|
|
expectedRoot: repoRoot,
|
|
expectedHead: path.join(repoRoot, ".git", "HEAD"),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
name: ".git is a directory",
|
|
label: "git-root-dir",
|
|
setup: async (temp: string) => {
|
|
const repoRoot = path.join(temp, "repo");
|
|
const workspace = path.join(repoRoot, "nested", "workspace");
|
|
await fs.mkdir(path.join(repoRoot, ".git"), { recursive: true });
|
|
await fs.mkdir(workspace, { recursive: true });
|
|
return {
|
|
startPath: workspace,
|
|
expectedRoot: repoRoot,
|
|
expectedHead: path.join(repoRoot, ".git", "HEAD"),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
name: ".git is a gitdir pointer file",
|
|
label: "git-root-file",
|
|
setup: async (temp: string) => {
|
|
const repoRoot = path.join(temp, "repo");
|
|
const workspace = path.join(repoRoot, "nested", "workspace");
|
|
const gitDir = path.join(repoRoot, ".actual-git");
|
|
await fs.mkdir(workspace, { recursive: true });
|
|
await fs.mkdir(gitDir, { recursive: true });
|
|
await fs.writeFile(path.join(repoRoot, ".git"), "gitdir: .actual-git\n", "utf-8");
|
|
return {
|
|
startPath: workspace,
|
|
expectedRoot: repoRoot,
|
|
expectedHead: path.join(gitDir, "HEAD"),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
name: "invalid gitdir content still keeps root detection",
|
|
label: "git-root-invalid-file",
|
|
setup: async (temp: string) => {
|
|
const parentRoot = path.join(temp, "repo");
|
|
const childRoot = path.join(parentRoot, "child");
|
|
const nested = path.join(childRoot, "nested");
|
|
await fs.mkdir(path.join(parentRoot, ".git"), { recursive: true });
|
|
await fs.mkdir(nested, { recursive: true });
|
|
await fs.writeFile(path.join(childRoot, ".git"), "not-a-gitdir-pointer\n", "utf-8");
|
|
return {
|
|
startPath: nested,
|
|
expectedRoot: childRoot,
|
|
expectedHead: path.join(parentRoot, ".git", "HEAD"),
|
|
};
|
|
},
|
|
},
|
|
{
|
|
name: "invalid gitdir content without a parent repo",
|
|
label: "git-root-invalid-only",
|
|
setup: async (temp: string) => {
|
|
const repoRoot = path.join(temp, "repo");
|
|
const nested = path.join(repoRoot, "nested");
|
|
await fs.mkdir(nested, { recursive: true });
|
|
await fs.writeFile(path.join(repoRoot, ".git"), "not-a-gitdir-pointer\n", "utf-8");
|
|
return {
|
|
startPath: nested,
|
|
expectedRoot: repoRoot,
|
|
expectedHead: null,
|
|
};
|
|
},
|
|
},
|
|
])("resolves git roots when $name", async ({ label, setup }) => {
|
|
await expectGitRootResolution({ label, setup });
|
|
});
|
|
|
|
it("respects maxDepth traversal limit", async () => {
|
|
const temp = await makeTempDir("git-root-depth");
|
|
const repoRoot = path.join(temp, "repo");
|
|
const nested = path.join(repoRoot, "a", "b", "c");
|
|
await fs.mkdir(path.join(repoRoot, ".git"), { recursive: true });
|
|
await fs.mkdir(nested, { recursive: true });
|
|
|
|
expect(findGitRoot(nested, { maxDepth: 2 })).toBeNull();
|
|
expect(resolveGitHeadPath(nested, { maxDepth: 2 })).toBeNull();
|
|
});
|
|
});
|