mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-02 10:46:46 +00:00
refactor(effect): yield services instead of promise facades (#19325)
This commit is contained in:
@@ -11,9 +11,10 @@ import { Log } from "../util/log"
|
||||
import { Slug } from "@opencode-ai/util/slug"
|
||||
import { BusEvent } from "@/bus/bus-event"
|
||||
import { GlobalBus } from "@/bus/global"
|
||||
import { Effect, FileSystem, Layer, Path, Scope, ServiceMap, Stream } from "effect"
|
||||
import { Effect, Layer, Path, Scope, ServiceMap, Stream } from "effect"
|
||||
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
|
||||
import { NodeFileSystem, NodePath } from "@effect/platform-node"
|
||||
import { NodePath } from "@effect/platform-node"
|
||||
import { AppFileSystem } from "@/filesystem"
|
||||
import { makeRuntime } from "@/effect/run-service"
|
||||
import * as CrossSpawnSpawner from "@/effect/cross-spawn-spawner"
|
||||
|
||||
@@ -167,14 +168,15 @@ export namespace Worktree {
|
||||
export const layer: Layer.Layer<
|
||||
Service,
|
||||
never,
|
||||
FileSystem.FileSystem | Path.Path | ChildProcessSpawner.ChildProcessSpawner
|
||||
AppFileSystem.Service | Path.Path | ChildProcessSpawner.ChildProcessSpawner | Project.Service
|
||||
> = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const scope = yield* Scope.Scope
|
||||
const fsys = yield* FileSystem.FileSystem
|
||||
const fs = yield* AppFileSystem.Service
|
||||
const pathSvc = yield* Path.Path
|
||||
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
|
||||
const project = yield* Project.Service
|
||||
|
||||
const git = Effect.fnUntraced(
|
||||
function* (args: string[], opts?: { cwd?: string }) {
|
||||
@@ -201,7 +203,7 @@ export namespace Worktree {
|
||||
const branch = `opencode/${name}`
|
||||
const directory = pathSvc.join(root, name)
|
||||
|
||||
if (yield* fsys.exists(directory).pipe(Effect.orDie)) continue
|
||||
if (yield* fs.exists(directory).pipe(Effect.orDie)) continue
|
||||
|
||||
const ref = `refs/heads/${branch}`
|
||||
const branchCheck = yield* git(["show-ref", "--verify", "--quiet", ref], { cwd: Instance.worktree })
|
||||
@@ -218,7 +220,7 @@ export namespace Worktree {
|
||||
}
|
||||
|
||||
const root = pathSvc.join(Global.Path.data, "worktree", Instance.project.id)
|
||||
yield* fsys.makeDirectory(root, { recursive: true }).pipe(Effect.orDie)
|
||||
yield* fs.makeDirectory(root, { recursive: true }).pipe(Effect.orDie)
|
||||
|
||||
const base = name ? slugify(name) : ""
|
||||
return yield* candidate(root, base || undefined)
|
||||
@@ -232,7 +234,7 @@ export namespace Worktree {
|
||||
throw new CreateFailedError({ message: created.stderr || created.text || "Failed to create git worktree" })
|
||||
}
|
||||
|
||||
yield* Effect.promise(() => Project.addSandbox(Instance.project.id, info.directory).catch(() => undefined))
|
||||
yield* project.addSandbox(Instance.project.id, info.directory).pipe(Effect.catch(() => Effect.void))
|
||||
})
|
||||
|
||||
const boot = Effect.fnUntraced(function* (info: Info, startCommand?: string) {
|
||||
@@ -297,7 +299,7 @@ export namespace Worktree {
|
||||
|
||||
const canonical = Effect.fnUntraced(function* (input: string) {
|
||||
const abs = pathSvc.resolve(input)
|
||||
const real = yield* fsys.realPath(abs).pipe(Effect.catch(() => Effect.succeed(abs)))
|
||||
const real = yield* fs.realPath(abs).pipe(Effect.catch(() => Effect.succeed(abs)))
|
||||
const normalized = pathSvc.normalize(real)
|
||||
return process.platform === "win32" ? normalized.toLowerCase() : normalized
|
||||
})
|
||||
@@ -334,7 +336,7 @@ export namespace Worktree {
|
||||
})
|
||||
|
||||
function stopFsmonitor(target: string) {
|
||||
return fsys.exists(target).pipe(
|
||||
return fs.exists(target).pipe(
|
||||
Effect.orDie,
|
||||
Effect.flatMap((exists) => (exists ? git(["fsmonitor--daemon", "stop"], { cwd: target }) : Effect.void)),
|
||||
)
|
||||
@@ -364,7 +366,7 @@ export namespace Worktree {
|
||||
const entry = yield* locateWorktree(entries, directory)
|
||||
|
||||
if (!entry?.path) {
|
||||
const directoryExists = yield* fsys.exists(directory).pipe(Effect.orDie)
|
||||
const directoryExists = yield* fs.exists(directory).pipe(Effect.orDie)
|
||||
if (directoryExists) {
|
||||
yield* stopFsmonitor(directory)
|
||||
yield* cleanDirectory(directory)
|
||||
@@ -464,7 +466,7 @@ export namespace Worktree {
|
||||
const target = yield* canonical(pathSvc.resolve(root, entry))
|
||||
if (target === base) return
|
||||
if (!target.startsWith(`${base}${pathSvc.sep}`)) return
|
||||
yield* fsys.remove(target, { recursive: true }).pipe(Effect.ignore)
|
||||
yield* fs.remove(target, { recursive: true }).pipe(Effect.ignore)
|
||||
}),
|
||||
{ concurrency: "unbounded" },
|
||||
)
|
||||
@@ -603,8 +605,9 @@ export namespace Worktree {
|
||||
)
|
||||
|
||||
const defaultLayer = layer.pipe(
|
||||
Layer.provide(CrossSpawnSpawner.layer),
|
||||
Layer.provide(NodeFileSystem.layer),
|
||||
Layer.provide(CrossSpawnSpawner.defaultLayer),
|
||||
Layer.provide(Project.defaultLayer),
|
||||
Layer.provide(AppFileSystem.defaultLayer),
|
||||
Layer.provide(NodePath.layer),
|
||||
)
|
||||
const { runPromise } = makeRuntime(Service, defaultLayer)
|
||||
|
||||
Reference in New Issue
Block a user