| Index: tools/gardening/lib/src/logdog.dart
|
| diff --git a/tools/gardening/lib/src/logdog.dart b/tools/gardening/lib/src/logdog.dart
|
| index c18d539314293da901834b715e82db6b38659d8c..2eb887554b2a521dda9045dc790c316bc3c3b39b 100644
|
| --- a/tools/gardening/lib/src/logdog.dart
|
| +++ b/tools/gardening/lib/src/logdog.dart
|
| @@ -5,19 +5,39 @@
|
| import 'dart:io';
|
| import 'dart:async';
|
| import 'dart:collection';
|
| +import 'dart:convert';
|
| +
|
| +import 'util.dart';
|
|
|
| final String cit = Platform.isWindows ? 'cit.bat' : 'cit';
|
|
|
| +enum LogdogExitKind {
|
| + /// Normal program termination with a negative exit code.
|
| + normal,
|
| +
|
| + /// Program killed due to error output.
|
| + error,
|
| +
|
| + /// Program killed due to timeout.
|
| + timeout,
|
| +}
|
| +
|
| class LogdogException implements Exception {
|
| + final List<String> command;
|
| final int errorCode;
|
| final String stdout;
|
| final String stderr;
|
| + final LogdogExitKind exitKind;
|
|
|
| - LogdogException(this.errorCode, this.stdout, this.stderr);
|
| + LogdogException(
|
| + this.command, this.errorCode, this.stdout, this.stderr, this.exitKind);
|
| LogdogException.fromProcessResult(ProcessResult result)
|
| - : this(result.exitCode, result.stdout, result.stderr);
|
| + : this(null, result.exitCode, result.stdout, result.stderr,
|
| + LogdogExitKind.normal);
|
|
|
| - toString() => "Error during logdog execution:\n$stderr";
|
| + toString() => "Error during logdog execution"
|
| + "${command != null ? ' `${command.join(' ')}`': ''}"
|
| + ":\n$stderr";
|
| }
|
|
|
| bool logdogCheckDone = false;
|
| @@ -44,22 +64,55 @@ void checkLogdog({bool tryToInstall: true}) {
|
| }
|
| }
|
|
|
| -String logdog(List<String> args) {
|
| +Future<String> logdog(List<String> args,
|
| + {bool exitOnError: true,
|
| + Duration timeout: const Duration(seconds: 10)}) async {
|
| checkLogdog();
|
| args = args.toList()..insert(0, "logdog");
|
| - var result = Process.runSync(cit, args);
|
| - if (result.exitCode == 0) return result.stdout;
|
| - throw new LogdogException.fromProcessResult(result);
|
| +
|
| + LogdogExitKind exitKind = LogdogExitKind.normal;
|
| + Process process = await Process.start(cit, args);
|
| + StringBuffer stdout = new StringBuffer();
|
| + StringBuffer stderr = new StringBuffer();
|
| + StreamSubscription stdoutSubscription =
|
| + process.stdout.transform(UTF8.decoder).listen(stdout.write);
|
| + StreamSubscription stderrSubscription =
|
| + process.stderr.transform(UTF8.decoder).listen((String text) {
|
| + stderr.write(text);
|
| + if (exitOnError) {
|
| + exitKind = LogdogExitKind.error;
|
| + log('Error on `${args.join(' ')}`: $text');
|
| + process.kill();
|
| + }
|
| + });
|
| + Timer timer;
|
| + if (timeout != null) {
|
| + timer = new Timer(timeout, () {
|
| + exitKind = LogdogExitKind.timeout;
|
| + log('Timeout on `${args.join(' ')}`');
|
| + process.kill();
|
| + });
|
| + }
|
| + int exitCode = await process.exitCode;
|
| + // Cancel the timer; it might still be running.
|
| + timer?.cancel();
|
| + // Cancel the stdout/stderr subscriptions; if the process is killed the
|
| + // streams might not have closed.
|
| + stdoutSubscription.cancel();
|
| + stderrSubscription.cancel();
|
| + if (exitCode == 0) return stdout.toString();
|
| + throw new LogdogException(
|
| + args, exitCode, stdout.toString(), stderr.toString(), exitKind);
|
| }
|
|
|
| -String cat(String log) {
|
| +Future<String> cat(String log) async {
|
| return logdog(["cat", "-raw", log]);
|
| }
|
|
|
| /// Returns the content for [path], for instance the available build numbers
|
| /// for 'dart2js-linux-chromeff-1-4-be' using the path
|
| /// `chromium/bb/client.dart/dart2js-linux-chromeff-1-4-be`.
|
| -String ls(String path) {
|
| +Future<String> ls(String path) async {
|
| return logdog(["ls", path]);
|
| }
|
|
|
|
|