MCPcopy Index your code
hub / github.com/anomalyco/opencode / run

Function run

packages/core/src/ripgrep.ts:98–152  ·  view source on GitHub ↗
(input: {
      readonly cwd: string
      readonly args: string[]
      readonly limit: number
      readonly signal?: AbortSignal
      readonly parse: (line: string) => Effect.Effect<A | undefined, Error>
      readonly pattern?: string
      readonly onItem?: (item: A) => Effect.Effect<void>
    })

Source from the content-addressed store, hash-verified

96 const binary = yield* RipgrepBinary.Service
97
98 const run = <A>(input: {
99 readonly cwd: string
100 readonly args: string[]
101 readonly limit: number
102 readonly signal?: AbortSignal
103 readonly parse: (line: string) => Effect.Effect<A | undefined, Error>
104 readonly pattern?: string
105 readonly onItem?: (item: A) => Effect.Effect<void>
106 }) => {
107 const program = Effect.scoped(
108 Effect.gen(function* () {
109 const handle = yield* process.spawn(
110 ChildProcess.make(yield* binary.filepath, input.args, { cwd: input.cwd, extendEnv: true, stdin: "ignore" }),
111 )
112 const stderrFiber = yield* collectStream(handle.stderr, ERROR_BYTES).pipe(
113 Effect.map((output) => output.buffer.toString("utf8")),
114 Effect.forkScoped,
115 )
116 let observed = 0
117 const rows = yield* Stream.decodeText(handle.stdout).pipe(
118 Stream.splitLines,
119 Stream.filter((line) => line.length > 0),
120 Stream.mapEffect(input.parse),
121 Stream.filter((row): row is A => row !== undefined),
122 Stream.tap((row) => {
123 if (!input.onItem || observed++ >= input.limit) return Effect.void
124 return input.onItem(row)
125 }),
126 Stream.take(input.limit + 1),
127 Stream.runCollect,
128 Effect.map((chunk) => [...chunk]),
129 )
130 const truncated = rows.length > input.limit
131 if (truncated) return { items: rows.slice(0, input.limit), truncated, partial: false }
132
133 const code = yield* handle.exitCode
134 const stderr = yield* Fiber.join(stderrFiber)
135 if (input.pattern && code === 2 && isInvalidPattern(stderr)) {
136 return yield* new InvalidPatternError({ pattern: input.pattern, message: stderr.trim() })
137 }
138 if (code !== 0 && code !== 1 && code !== 2) {
139 return yield* failure(stderr.trim() || `ripgrep failed with code ${code}`)
140 }
141 return { items: code === 1 ? [] : rows, truncated: false, partial: code === 2 }
142 }),
143 )
144 const abortable = input.signal ? program.pipe(Effect.raceFirst(waitForAbort(input.signal))) : program
145 return abortable.pipe(
146 Effect.mapError((cause) =>
147 cause instanceof Error || cause instanceof InvalidPatternError
148 ? cause
149 : failure("ripgrep execution failed", cause),
150 ),
151 )
152 }
153
154 return Service.of({
155 glob: (input) =>

Callers 1

ripgrep.tsFile · 0.70

Calls 6

collectStreamFunction · 0.90
waitForAbortFunction · 0.90
isInvalidPatternFunction · 0.85
spawnMethod · 0.80
failureFunction · 0.70
makeMethod · 0.45

Tested by

no test coverage detected