1// @effect-diagnostics nodeBuiltinImport:off - builds real worktree layouts on disk.
2import * as NodeServices from "@effect/platform-node/NodeServices";
3import { assert, describe, it } from "@effect/vitest";
4import * as NodeFS from "node:fs";
5import * as NodeOS from "node:os";
6import * as NodePath from "node:path";
7import * as Effect from "effect/Effect";
8
9import { resolveGitWorktreePath, resolveWorktreeT3Home } from "./devHome.ts";
10
11const makeRepo = (
12 kind:
13 | "worktree"
14 | "checkout"
15 | "bare"
16 | "submodule"
17 | "unreadable-git-file"
18 | "bare-repo-worktree"
19 | "custom-common-dir-worktree",
20) =>
21 Effect.acquireRelease(
22 Effect.sync(() => {
23 const root = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-devhome-"));
24 if (kind === "worktree") {
25 NodeFS.writeFileSync(NodePath.join(root, ".git"), "gitdir: /elsewhere/.git/worktrees/x\n");
26 } else if (kind === "bare-repo-worktree") {
27 NodeFS.writeFileSync(NodePath.join(root, ".git"), "gitdir: /srv/myrepo.git/worktrees/x\n");
28 } else if (kind === "custom-common-dir-worktree") {
29 NodeFS.writeFileSync(NodePath.join(root, ".git"), "gitdir: /srv/store/worktrees/x\n");
30 } else if (kind === "submodule") {
31 NodeFS.writeFileSync(NodePath.join(root, ".git"), "gitdir: ../.git/modules/sub\n");
32 } else if (kind === "unreadable-git-file") {
33 NodeFS.writeFileSync(NodePath.join(root, ".git"), "not a gitdir pointer\n");
34 } else if (kind === "checkout") {
35 NodeFS.mkdirSync(NodePath.join(root, ".git"));
36 }
37 const nested = NodePath.join(root, "apps", "web", "src");
38 NodeFS.mkdirSync(nested, { recursive: true });
39 return { root, nested };
40 }),
41 ({ root }) => Effect.sync(() => NodeFS.rmSync(root, { recursive: true, force: true })),
42 );
43
44describe("resolveGitWorktreePath", () => {
45 it.effect("finds a worktree root from a nested directory", () =>
46 Effect.gen(function* () {
47 const { root, nested } = yield* makeRepo("worktree");
48 assert.equal(yield* resolveGitWorktreePath(nested), NodePath.resolve(root));
49 }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
50 );
51
52 it.effect("reports a main checkout as not a linked worktree", () =>
53 Effect.gen(function* () {
54 const { nested } = yield* makeRepo("checkout");
55 assert.equal(yield* resolveGitWorktreePath(nested), undefined);
56 }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
57 );
58
59 it.effect("reports a submodule as not a linked worktree", () =>
60 Effect.gen(function* () {
61 const { nested } = yield* makeRepo("submodule");
62 assert.equal(yield* resolveGitWorktreePath(nested), undefined);
63 }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
64 );
65
66 it.effect("finds a worktree of a bare repository", () =>
67 Effect.gen(function* () {
68 const { root, nested } = yield* makeRepo("bare-repo-worktree");
69 assert.equal(yield* resolveGitWorktreePath(nested), NodePath.resolve(root));
70 }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
71 );
72});
73
74describe("resolveWorktreeT3Home", () => {
75 it.effect("answers with .t3 before the dev runner creates it", () =>
76 Effect.gen(function* () {
77 const { root, nested } = yield* makeRepo("worktree");
78 const home = yield* resolveWorktreeT3Home(nested);
79 assert.equal(home, NodePath.join(NodePath.resolve(root), ".t3"));
80 assert.isFalse(NodeFS.existsSync(home ?? ""));
81 }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)),
82 );
83});