Chromium Code Reviews| Index: pkg/front_end/tool/bazel/worker.dart |
| diff --git a/pkg/front_end/tool/bazel/worker.dart b/pkg/front_end/tool/bazel/worker.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..93bd5e43d41d037fd291e6a5f36e626f2a5bd405 |
| --- /dev/null |
| +++ b/pkg/front_end/tool/bazel/worker.dart |
| @@ -0,0 +1,114 @@ |
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| +import 'dart:async'; |
| +import 'dart:io'; |
| + |
| +import 'package:args/args.dart'; |
| +import 'package:bazel_worker/bazel_worker.dart'; |
| +import 'package:front_end/front_end.dart' hide FileSystemException; |
| +import 'package:front_end/src/fasta/command_line_reporting.dart'; |
| +import 'package:kernel/target/targets.dart'; |
| + |
| +main(List<String> args) async { |
|
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
I'm still contemplating whether to put this here o
jakemac
2017/08/21 21:16:37
I don't feel that strongly, but analyzer/ddc both
|
| + args = preprocessArgs(args); |
| + |
| + if (args.contains('--persistent_worker')) { |
| + if (args.length != 1) { |
| + throw new StateError( |
| + "unexpected args, expected only --persistent-worker but got: $args"); |
| + } |
| + await new SummaryWorker().run(); |
| + } else { |
| + await computeSummary(args); |
| + } |
| +} |
| + |
| +/// A bazel worker loop that can compute summaries. |
| +class SummaryWorker extends AsyncWorkerLoop { |
| + Future<WorkResponse> performRequest(WorkRequest request) async { |
| + var outputBuffer = new StringBuffer(); |
| + var response = new WorkResponse()..exitCode = 0; |
| + try { |
| + await computeSummary(request.arguments, |
| + isWorker: true, outputBuffer: outputBuffer); |
| + } catch (_, s) { |
| + outputBuffer.writeln(s); |
| + response.exitCode = 15; |
| + } |
| + response.output = outputBuffer.toString(); |
| + return response; |
| + } |
| +} |
| + |
| +/// If the last arg starts with `@`, this reads the file it points to and treats |
| +/// each line as an additional arg. |
| +/// |
| +/// This is how individual work request args are differentiated from startup |
| +/// args in bazel (inidividual work request args go in that file). |
| +List<String> preprocessArgs(List<String> args) { |
| + args = new List.from(args); |
| + if (args.isEmpty) { |
| + return args; |
| + } |
| + String lastArg = args.last; |
| + if (lastArg.startsWith('@')) { |
| + File argsFile = new File(lastArg.substring(1)); |
| + try { |
| + args.removeLast(); |
| + args.addAll(argsFile.readAsLinesSync()); |
| + } on FileSystemException catch (e) { |
| + throw new Exception('Failed to read file specified by $lastArg : $e'); |
| + } |
| + } |
| + return args; |
| +} |
| + |
| +/// An [ArgParser] for generating kernel summaries. |
| +final summaryArgsParser = new ArgParser() |
| + ..addOption('dart-sdk-summary') |
| + ..addOption('input-summary', allowMultiple: true) |
| + ..addOption('multi-root', allowMultiple: true) |
| + ..addOption('packages-file') |
| + ..addOption('source', allowMultiple: true) |
| + ..addOption('output'); |
| + |
| +/// Computes a kernel summary based on [args]. |
| +/// |
| +/// If [isWorker] is true then exit codes will not be set on failure. |
| +/// |
| +/// If [outputBuffer] is provided then messages will be written to that buffer |
| +/// instead of printed to the console. |
| +Future computeSummary(List<String> args, |
| + {bool isWorker: false, StringBuffer outputBuffer}) async { |
| + var parsedArgs = summaryArgsParser.parse(args); |
| + var options = new CompilerOptions() |
| + ..packagesFileUri = Uri.parse(parsedArgs['packages-file']) |
| + ..inputSummaries = parsedArgs['input-summary'].map(Uri.parse).toList() |
| + ..sdkSummary = Uri.parse(parsedArgs['dart-sdk-summary']) |
| + ..multiRoots = parsedArgs['multi-root'].map(Uri.parse).toList() |
| + ..target = new NoneTarget(new TargetFlags()); |
| + |
| + if (isWorker) { |
| + options.setExitCodeOnProblem = false; |
|
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
this is already false by default :)
In your case
jakemac
2017/08/21 21:16:37
done
|
| + } |
| + |
| + if (outputBuffer != null) { |
| + options.onError = (CompilationMessage error) { |
| + var severityString = severityName(error.severity, capitalized: true); |
| + outputBuffer.writeln('$severityString: ${error.message}'); |
| + if (error.severity != Severity.nit) { |
| + throw error; |
|
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
`throw` might not be the most user-friendly respon
jakemac
2017/08/21 21:16:37
The bazel worker handles errors and sends a proper
|
| + } |
| + }; |
| + } else { |
| + options.throwOnWarnings = true; |
|
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
our default error reporting throws and prints to t
jakemac
2017/08/21 21:16:37
I think the default handling is fine
|
| + } |
| + |
| + var sources = parsedArgs['source'].map(Uri.parse).toList(); |
|
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
we intend to fix this, but we've had issues in the
jakemac
2017/08/21 21:16:37
These will be real uris with schemes yes
|
| + var program = await summaryFor(sources, options); |
| + |
| + var outputFile = new File(parsedArgs['output']); |
| + outputFile.createSync(recursive: true); |
| + outputFile.writeAsBytesSync(program); |
| +} |