feat(core): project copying and tracking directories (#30139)

This commit is contained in:
James Long
2026-06-02 23:26:10 -04:00
committed by GitHub
parent 7a66eae586
commit 147c6c4d51
28 changed files with 3638 additions and 10 deletions

View File

@@ -1,8 +1,10 @@
import { describe, expect } from "bun:test"
import { $ } from "bun"
import fs from "fs/promises"
import path from "path"
import { Effect } from "effect"
import { Git } from "@opencode-ai/core/git"
import { AbsolutePath } from "@opencode-ai/core/schema"
import { branch, commit, gitRemote } from "./fixture/git"
import { tmpdir } from "./fixture/tmpdir"
import { testEffect } from "./lib/effect"
@@ -64,3 +66,41 @@ function withRemote<A, E, R>(body: (fixture: Awaited<ReturnType<typeof gitRemote
function read(file: string) {
return Effect.promise(() => fs.readFile(file, "utf8")).pipe(Effect.map((content) => content.replace(/\r\n/g, "\n")))
}
async function initRepo(directory: string) {
await $`git init`.cwd(directory).quiet()
await $`git config core.fsmonitor false`.cwd(directory).quiet()
await $`git config commit.gpgsign false`.cwd(directory).quiet()
await $`git config user.email test@opencode.test`.cwd(directory).quiet()
await $`git config user.name Test`.cwd(directory).quiet()
await $`git commit --allow-empty -m root`.cwd(directory).quiet()
}
describe("Git worktrees", () => {
it.live("creates, lists, and removes linked worktrees", () =>
Effect.gen(function* () {
const root = yield* Effect.acquireRelease(
Effect.promise(() => tmpdir()),
(dir) => Effect.promise(() => dir[Symbol.asyncDispose]()),
)
yield* Effect.promise(() => initRepo(root.path))
const directory = AbsolutePath.make(yield* Effect.promise(() => fs.realpath(root.path)))
const worktree = AbsolutePath.make(`${root.path}-git-worktree`)
yield* Effect.addFinalizer(() =>
Effect.promise(() => fs.rm(worktree, { recursive: true, force: true })).pipe(Effect.ignore),
)
const git = yield* Git.Service
const repo = { directory, store: AbsolutePath.make(path.join(directory, ".git")) }
yield* git.worktreeCreate({ repo, directory: worktree })
expect((yield* git.worktreeList(repo)).some((entry) => entry.endsWith("-git-worktree"))).toBe(true)
const linked = yield* git.find(worktree)
expect(linked?.directory).toBe(AbsolutePath.make(yield* Effect.promise(() => fs.realpath(worktree))))
expect(linked?.store).toBe(repo.store)
if (!linked) throw new Error("Linked worktree not found")
yield* git.worktreeRemove({ repo: linked, directory: worktree })
expect((yield* git.worktreeList(repo)).some((entry) => entry.endsWith("-git-worktree"))).toBe(false)
}),
)
})