Преглед изворни кода

fix: retry scoped tempdir cleanup on windows

Kit Langton пре 3 недеља
родитељ
комит
4ff0fbc043
1 измењених фајлова са 17 додато и 7 уклоњено
  1. 17 7
      packages/opencode/test/fixture/fixture.ts

+ 17 - 7
packages/opencode/test/fixture/fixture.ts

@@ -2,7 +2,7 @@ import { $ } from "bun"
 import * as fs from "fs/promises"
 import * as fs from "fs/promises"
 import os from "os"
 import os from "os"
 import path from "path"
 import path from "path"
-import { Effect, FileSystem, ServiceMap } from "effect"
+import { Effect, ServiceMap } from "effect"
 import type * as PlatformError from "effect/PlatformError"
 import type * as PlatformError from "effect/PlatformError"
 import type * as Scope from "effect/Scope"
 import type * as Scope from "effect/Scope"
 import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
 import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
@@ -82,9 +82,17 @@ export async function tmpdir<T>(options?: TmpDirOptions<T>) {
 /** Effectful scoped tmpdir. Cleaned up when the scope closes. Make sure these stay in sync */
 /** Effectful scoped tmpdir. Cleaned up when the scope closes. Make sure these stay in sync */
 export function tmpdirScoped(options?: { git?: boolean; config?: Partial<Config.Info> }) {
 export function tmpdirScoped(options?: { git?: boolean; config?: Partial<Config.Info> }) {
   return Effect.gen(function* () {
   return Effect.gen(function* () {
-    const fs = yield* FileSystem.FileSystem
     const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
     const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
-    const dir = yield* fs.makeTempDirectoryScoped({ prefix: "opencode-test-" })
+    const dirpath = sanitizePath(path.join(os.tmpdir(), "opencode-test-" + Math.random().toString(36).slice(2)))
+    yield* Effect.promise(() => fs.mkdir(dirpath, { recursive: true }))
+    const dir = sanitizePath(yield* Effect.promise(() => fs.realpath(dirpath)))
+
+    yield* Effect.addFinalizer(() =>
+      Effect.promise(async () => {
+        if (options?.git) await stop(dir).catch(() => undefined)
+        await clean(dir).catch(() => undefined)
+      }),
+    )
 
 
     const git = (...args: string[]) =>
     const git = (...args: string[]) =>
       spawner.spawn(ChildProcess.make("git", args, { cwd: dir })).pipe(Effect.flatMap((handle) => handle.exitCode))
       spawner.spawn(ChildProcess.make("git", args, { cwd: dir })).pipe(Effect.flatMap((handle) => handle.exitCode))
@@ -98,9 +106,11 @@ export function tmpdirScoped(options?: { git?: boolean; config?: Partial<Config.
     }
     }
 
 
     if (options?.config) {
     if (options?.config) {
-      yield* fs.writeFileString(
-        path.join(dir, "opencode.json"),
-        JSON.stringify({ $schema: "https://opencode.ai/config.json", ...options.config }),
+      yield* Effect.promise(() =>
+        fs.writeFile(
+          path.join(dir, "opencode.json"),
+          JSON.stringify({ $schema: "https://opencode.ai/config.json", ...options.config }),
+        ),
       )
       )
     }
     }
 
 
@@ -150,7 +160,7 @@ export function provideTmpdirServer<A, E, R>(
 ): Effect.Effect<
 ): Effect.Effect<
   A,
   A,
   E | PlatformError.PlatformError,
   E | PlatformError.PlatformError,
-  R | TestLLMServer | FileSystem.FileSystem | ChildProcessSpawner.ChildProcessSpawner | Scope.Scope
+  R | TestLLMServer | ChildProcessSpawner.ChildProcessSpawner | Scope.Scope
 > {
 > {
   return Effect.gen(function* () {
   return Effect.gen(function* () {
     const llm = yield* TestLLMServer
     const llm = yield* TestLLMServer