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

refactor(ripgrep): migrate result schemas to effect (#24213)

Kit Langton пре 4 месеци
родитељ
комит
5a04de231e
2 измењених фајлова са 63 додато и 66 уклоњено
  1. 62 65
      packages/opencode/src/file/ripgrep.ts
  2. 1 1
      packages/opencode/src/server/routes/instance/file.ts

+ 62 - 65
packages/opencode/src/file/ripgrep.ts

@@ -1,7 +1,6 @@
 import path from "path"
 import path from "path"
-import z from "zod"
 import { AppFileSystem } from "@opencode-ai/shared/filesystem"
 import { AppFileSystem } from "@opencode-ai/shared/filesystem"
-import { Cause, Context, Effect, Fiber, Layer, Queue, Stream } from "effect"
+import { Cause, Context, Effect, Fiber, Layer, Queue, Schema, Stream } from "effect"
 import type { PlatformError } from "effect/PlatformError"
 import type { PlatformError } from "effect/PlatformError"
 import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http"
 import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http"
 import { ChildProcess } from "effect/unstable/process"
 import { ChildProcess } from "effect/unstable/process"
@@ -12,6 +11,8 @@ import { Global } from "@/global"
 import { Log } from "@/util"
 import { Log } from "@/util"
 import { sanitizedProcessEnv } from "@/util/opencode-process"
 import { sanitizedProcessEnv } from "@/util/opencode-process"
 import { which } from "@/util/which"
 import { which } from "@/util/which"
+import { zod } from "@/util/effect-zod"
+import { withStatics } from "@/util/schema"
 
 
 const log = Log.create({ service: "ripgrep" })
 const log = Log.create({ service: "ripgrep" })
 const VERSION = "15.1.0"
 const VERSION = "15.1.0"
@@ -25,83 +26,82 @@ const PLATFORM = {
   "x64-win32": { platform: "x86_64-pc-windows-msvc", extension: "zip" },
   "x64-win32": { platform: "x86_64-pc-windows-msvc", extension: "zip" },
 } as const
 } as const
 
 
-const Stats = z.object({
-  elapsed: z.object({
-    secs: z.number(),
-    nanos: z.number(),
-    human: z.string(),
-  }),
-  searches: z.number(),
-  searches_with_match: z.number(),
-  bytes_searched: z.number(),
-  bytes_printed: z.number(),
-  matched_lines: z.number(),
-  matches: z.number(),
+const TimeStats = Schema.Struct({
+  secs: Schema.Number,
+  nanos: Schema.Number,
+  human: Schema.String,
 })
 })
 
 
-const Begin = z.object({
-  type: z.literal("begin"),
-  data: z.object({
-    path: z.object({
-      text: z.string(),
-    }),
-  }),
+const Stats = Schema.Struct({
+  elapsed: TimeStats,
+  searches: Schema.Number,
+  searches_with_match: Schema.Number,
+  bytes_searched: Schema.Number,
+  bytes_printed: Schema.Number,
+  matched_lines: Schema.Number,
+  matches: Schema.Number,
 })
 })
 
 
-export const Match = z.object({
-  type: z.literal("match"),
-  data: z.object({
-    path: z.object({
-      text: z.string(),
-    }),
-    lines: z.object({
-      text: z.string(),
-    }),
-    line_number: z.number(),
-    absolute_offset: z.number(),
-    submatches: z.array(
-      z.object({
-        match: z.object({
-          text: z.string(),
-        }),
-        start: z.number(),
-        end: z.number(),
-      }),
-    ),
+const PathText = Schema.Struct({
+  text: Schema.String,
+})
+
+const Begin = Schema.Struct({
+  type: Schema.Literal("begin"),
+  data: Schema.Struct({
+    path: PathText,
   }),
   }),
 })
 })
 
 
-const End = z.object({
-  type: z.literal("end"),
-  data: z.object({
-    path: z.object({
-      text: z.string(),
+export const SearchMatch = Schema.Struct({
+  path: PathText,
+  lines: Schema.Struct({
+    text: Schema.String,
+  }),
+  line_number: Schema.Number,
+  absolute_offset: Schema.Number,
+  submatches: Schema.Array(
+    Schema.Struct({
+      match: Schema.Struct({
+        text: Schema.String,
+      }),
+      start: Schema.Number,
+      end: Schema.Number,
     }),
     }),
-    binary_offset: z.number().nullable(),
+  ),
+}).pipe(withStatics((s) => ({ zod: zod(s) })))
+
+export const Match = Schema.Struct({
+  type: Schema.Literal("match"),
+  data: SearchMatch,
+})
+
+const End = Schema.Struct({
+  type: Schema.Literal("end"),
+  data: Schema.Struct({
+    path: PathText,
+    binary_offset: Schema.NullOr(Schema.Number),
     stats: Stats,
     stats: Stats,
   }),
   }),
 })
 })
 
 
-const Summary = z.object({
-  type: z.literal("summary"),
-  data: z.object({
-    elapsed_total: z.object({
-      human: z.string(),
-      nanos: z.number(),
-      secs: z.number(),
-    }),
+const Summary = Schema.Struct({
+  type: Schema.Literal("summary"),
+  data: Schema.Struct({
+    elapsed_total: TimeStats,
     stats: Stats,
     stats: Stats,
   }),
   }),
 })
 })
 
 
-const Result = z.union([Begin, Match, End, Summary])
+const Result = Schema.Union([Begin, Match, End, Summary])
+const decodeResult = Schema.decodeUnknownEffect(Schema.fromJsonString(Result))
 
 
-export type Result = z.infer<typeof Result>
-export type Match = z.infer<typeof Match>
+export type Result = Schema.Schema.Type<typeof Result>
+export type Match = Schema.Schema.Type<typeof Match>
 export type Item = Match["data"]
 export type Item = Match["data"]
-export type Begin = z.infer<typeof Begin>
-export type End = z.infer<typeof End>
-export type Summary = z.infer<typeof Summary>
+export type Begin = Schema.Schema.Type<typeof Begin>
+export type End = Schema.Schema.Type<typeof End>
+export type Summary = Schema.Schema.Type<typeof Summary>
 export type Row = Match["data"]
 export type Row = Match["data"]
 
 
 export interface SearchResult {
 export interface SearchResult {
@@ -187,10 +187,7 @@ function row(data: Row): Row {
 }
 }
 
 
 function parse(line: string) {
 function parse(line: string) {
-  return Effect.try({
-    try: () => Result.parse(JSON.parse(line)),
-    catch: (cause) => new Error("invalid ripgrep output", { cause }),
-  })
+  return decodeResult(line).pipe(Effect.mapError((cause) => new Error("invalid ripgrep output", { cause })))
 }
 }
 
 
 function fail(queue: Queue.Queue<string, PlatformError | Error | Cause.Done>, err: PlatformError | Error) {
 function fail(queue: Queue.Queue<string, PlatformError | Error | Cause.Done>, err: PlatformError | Error) {

+ 1 - 1
packages/opencode/src/server/routes/instance/file.ts

@@ -21,7 +21,7 @@ export const FileRoutes = lazy(() =>
             description: "Matches",
             description: "Matches",
             content: {
             content: {
               "application/json": {
               "application/json": {
-                schema: resolver(Ripgrep.Match.shape.data.array()),
+                schema: resolver(Ripgrep.SearchMatch.zod.array()),
               },
               },
             },
             },
           },
           },