run method
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);
}
}
}