runProcess method
Runs a Process command and returns it.
- commandNameis the command to be executed to start the Process.
- argsis the arguments to pass to the Process.
- If resolveCommandPathistrueresolvescommandNameto the local path of the command binary, using executablePath.
- workingDirectoryis the Process working directory. If- nullwill use the current working directory.
- If handleSignalsistruekills the Process ifSIGINTorSIGTERMis triggered in the host/current process.- onSignalis the hook for when a- SIGINTor- SIGTERMis redirected.
 
- If redirectOutputistrueredirects the Process outputs to the host/current stdout and stderr.
- If catchOutputistruecatches the Process outputs to ProcessInfo.outputBuffer and ProcessInfo.errorOutputBuffer.
- stdoutFilteris a filter for the Process- stdout. Useful to remove sensitive data.
- stderrFilteris a filter for the Process- stderr. Useful to remove sensitive data.
Implementation
Future<ProcessInfo> runProcess(String commandName, List<String> args,
    {bool resolveCommandPath = true,
    String? workingDirectory,
    bool handleSignals = false,
    bool redirectOutput = false,
    bool catchOutput = false,
    String Function(String o)? stdoutFilter,
    String Function(String o)? stderrFilter,
    void Function(ProcessSignal signal)? onSignal}) async {
  String? binPath;
  if (resolveCommandPath) {
    binPath = await executablePath(commandName);
    if (binPath == null) {
      throw StateError('Error resolving `$commandName` binary!');
    }
  } else {
    binPath = commandName;
  }
  log('INFO',
      'Process.start> $binPath $args > workingDirectory: $workingDirectory');
  var process =
      await Process.start(binPath, args, workingDirectory: workingDirectory);
  StreamSubscription<ProcessSignal>? listenSigInt;
  StreamSubscription<ProcessSignal>? listenSigTerm;
  if (handleSignals) {
    listenSigInt = ProcessSignal.sigint.watch().listen((s) {
      if (onSignal != null) onSignal(s);
      process.kill(ProcessSignal.sigint);
    });
    listenSigTerm = ProcessSignal.sigterm.watch().listen((s) {
      if (onSignal != null) onSignal(s);
      process.kill(ProcessSignal.sigterm);
    });
  }
  var processInfo = ProcessInfo(process, binPath, args, workingDirectory);
  var outputDecoder = systemEncoding.decoder;
  final stdoutFilterF = stdoutFilter ?? (o) => o;
  final stderrFilterF = stderrFilter ?? (o) => o;
  if (catchOutput && redirectOutput) {
    // ignore: unawaited_futures
    process.stdout.transform(outputDecoder).forEach((o) {
      o = stdoutFilterF(o);
      stdout.write(o);
      processInfo.outputBuffer.add(o);
    });
    // ignore: unawaited_futures
    process.stderr.transform(outputDecoder).forEach((o) {
      o = stderrFilterF(o);
      stderr.write(o);
      processInfo.errorOutputBuffer.add(o);
    });
  } else if (catchOutput) {
    // ignore: unawaited_futures
    process.stdout.transform(outputDecoder).forEach((o) {
      o = stdoutFilterF(o);
      processInfo.outputBuffer.add(o);
    });
    // ignore: unawaited_futures
    process.stderr.transform(outputDecoder).forEach((o) {
      o = stderrFilterF(o);
      processInfo.errorOutputBuffer.add(o);
    });
  } else if (redirectOutput) {
    // ignore: unawaited_futures
    process.stdout.transform(outputDecoder).forEach((o) {
      o = stdoutFilterF(o);
      stdout.write(o);
    });
    // ignore: unawaited_futures
    process.stderr.transform(outputDecoder).forEach((o) {
      o = stderrFilterF(o);
      stderr.write(o);
    });
  }
  process.exitCode.then((_) {
    // ignore: unawaited_futures
    listenSigInt?.cancel();
    // ignore: unawaited_futures
    listenSigTerm?.cancel();
  });
  return processInfo;
}