xargs method
Passes the strings emitted by this stream as arguments to callback
.
The callback
is invoked within a Script.capture block, so any stdout
or stderr it emits will be piped into the returned Script's stdout and
stderr streams. If any callback
throws an error or starts a Script
that fails with a non-zero exit code, the returned Script will fail as
well.
Waits for each callback
to complete before executing the next one. While
it's possible for callbacks to run in parallel by returning before the
processing is complete, this is not recommended, as it will cause error and
output streams from multiple callbacks to become mangled and could cause
later callbacks to be executed even if earlier ones failed.
If maxArgs
is passed, this invokes callback
multiple times, passing at
most maxArgs
arguments to each invocation. Otherwise, it passes all
arguments to a single invocation.
If name
is passed, it's used as the name of the spawned script.
Script.kill closes the input stream. It returns true
if the stream was
interrupted and the script exits with Script.exitCode 143
, or false
if the stream was already closed.
The callback
can't be interrupted by calling kill
, but the onSignal
callback allows capturing those signals so the callback may react
appropriately. Calling kill
returns true
even without an onSignal
callback if the stream is interrupted.
See also xargs
in package:cli_script/cli_script.dart
, which takes
arguments from stdin rather than from this string stream.
Implementation
Script xargs(FutureOr<void> callback(List<String> args),
{int? maxArgs, String? name, void onSignal(ProcessSignal signal)?}) {
if (maxArgs != null && maxArgs < 1) {
throw RangeError.range(maxArgs, 1, null, 'maxArgs');
}
var signalCloser = StreamCloser<String>();
var self = transform(signalCloser);
var chunks =
maxArgs != null ? self.slices(maxArgs) : self.toList().asStream();
return Script.capture(
(_) async {
await for (var chunk in chunks) {
if (signalCloser.isClosed) break;
await callback(chunk);
}
if (signalCloser.isClosed) {
throw ScriptException(name ?? 'xargs', 143);
}
},
name: name,
onSignal: (signal) {
signalCloser.close();
if (onSignal != null) onSignal(signal);
return true;
});
}