capture<R> function
Run code in a zone which traps calls to print and printerr
redirecting them to the passed progress.
If no progress
is passed then then both print and printerr
output is surpressed.
Implementation
Future<Progress> capture<R>(Future<R> Function() action,
{Progress? progress}) async {
progress ??= Progress.devNull();
/// overload printerr so we can trap it.
final zoneValues = <String, CaptureZonePrintErr>{
'printerr': (line) {
if (line != null) {
progress!.addToStderr(line);
}
}
};
final zoneCompleter = Completer<R>();
runZonedGuarded(
/// runZone takes a sync method but we need
/// an async body s we can await the real [body]
/// method in [_body]
/// We then use the zoneCompleter to wait for the body to complete.
() => _unawaited(_body(action, zoneCompleter)),
(e, st) {
if (!zoneCompleter.isCompleted) {
zoneCompleter.complete(null);
}
},
zoneValues: zoneValues,
zoneSpecification: ZoneSpecification(
print: (self, parent, zone, line) => progress!.addToStdout(line),
),
);
await zoneCompleter.future;
// give the stream listeners a chance to flush.
await _flush(progress);
return progress;
}