runStreaming function

Future<int> runStreaming(
  1. String executable,
  2. List<String> args, {
  3. String? workingDirectory,
})

Runs executable and streams its stdout/stderr to the terminal in real time. Returns the exit code.

Implementation

Future<int> runStreaming(String executable, List<String> args, {String? workingDirectory}) async {
  final process = await Process.start(executable, args, workingDirectory: workingDirectory);

  // Kill the child process if the parent is interrupted (Ctrl+C).
  // SIGINT/SIGTERM watch is not supported on Windows.
  StreamSubscription? sigintSub;
  StreamSubscription? sigtermSub;
  if (!Platform.isWindows) {
    sigintSub = ProcessSignal.sigint.watch().listen((_) {
      process.kill(ProcessSignal.sigint);
      exit(130); // 128 + SIGINT
    });
    sigtermSub = ProcessSignal.sigterm.watch().listen((_) {
      process.kill(ProcessSignal.sigterm);
      exit(143); // 128 + SIGTERM
    });
  }

  // Use listen().asFuture() instead of pipe() — pipe() closes the sink when
  // the stream ends, which would close nitrogen's own stdout/stderr for all
  // subsequent output.
  await Future.wait([
    process.stdout.listen(stdout.add).asFuture<void>(),
    process.stderr.listen(stderr.add).asFuture<void>(),
  ]);

  await sigintSub?.cancel();
  await sigtermSub?.cancel();

  return process.exitCode;
}