silenceUntilFailure function

Script silenceUntilFailure(
  1. FutureOr<void> callback(
    1. Stream<List<int>> stdin
    ), {
  2. String? name,
  3. bool? when,
  4. bool stderrOnly = false,
  5. bool onSignal(
    1. ProcessSignal signal
    )?,
})

Runs callback in a Script.capture block and silences all stdout and stderr emitted by Scripts or calls to print within it until the callback produces an error.

If and when callback produces an error, all the silenced output will be forwarded to the returned script's Script.stdout and Script.stderr streams.

If when is false, this doesn't silence any output. If stderrOnly is false, this only silences stderr and passes stdout on as normal.

The callback can't be interrupted by calling kill, but the onSignal callback allows capturing those signals so the callback may react appropriately. When no onSignal handler was set, calling kill will do nothing and return false.

Implementation

Script silenceUntilFailure(
    FutureOr<void> Function(Stream<List<int>> stdin) callback,
    {String? name,
    bool? when,
    bool stderrOnly = false,
    bool onSignal(ProcessSignal signal)?}) {
  // Wrap this in an additional [Script.capture] so that we can both handle the
  // failure *and* still have it be top-leveled if it's not handled by the
  // caller.
  return Script.capture((stdin) async {
    if (when == false) {
      await callback(stdin);
      return;
    }

    var script = BufferedScript.capture((_) => callback(stdin),
        name: name == null ? null : '$name.inner', stderrOnly: stderrOnly);

    try {
      await script.done;
    } catch (_) {
      script.release();

      // Give the new stdio a chance to propagate.
      await Future<void>.delayed(Duration.zero);
      rethrow;
    }
  }, name: name, onSignal: onSignal);
}