runProcess method
Runs a Process command and returns it.
commandName
is the command to be executed to start the Process.args
is the arguments to pass to the Process.- If
resolveCommandPath
istrue
resolvescommandName
to the local path of the command binary, using executablePath. workingDirectory
is the Process working directory. Ifnull
will use the current working directory.- If
handleSignals
istrue
kills the Process ifSIGINT
orSIGTERM
is triggered in the host/current process.onSignal
is the hook for when aSIGINT
orSIGTERM
is redirected.
- If
redirectOutput
istrue
redirects the Process outputs to the host/current stdout and stderr. - If
catchOutput
istrue
catches the Process outputs to ProcessInfo.outputBuffer and ProcessInfo.errorOutputBuffer. stdoutFilter
is a filter for the Processstdout
. Useful to remove sensitive data.stderrFilter
is a filter for the Processstderr
. 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;
}