mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-13 15:44:56 +00:00
effect(git): migrate to AppProcess.run
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { AppProcess } from "@opencode-ai/core/process"
|
||||
import { Effect, Layer, Context, Stream } from "effect"
|
||||
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
|
||||
import { ChildProcess } from "effect/unstable/process"
|
||||
|
||||
const cfg = [
|
||||
"--no-optional-locks",
|
||||
@@ -102,49 +102,31 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/Gi
|
||||
export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
|
||||
const appProcess = yield* AppProcess.Service
|
||||
const encoder = new TextEncoder()
|
||||
const stdin = (text: string) => Stream.make(encoder.encode(text))
|
||||
|
||||
const run = Effect.fn("Git.run")(
|
||||
function* (args: string[], opts: Options) {
|
||||
const proc = ChildProcess.make("git", [...cfg, ...args], {
|
||||
cwd: opts.cwd,
|
||||
env: opts.env,
|
||||
extendEnv: true,
|
||||
stdin: opts.stdin ?? "ignore",
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
})
|
||||
const handle = yield* spawner.spawn(proc)
|
||||
const collect = (stream: typeof handle.stdout) =>
|
||||
Stream.runFold(
|
||||
stream,
|
||||
() => ({ chunks: [] as Uint8Array[], bytes: 0, truncated: false }),
|
||||
(acc, chunk) => {
|
||||
if (opts.maxOutputBytes === undefined) {
|
||||
acc.chunks.push(chunk)
|
||||
acc.bytes += chunk.length
|
||||
return acc
|
||||
}
|
||||
|
||||
const remaining = opts.maxOutputBytes - acc.bytes
|
||||
if (remaining > 0) acc.chunks.push(remaining >= chunk.length ? chunk : chunk.slice(0, remaining))
|
||||
acc.bytes += chunk.length
|
||||
acc.truncated = acc.truncated || acc.bytes > opts.maxOutputBytes
|
||||
return acc
|
||||
},
|
||||
).pipe(Effect.map((x) => ({ buffer: Buffer.concat(x.chunks), truncated: x.truncated })))
|
||||
const [stdout, stderr] = yield* Effect.all([collect(handle.stdout), collect(handle.stderr)], { concurrency: 2 })
|
||||
const result = yield* appProcess.run(
|
||||
ChildProcess.make("git", [...cfg, ...args], {
|
||||
cwd: opts.cwd,
|
||||
env: opts.env,
|
||||
extendEnv: true,
|
||||
stdin: opts.stdin ?? "ignore",
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
}),
|
||||
{ maxOutputBytes: opts.maxOutputBytes },
|
||||
)
|
||||
return {
|
||||
exitCode: yield* handle.exitCode,
|
||||
text: () => stdout.buffer.toString("utf8"),
|
||||
stdout: stdout.buffer,
|
||||
stderr: stderr.buffer,
|
||||
truncated: stdout.truncated || stderr.truncated,
|
||||
exitCode: result.exitCode,
|
||||
text: () => result.stdout.toString("utf8"),
|
||||
stdout: result.stdout,
|
||||
stderr: result.stderr,
|
||||
truncated: result.truncated,
|
||||
} satisfies Result
|
||||
},
|
||||
Effect.scoped,
|
||||
Effect.catch((err) => Effect.succeed(fail(err))),
|
||||
)
|
||||
|
||||
@@ -360,6 +342,6 @@ export const layer = Layer.effect(
|
||||
}),
|
||||
)
|
||||
|
||||
export const defaultLayer = layer.pipe(Layer.provide(CrossSpawnSpawner.defaultLayer))
|
||||
export const defaultLayer = layer.pipe(Layer.provide(AppProcess.defaultLayer))
|
||||
|
||||
export * as Git from "."
|
||||
|
||||
Reference in New Issue
Block a user