run method

  1. @override
Future<ProcessResult> run([
  1. Stdout? stdout
])
override

Runs a command within a IShell environment. Returning the piped commands result. May throw CommandExceptions.

since 2.2.0

Implementation

@override
Future<ProcessResult> run([Stdout? stdout]) async {
  _commands.forEach(_requireSingleCommand);
  if (1 == _commands.length) {
    return _shell.run(_commands.first, stdout: stdout);
  } else {
    // TODO There is an issue at the moment catching a stream closing error.
    // this occurs when a previous processes stdout is fed to the next stdin
    // but the next is shutting down or is closed.
    var shell = _shell.copyWith(throwOnError: false);
    // ignore: omit_local_variable_types
    List<_PreviousPipe> pipes = _commands.fold([], (procs, command) {
      var prev = procs.isNotEmpty ? procs.last : null;
      var controller = (procs.length == _commands.length - 1)
          ? null
          : StreamController<List<int>>();
      var process = __prRun(
        shell,
        command,
        stdin: prev?.controller?.stream,
        stdout: controller?.sink ?? stdout,
      )..whenComplete(() async {
          await controller?.close();
        });
      return procs..add(_PreviousPipe(process, controller));
    });

    var results = (await Future.wait(
      pipes.map((e) async {
        return (await e.process).first;
      }).toList(),
    ))
        .map<ProcessResult>(
      (v) {
        return ProcessResult(
          v.pid,
          v.exitCode,
          tryTrimRight(v.stdout),
          tryTrimRight(v.stderr),
        );
      },
    ).toList();
    if (_shell.throwsOnError() && results.any(_nonZeroExitCode)) {
      var firstError = results.firstWhere(_nonZeroExitCode);
      var res = PipedProcessResult(results, firstError);
      throw PipedCommandResultException(
        firstError.stdout,
        res,
        _commands.join(' | '),
      );
    } else {
      return PipedProcessResult(results, results.last);
    }
  }
}