runStreaming function
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;
}