runStreaming method

  1. @override
Future<ProcessResult> runStreaming(
  1. String executable,
  2. List<String> arguments, {
  3. Directory? workingDirectory,
  4. Map<String, String>? environment,
  5. bool requireSuccess = true,
})
override

Run a command and stream output in real-time.

Implementation

@override
Future<ProcessResult> runStreaming(
  String executable,
  List<String> arguments, {
  Directory? workingDirectory,
  Map<String, String>? environment,
  bool requireSuccess = true,
}) async {
  logger?.info('Running: $executable ${arguments.join(' ')}');

  final process = await Process.start(
    executable,
    arguments,
    workingDirectory: workingDirectory?.path,
    environment: environment,
  );

  final stdoutBuffer = StringBuffer();
  final stderrBuffer = StringBuffer();
  final stdoutDone = Completer<void>();
  final stderrDone = Completer<void>();

  process.stdout
      .transform(utf8.decoder)
      .listen(
        (chunk) {
          stdoutBuffer.write(chunk);
          final line = chunk.trimRight();
          if (line.isNotEmpty) {
            logger?.info('  $line');
          }
        },
        onDone: () => stdoutDone.complete(),
        onError: stdoutDone.completeError,
        cancelOnError: true,
      );

  process.stderr
      .transform(utf8.decoder)
      .listen(
        (chunk) {
          stderrBuffer.write(chunk);
          final line = chunk.trimRight();
          if (line.isNotEmpty) {
            logger?.warning('  $line');
          }
        },
        onDone: () => stderrDone.complete(),
        onError: stderrDone.completeError,
        cancelOnError: true,
      );

  final exitCode = await process.exitCode;
  await Future.wait([stdoutDone.future, stderrDone.future]);

  if (requireSuccess && exitCode != 0) {
    throw ProcessException(
      executable,
      arguments,
      'Process exited with code $exitCode',
      exitCode,
    );
  }

  return ProcessResult(
    exitCode: exitCode,
    stdout: stdoutBuffer.toString(),
    stderr: stderrBuffer.toString(),
  );
}