(command: ChildProcess.Command, options?: RunOptions)
| 142 | const spawner = yield* ChildProcessSpawner |
| 143 | |
| 144 | const runCommand = (command: ChildProcess.Command, options?: RunOptions) => { |
| 145 | const description = describeCommand(command) |
| 146 | const collect = Effect.scoped( |
| 147 | Effect.gen(function* () { |
| 148 | const handle = yield* spawner.spawn(command) |
| 149 | if (options?.combineOutput) { |
| 150 | const [output, exitCode] = yield* Effect.all( |
| 151 | [collectStream(handle.all, options.maxOutputBytes), handle.exitCode], |
| 152 | { concurrency: "unbounded" }, |
| 153 | ) |
| 154 | return { |
| 155 | command: description, |
| 156 | exitCode, |
| 157 | output: output.buffer, |
| 158 | stdout: Buffer.alloc(0), |
| 159 | stderr: Buffer.alloc(0), |
| 160 | outputTruncated: output.truncated, |
| 161 | stdoutTruncated: false, |
| 162 | stderrTruncated: false, |
| 163 | } satisfies RunResult |
| 164 | } |
| 165 | const [stdout, stderr, exitCode] = yield* Effect.all( |
| 166 | [ |
| 167 | collectStream(handle.stdout, options?.maxOutputBytes), |
| 168 | collectStream(handle.stderr, options?.maxErrorBytes), |
| 169 | handle.exitCode, |
| 170 | ], |
| 171 | { concurrency: "unbounded" }, |
| 172 | ) |
| 173 | return { |
| 174 | command: description, |
| 175 | exitCode, |
| 176 | stdout: stdout.buffer, |
| 177 | stderr: stderr.buffer, |
| 178 | stdoutTruncated: stdout.truncated, |
| 179 | stderrTruncated: stderr.truncated, |
| 180 | } satisfies RunResult |
| 181 | }), |
| 182 | ) |
| 183 | const timed = options?.timeout |
| 184 | ? Effect.timeoutOrElse(collect, { |
| 185 | duration: options.timeout, |
| 186 | orElse: () => Effect.fail(new AppProcessError({ command: description, cause: new Error("Timed out") })), |
| 187 | }) |
| 188 | : collect |
| 189 | const aborted = options?.signal |
| 190 | ? timed.pipe( |
| 191 | Effect.raceFirst( |
| 192 | waitForAbort(options.signal).pipe(Effect.mapError((cause) => wrapError(description, cause))), |
| 193 | ), |
| 194 | ) |
| 195 | : timed |
| 196 | return aborted.pipe(Effect.catch((cause) => Effect.fail(wrapError(description, cause)))) |
| 197 | } |
| 198 | |
| 199 | const run = Effect.fn("AppProcess.run")(function* (command: ChildProcess.Command, options?: RunOptions) { |
| 200 | if (options?.stdin === undefined) return yield* runCommand(command, options) |
no test coverage detected