// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not.import * as NodeFS from "node:fs";import * as NodeServices from "@effect/platform-node/NodeServices";import { HostProcessPlatform } from "@t3tools/shared/hostProcess";import { assert, it, describe } from "@effect/vitest";import * as Deferred from "effect/Deferred";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Fiber from "effect/Fiber";import * as Layer from "effect/Layer";import * as Logger from "effect/Logger";import * as Path from "effect/Path";import * as PlatformError from "effect/PlatformError";import * as Ref from "effect/Ref";import * as Scope from "effect/Scope";import * as Schema from "effect/Schema";import * as Sink from "effect/Sink";import * as Stream from "effect/Stream";import * as TestClock from "effect/testing/TestClock";import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { GitCommandError, type ReviewDiffFileContentsInput } from "@t3tools/contracts";import { ServerConfig } from "../config.ts";import { makeGitVcsDriverCore, splitNullSeparatedGitStdoutPaths } from "./GitVcsDriverCore.ts";import * as GitVcsDriver from "./GitVcsDriver.ts"; const encodeGitCommandError = Schema.encodeEffect(Schema.fromJsonString(GitCommandError)); const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-git-vcs-driver-test-",});const TestLayer = GitVcsDriver.layer.pipe( Layer.provide(ServerConfigLayer), Layer.provideMerge(NodeServices.layer),); const makeNonRepositoryHandle = () => ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(128)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: Stream.empty, stderr: Stream.encodeText(Stream.make("fatal: not a git repository")), all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, }); const makeSuccessfulHandle = (stdout: string) => ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(0)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: Stream.encodeText(Stream.make(stdout)), stderr: Stream.empty, all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, }); const makeTmpDir = ( prefix = "git-vcs-driver-test-",): Effect.Effect<string, PlatformError.PlatformError, FileSystem.FileSystem | Scope.Scope> => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; return yield* fileSystem.makeTempDirectoryScoped({ prefix }); }); const writeTextFile = ( cwd: string, relativePath: string, contents: string,): Effect.Effect<void, PlatformError.PlatformError, FileSystem.FileSystem | Path.Path> => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const pathService = yield* Path.Path; const filePath = pathService.join(cwd, relativePath); yield* fileSystem.makeDirectory(pathService.dirname(filePath), { recursive: true }); yield* fileSystem.writeFileString(filePath, contents); }); const makeReviewDiffFileContentsInput = ( cwd: string, overrides: Partial<Omit<ReviewDiffFileContentsInput, "cwd">> = {},): ReviewDiffFileContentsInput => ({ cwd, sourceKind: "working-tree", changeType: "change", baseRef: "HEAD", headRef: null, oldPath: "README.md", newPath: "README.md", ...overrides,}); const git = ( cwd: string, args: ReadonlyArray<string>, env?: NodeJS.ProcessEnv,): Effect.Effect<string, GitCommandError, GitVcsDriver.GitVcsDriver> => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const result = yield* driver.execute({ operation: "GitVcsDriver.test.git", cwd, args, ...(env ? { env } : {}), timeoutMs: 10_000, }); return result.stdout.trim(); }); const initRepoWithCommit = ( cwd: string,): Effect.Effect< { readonly initialBranch: string }, GitCommandError | PlatformError.PlatformError, GitVcsDriver.GitVcsDriver | FileSystem.FileSystem | Path.Path> => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; yield* driver.initRepo({ cwd }); yield* git(cwd, ["config", "user.email", "test@test.com"]); yield* git(cwd, ["config", "user.name", "Test"]); yield* writeTextFile(cwd, "README.md", "# test\n"); yield* git(cwd, ["add", "."]); yield* git(cwd, ["commit", "-m", "initial commit"]); const initialBranch = yield* git(cwd, ["branch", "--show-current"]); return { initialBranch }; }); it.effect("uses stable diagnostics for every parsed non-repository command", () => { const commands: Array<{ readonly args: ReadonlyArray<string>; readonly lcAll?: string }> = []; const spawner = ChildProcessSpawner.make((command) => Effect.sync(() => { if (!ChildProcess.isStandardCommand(command)) { return assert.fail("expected a standard Git command"); } commands.push({ args: command.args, ...(command.options.env?.LC_ALL ? { lcAll: command.options.env.LC_ALL } : {}), }); return makeNonRepositoryHandle(); }), ); const nodeServicesLayer = Layer.merge( NodeServices.layer, Layer.succeed(ChildProcessSpawner.ChildProcessSpawner, spawner), ); const layer = GitVcsDriver.layer.pipe( Layer.provide(ServerConfigLayer), Layer.provideMerge(nodeServicesLayer), ); return Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = "/repo"; yield* driver.statusDetailsLocal(cwd); yield* driver.statusDetailsRemote(cwd, { refreshUpstream: false }); yield* driver.listRefs({ cwd }); assert.deepStrictEqual(commands, [ { args: ["status", "--porcelain=2", "--branch"], lcAll: "C" }, { args: ["rev-parse", "--abbrev-ref", "HEAD"], lcAll: "C" }, { args: ["rev-parse", "--git-common-dir"], lcAll: "C" }, ]); }).pipe(Effect.provide(layer));}); it.effect("invalidates origin remote cache when a driver mutation adds origin", () => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = yield* makeTmpDir(); const remote = yield* makeTmpDir("git-vcs-driver-remote-"); yield* initRepoWithCommit(cwd); yield* git(remote, ["init", "--bare"]); const before = yield* driver.statusDetailsLocal(cwd); assert.equal(before.hasOriginRemote, false); yield* driver.ensureRemote({ cwd, preferredName: "origin", url: remote }); const after = yield* driver.statusDetailsLocal(cwd); assert.equal(after.hasOriginRemote, true); }).pipe(Effect.provide(TestLayer)),); it.effect("re-reads origin remote status after cache TTL expiry and bypassed invalidation", () => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = yield* makeTmpDir(); const remote = yield* makeTmpDir("git-vcs-driver-remote-"); yield* initRepoWithCommit(cwd); yield* git(remote, ["init", "--bare"]); // First call caches hasOriginRemote = false (5-min TTL) assert.equal((yield* driver.statusDetailsLocal(cwd)).hasOriginRemote, false); // Add origin via raw git (bypasses invalidation hook) yield* git(cwd, ["remote", "add", "origin", remote]); // Cache still has the stale false (TTL not yet expired) const stillCached = yield* driver.statusDetailsLocal(cwd); assert.equal(stillCached.hasOriginRemote, false); // Advance past the 5-minute TTL so the cache entry expires yield* TestClock.adjust("6 minutes"); // After expiry, the next call re-executes and picks up the remote const afterExpiry = yield* driver.statusDetailsLocal(cwd); assert.equal(afterExpiry.hasOriginRemote, true); }).pipe(Effect.provide(TestLayer)),); it.effect("coalesces concurrent ref pages into one repository snapshot", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const spawnedArgs = yield* Ref.make<ReadonlyArray<ReadonlyArray<string>>>([]); const firstWorktreeScanStarted = yield* Deferred.make<void>(); const remoteNamesScanCompleted = yield* Deferred.make<void>(); const delayFirstWorktreeScan = yield* Ref.make(true); const countingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } yield* Ref.update(spawnedArgs, (current) => [...current, command.args]); const isWorktreeScan = command.args.includes("worktree") && command.args.includes("--porcelain"); const shouldDelay = isWorktreeScan && (yield* Ref.getAndSet(delayFirstWorktreeScan, false)); if (shouldDelay) { yield* Deferred.succeed(firstWorktreeScanStarted, undefined); yield* Effect.sleep("8 seconds"); } const handle = yield* delegate.spawn(command); const isRemoteNamesScan = command.args.length === 3 && command.args[0] === "--git-dir" && command.args[2] === "remote"; return isRemoteNamesScan ? ChildProcessSpawner.makeHandle({ ...handle, exitCode: handle.exitCode.pipe( Effect.tap(() => Deferred.succeed(remoteNamesScanCompleted, undefined)), ), }) : handle; }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, countingSpawner), ); const cwd = yield* makeTmpDir(); const runGit = (args: ReadonlyArray<string>) => driver.execute({ operation: "GitVcsDriver.test.coalescedListRefs", cwd, args, timeoutMs: 10_000, }); yield* driver.initRepo({ cwd }); yield* runGit(["config", "user.email", "test@test.com"]); yield* runGit(["config", "user.name", "Test"]); yield* writeTextFile(cwd, "README.md", "# test\n"); yield* runGit(["add", "."]); yield* runGit(["commit", "-m", "initial commit"]); yield* Ref.set(spawnedArgs, []); const initialRequest = yield* driver .listRefs({ cwd, refresh: true, limit: 100 }) .pipe(Effect.forkChild({ startImmediately: true })); yield* Deferred.await(firstWorktreeScanStarted); yield* Deferred.await(remoteNamesScanCompleted); yield* TestClock.adjust("6 seconds"); const laterRequests = yield* Effect.all( Array.from({ length: 30 }, (_, index) => driver.listRefs({ cwd, refresh: true, query: `missing-${index}`, limit: 100, }), ), { concurrency: "unbounded" }, ).pipe(Effect.forkChild({ startImmediately: true })); yield* TestClock.adjust("2 seconds"); yield* Fiber.join(initialRequest); yield* Fiber.join(laterRequests); yield* driver.listRefs({ cwd, cursor: 1, limit: 100 }); const firstSnapshotCommands = yield* Ref.get(spawnedArgs); const snapshotRefScans = firstSnapshotCommands.filter( (args) => args.includes("for-each-ref") && args.includes("refs/heads") && args.includes("refs/remotes"), ); const worktreeScans = firstSnapshotCommands.filter( (args) => args.includes("worktree") && args.includes("--porcelain"), ); assert.equal(snapshotRefScans.length, 1); assert.equal(worktreeScans.length, 1); yield* driver.createRef({ cwd, refName: "feature/cache-invalidation" }); const refreshed = yield* driver.listRefs({ cwd, limit: 100 }); assert.equal( refreshed.refs.some((ref) => ref.name === "feature/cache-invalidation"), true, ); const allCommands = yield* Ref.get(spawnedArgs); assert.equal( allCommands.filter( (args) => args.includes("for-each-ref") && args.includes("refs/heads") && args.includes("refs/remotes"), ).length, 2, ); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))),); it.effect("retries an in-flight ref snapshot invalidated by a mutation", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const firstWorktreeScanStarted = yield* Deferred.make<void>(); const firstRefScanCompleted = yield* Deferred.make<void>(); const releaseFirstWorktreeScan = yield* Deferred.make<void>(); const delayFirstWorktreeScan = yield* Ref.make(true); const refScans = yield* Ref.make(0); const coordinatingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } const isWorktreeScan = command.args.includes("worktree") && command.args.includes("--porcelain"); if (isWorktreeScan && (yield* Ref.getAndSet(delayFirstWorktreeScan, false))) { yield* Deferred.succeed(firstWorktreeScanStarted, undefined); yield* Deferred.await(releaseFirstWorktreeScan); } const handle = yield* delegate.spawn(command); const isRefScan = command.args.includes("for-each-ref") && command.args.includes("refs/heads") && command.args.includes("refs/remotes"); if (!isRefScan) return handle; const scan = yield* Ref.updateAndGet(refScans, (count) => count + 1); return scan === 1 ? ChildProcessSpawner.makeHandle({ ...handle, exitCode: handle.exitCode.pipe( Effect.tap(() => Deferred.succeed(firstRefScanCompleted, undefined)), ), }) : handle; }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, coordinatingSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); const inFlight = yield* driver .listRefs({ cwd, refresh: true, limit: 100 }) .pipe(Effect.forkChild({ startImmediately: true })); yield* Deferred.await(firstWorktreeScanStarted); yield* Deferred.await(firstRefScanCompleted); yield* driver.createRef({ cwd, refName: "feature/during-refresh" }); yield* Deferred.succeed(releaseFirstWorktreeScan, undefined); const refs = yield* Fiber.join(inFlight); assert.isTrue(refs.refs.some((ref) => ref.name === "feature/during-refresh")); assert.equal(yield* Ref.get(refScans), 2); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))),); it.effect("invalidates a ref snapshot when a mutation fails after changing Git", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const partiallyFailingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } if (command.args[0] === "branch" && command.args[1] === "feature/partial-failure") { const handle = yield* delegate.spawn(command); yield* handle.exitCode; return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, partiallyFailingSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); yield* driver.listRefs({ cwd, refresh: true }); yield* driver.createRef({ cwd, refName: "feature/partial-failure" }).pipe(Effect.flip); const refs = yield* driver.listRefs({ cwd }); assert.isTrue(refs.refs.some((ref) => ref.name === "feature/partial-failure")); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))),); it.effect("fails a ref snapshot when for-each-ref exits unsuccessfully", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const snapshotAttempts = yield* Ref.make(0); const failingSnapshotSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } if (command.args.includes("for-each-ref")) { yield* Ref.update(snapshotAttempts, (count) => count + 1); return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, failingSnapshotSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); const error = yield* driver.listRefs({ cwd, refresh: true }).pipe(Effect.flip); assert.deepInclude(error, { _tag: "GitCommandError", operation: "GitVcsDriver.listRefs.snapshotRefs", detail: "Git ref snapshot enumeration failed.", exitCode: 128, }); assert.equal(yield* Ref.get(snapshotAttempts), 1); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))),); it.effect("marks the current branch when worktree metadata is unavailable", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const incompleteMetadataSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } const isWorktreeRoot = command.args.includes("rev-parse") && command.args.includes("--show-toplevel"); const isWorktreeList = command.args.includes("worktree") && command.args.includes("--porcelain"); if (isWorktreeRoot || isWorktreeList) { return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, incompleteMetadataSpawner), ); const cwd = yield* makeTmpDir(); const { initialBranch } = yield* initRepoWithCommit(cwd).pipe( Effect.provideService(GitVcsDriver.GitVcsDriver, driver), ); const refs = yield* driver.listRefs({ cwd, refresh: true }); assert.isTrue(refs.isRepo); assert.isTrue(refs.refs.find((ref) => ref.name === initialBranch)?.current); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))),); it.effect("ignores worktree metadata for directories that no longer exist", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const missingWorktreePath = "/missing/deleted-worktree";Lines 1–500 of 2266. Load more
// @effect-diagnostics nodeBuiltinImport:off - realpathSync.native resolves Windows 8.3 short names, which the Effect realPath does not. import * as NodeFS from "node:fs"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; import { assert, it, describe } from "@effect/vitest"; import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Fiber from "effect/Fiber"; import * as Layer from "effect/Layer"; import * as Logger from "effect/Logger"; import * as Path from "effect/Path"; import * as PlatformError from "effect/PlatformError"; import * as Ref from "effect/Ref"; import * as Scope from "effect/Scope"; import * as Schema from "effect/Schema"; import * as Sink from "effect/Sink"; import * as Stream from "effect/Stream"; import * as TestClock from "effect/testing/TestClock"; import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { GitCommandError, type ReviewDiffFileContentsInput } from "@t3tools/contracts"; import { ServerConfig } from "../config.ts"; import { makeGitVcsDriverCore, splitNullSeparatedGitStdoutPaths } from "./GitVcsDriverCore.ts"; import * as GitVcsDriver from "./GitVcsDriver.ts"; const encodeGitCommandError = Schema.encodeEffect(Schema.fromJsonString(GitCommandError)); const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-git-vcs-driver-test-", }); const TestLayer = GitVcsDriver.layer.pipe( Layer.provide(ServerConfigLayer), Layer.provideMerge(NodeServices.layer), ); const makeNonRepositoryHandle = () => ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(128)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: Stream.empty, stderr: Stream.encodeText(Stream.make("fatal: not a git repository")), all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, }); const makeSuccessfulHandle = (stdout: string) => ChildProcessSpawner.makeHandle({ pid: ChildProcessSpawner.ProcessId(1), exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(0)), isRunning: Effect.succeed(false), kill: () => Effect.void, unref: Effect.succeed(Effect.void), stdin: Sink.drain, stdout: Stream.encodeText(Stream.make(stdout)), stderr: Stream.empty, all: Stream.empty, getInputFd: () => Sink.drain, getOutputFd: () => Stream.empty, }); const makeTmpDir = ( prefix = "git-vcs-driver-test-", ): Effect.Effect<string, PlatformError.PlatformError, FileSystem.FileSystem | Scope.Scope> => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; return yield* fileSystem.makeTempDirectoryScoped({ prefix }); }); const writeTextFile = ( cwd: string, relativePath: string, contents: string, ): Effect.Effect<void, PlatformError.PlatformError, FileSystem.FileSystem | Path.Path> => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const pathService = yield* Path.Path; const filePath = pathService.join(cwd, relativePath); yield* fileSystem.makeDirectory(pathService.dirname(filePath), { recursive: true }); yield* fileSystem.writeFileString(filePath, contents); }); const makeReviewDiffFileContentsInput = ( cwd: string, overrides: Partial<Omit<ReviewDiffFileContentsInput, "cwd">> = {}, ): ReviewDiffFileContentsInput => ({ cwd, sourceKind: "working-tree", changeType: "change", baseRef: "HEAD", headRef: null, oldPath: "README.md", newPath: "README.md", ...overrides, }); const git = ( cwd: string, args: ReadonlyArray<string>, env?: NodeJS.ProcessEnv, ): Effect.Effect<string, GitCommandError, GitVcsDriver.GitVcsDriver> => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const result = yield* driver.execute({ operation: "GitVcsDriver.test.git", cwd, args, ...(env ? { env } : {}), timeoutMs: 10_000, }); return result.stdout.trim(); }); const initRepoWithCommit = ( cwd: string, ): Effect.Effect< { readonly initialBranch: string }, GitCommandError | PlatformError.PlatformError, GitVcsDriver.GitVcsDriver | FileSystem.FileSystem | Path.Path > => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; yield* driver.initRepo({ cwd }); yield* git(cwd, ["config", "user.email", "test@test.com"]); yield* git(cwd, ["config", "user.name", "Test"]); yield* writeTextFile(cwd, "README.md", "# test\n"); yield* git(cwd, ["add", "."]); yield* git(cwd, ["commit", "-m", "initial commit"]); const initialBranch = yield* git(cwd, ["branch", "--show-current"]); return { initialBranch }; }); it.effect("uses stable diagnostics for every parsed non-repository command", () => { const commands: Array<{ readonly args: ReadonlyArray<string>; readonly lcAll?: string }> = []; const spawner = ChildProcessSpawner.make((command) => Effect.sync(() => { if (!ChildProcess.isStandardCommand(command)) { return assert.fail("expected a standard Git command"); } commands.push({ args: command.args, ...(command.options.env?.LC_ALL ? { lcAll: command.options.env.LC_ALL } : {}), }); return makeNonRepositoryHandle(); }), ); const nodeServicesLayer = Layer.merge( NodeServices.layer, Layer.succeed(ChildProcessSpawner.ChildProcessSpawner, spawner), ); const layer = GitVcsDriver.layer.pipe( Layer.provide(ServerConfigLayer), Layer.provideMerge(nodeServicesLayer), ); return Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = "/repo"; yield* driver.statusDetailsLocal(cwd); yield* driver.statusDetailsRemote(cwd, { refreshUpstream: false }); yield* driver.listRefs({ cwd }); assert.deepStrictEqual(commands, [ { args: ["status", "--porcelain=2", "--branch"], lcAll: "C" }, { args: ["rev-parse", "--abbrev-ref", "HEAD"], lcAll: "C" }, { args: ["rev-parse", "--git-common-dir"], lcAll: "C" }, ]); }).pipe(Effect.provide(layer)); }); it.effect("invalidates origin remote cache when a driver mutation adds origin", () => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = yield* makeTmpDir(); const remote = yield* makeTmpDir("git-vcs-driver-remote-"); yield* initRepoWithCommit(cwd); yield* git(remote, ["init", "--bare"]); const before = yield* driver.statusDetailsLocal(cwd); assert.equal(before.hasOriginRemote, false); yield* driver.ensureRemote({ cwd, preferredName: "origin", url: remote }); const after = yield* driver.statusDetailsLocal(cwd); assert.equal(after.hasOriginRemote, true); }).pipe(Effect.provide(TestLayer)), ); it.effect("re-reads origin remote status after cache TTL expiry and bypassed invalidation", () => Effect.gen(function* () { const driver = yield* GitVcsDriver.GitVcsDriver; const cwd = yield* makeTmpDir(); const remote = yield* makeTmpDir("git-vcs-driver-remote-"); yield* initRepoWithCommit(cwd); yield* git(remote, ["init", "--bare"]); // First call caches hasOriginRemote = false (5-min TTL) assert.equal((yield* driver.statusDetailsLocal(cwd)).hasOriginRemote, false); // Add origin via raw git (bypasses invalidation hook) yield* git(cwd, ["remote", "add", "origin", remote]); // Cache still has the stale false (TTL not yet expired) const stillCached = yield* driver.statusDetailsLocal(cwd); assert.equal(stillCached.hasOriginRemote, false); // Advance past the 5-minute TTL so the cache entry expires yield* TestClock.adjust("6 minutes"); // After expiry, the next call re-executes and picks up the remote const afterExpiry = yield* driver.statusDetailsLocal(cwd); assert.equal(afterExpiry.hasOriginRemote, true); }).pipe(Effect.provide(TestLayer)), ); it.effect("coalesces concurrent ref pages into one repository snapshot", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const spawnedArgs = yield* Ref.make<ReadonlyArray<ReadonlyArray<string>>>([]); const firstWorktreeScanStarted = yield* Deferred.make<void>(); const remoteNamesScanCompleted = yield* Deferred.make<void>(); const delayFirstWorktreeScan = yield* Ref.make(true); const countingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } yield* Ref.update(spawnedArgs, (current) => [...current, command.args]); const isWorktreeScan = command.args.includes("worktree") && command.args.includes("--porcelain"); const shouldDelay = isWorktreeScan && (yield* Ref.getAndSet(delayFirstWorktreeScan, false)); if (shouldDelay) { yield* Deferred.succeed(firstWorktreeScanStarted, undefined); yield* Effect.sleep("8 seconds"); } const handle = yield* delegate.spawn(command); const isRemoteNamesScan = command.args.length === 3 && command.args[0] === "--git-dir" && command.args[2] === "remote"; return isRemoteNamesScan ? ChildProcessSpawner.makeHandle({ ...handle, exitCode: handle.exitCode.pipe( Effect.tap(() => Deferred.succeed(remoteNamesScanCompleted, undefined)), ), }) : handle; }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, countingSpawner), ); const cwd = yield* makeTmpDir(); const runGit = (args: ReadonlyArray<string>) => driver.execute({ operation: "GitVcsDriver.test.coalescedListRefs", cwd, args, timeoutMs: 10_000, }); yield* driver.initRepo({ cwd }); yield* runGit(["config", "user.email", "test@test.com"]); yield* runGit(["config", "user.name", "Test"]); yield* writeTextFile(cwd, "README.md", "# test\n"); yield* runGit(["add", "."]); yield* runGit(["commit", "-m", "initial commit"]); yield* Ref.set(spawnedArgs, []); const initialRequest = yield* driver .listRefs({ cwd, refresh: true, limit: 100 }) .pipe(Effect.forkChild({ startImmediately: true })); yield* Deferred.await(firstWorktreeScanStarted); yield* Deferred.await(remoteNamesScanCompleted); yield* TestClock.adjust("6 seconds"); const laterRequests = yield* Effect.all( Array.from({ length: 30 }, (_, index) => driver.listRefs({ cwd, refresh: true, query: `missing-${index}`, limit: 100, }), ), { concurrency: "unbounded" }, ).pipe(Effect.forkChild({ startImmediately: true })); yield* TestClock.adjust("2 seconds"); yield* Fiber.join(initialRequest); yield* Fiber.join(laterRequests); yield* driver.listRefs({ cwd, cursor: 1, limit: 100 }); const firstSnapshotCommands = yield* Ref.get(spawnedArgs); const snapshotRefScans = firstSnapshotCommands.filter( (args) => args.includes("for-each-ref") && args.includes("refs/heads") && args.includes("refs/remotes"), ); const worktreeScans = firstSnapshotCommands.filter( (args) => args.includes("worktree") && args.includes("--porcelain"), ); assert.equal(snapshotRefScans.length, 1); assert.equal(worktreeScans.length, 1); yield* driver.createRef({ cwd, refName: "feature/cache-invalidation" }); const refreshed = yield* driver.listRefs({ cwd, limit: 100 }); assert.equal( refreshed.refs.some((ref) => ref.name === "feature/cache-invalidation"), true, ); const allCommands = yield* Ref.get(spawnedArgs); assert.equal( allCommands.filter( (args) => args.includes("for-each-ref") && args.includes("refs/heads") && args.includes("refs/remotes"), ).length, 2, ); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))), ); it.effect("retries an in-flight ref snapshot invalidated by a mutation", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const firstWorktreeScanStarted = yield* Deferred.make<void>(); const firstRefScanCompleted = yield* Deferred.make<void>(); const releaseFirstWorktreeScan = yield* Deferred.make<void>(); const delayFirstWorktreeScan = yield* Ref.make(true); const refScans = yield* Ref.make(0); const coordinatingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } const isWorktreeScan = command.args.includes("worktree") && command.args.includes("--porcelain"); if (isWorktreeScan && (yield* Ref.getAndSet(delayFirstWorktreeScan, false))) { yield* Deferred.succeed(firstWorktreeScanStarted, undefined); yield* Deferred.await(releaseFirstWorktreeScan); } const handle = yield* delegate.spawn(command); const isRefScan = command.args.includes("for-each-ref") && command.args.includes("refs/heads") && command.args.includes("refs/remotes"); if (!isRefScan) return handle; const scan = yield* Ref.updateAndGet(refScans, (count) => count + 1); return scan === 1 ? ChildProcessSpawner.makeHandle({ ...handle, exitCode: handle.exitCode.pipe( Effect.tap(() => Deferred.succeed(firstRefScanCompleted, undefined)), ), }) : handle; }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, coordinatingSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); const inFlight = yield* driver .listRefs({ cwd, refresh: true, limit: 100 }) .pipe(Effect.forkChild({ startImmediately: true })); yield* Deferred.await(firstWorktreeScanStarted); yield* Deferred.await(firstRefScanCompleted); yield* driver.createRef({ cwd, refName: "feature/during-refresh" }); yield* Deferred.succeed(releaseFirstWorktreeScan, undefined); const refs = yield* Fiber.join(inFlight); assert.isTrue(refs.refs.some((ref) => ref.name === "feature/during-refresh")); assert.equal(yield* Ref.get(refScans), 2); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))), ); it.effect("invalidates a ref snapshot when a mutation fails after changing Git", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const partiallyFailingSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } if (command.args[0] === "branch" && command.args[1] === "feature/partial-failure") { const handle = yield* delegate.spawn(command); yield* handle.exitCode; return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, partiallyFailingSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); yield* driver.listRefs({ cwd, refresh: true }); yield* driver.createRef({ cwd, refName: "feature/partial-failure" }).pipe(Effect.flip); const refs = yield* driver.listRefs({ cwd }); assert.isTrue(refs.refs.some((ref) => ref.name === "feature/partial-failure")); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))), ); it.effect("fails a ref snapshot when for-each-ref exits unsuccessfully", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const snapshotAttempts = yield* Ref.make(0); const failingSnapshotSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } if (command.args.includes("for-each-ref")) { yield* Ref.update(snapshotAttempts, (count) => count + 1); return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, failingSnapshotSpawner), ); const cwd = yield* makeTmpDir(); yield* initRepoWithCommit(cwd).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, driver)); const error = yield* driver.listRefs({ cwd, refresh: true }).pipe(Effect.flip); assert.deepInclude(error, { _tag: "GitCommandError", operation: "GitVcsDriver.listRefs.snapshotRefs", detail: "Git ref snapshot enumeration failed.", exitCode: 128, }); assert.equal(yield* Ref.get(snapshotAttempts), 1); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))), ); it.effect("marks the current branch when worktree metadata is unavailable", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const incompleteMetadataSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (!ChildProcess.isStandardCommand(command)) { return yield* Effect.die("expected a standard Git command"); } const isWorktreeRoot = command.args.includes("rev-parse") && command.args.includes("--show-toplevel"); const isWorktreeList = command.args.includes("worktree") && command.args.includes("--porcelain"); if (isWorktreeRoot || isWorktreeList) { return makeNonRepositoryHandle(); } return yield* delegate.spawn(command); }), ); const driver = yield* makeGitVcsDriverCore().pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, incompleteMetadataSpawner), ); const cwd = yield* makeTmpDir(); const { initialBranch } = yield* initRepoWithCommit(cwd).pipe( Effect.provideService(GitVcsDriver.GitVcsDriver, driver), ); const refs = yield* driver.listRefs({ cwd, refresh: true }); assert.isTrue(refs.isRepo); assert.isTrue(refs.refs.find((ref) => ref.name === initialBranch)?.current); }), ).pipe(Effect.provide(ServerConfigLayer.pipe(Layer.provideMerge(NodeServices.layer)))), ); it.effect("ignores worktree metadata for directories that no longer exist", () => Effect.scoped( Effect.gen(function* () { const delegate = yield* ChildProcessSpawner.ChildProcessSpawner; const missingWorktreePath = "/missing/deleted-worktree";