OLD | NEW |
---|---|
1 #!/usr/bin/env dart | 1 #!/usr/bin/env dart |
2 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 /// Command line entry point for Dart Development Compiler (dartdevc). | 6 /// Command line entry point for Dart Development Compiler (dartdevc), used to |
7 /// | 7 /// compile a collection of dart libraries into a single JS module |
8 /// Supported commands are | |
9 /// * compile: builds a collection of dart libraries into a single JS module | |
10 /// | |
11 /// Additionally, these commands are being considered | |
12 /// * link: combines several JS modules into a single JS file | |
13 /// * build: compiles & links a set of code, automatically determining | |
14 /// appropriate groupings of libraries to combine into JS modules | |
15 /// * watch: watch a directory and recompile build units automatically | |
16 /// * serve: uses `watch` to recompile and exposes a simple static file server | |
17 /// for local development | |
18 /// | |
19 /// These commands are combined so we have less names to expose on the PATH, | |
20 /// and for development simplicity while the precise UI has not been determined. | |
21 /// | |
22 /// A more typical structure for web tools is simply to have the compiler with | |
23 /// "watch" as an option. The challenge for us is: | |
24 /// | |
25 /// * Dart used to assume whole-program compiles, so we don't have a | |
26 /// user-declared unit of building, and neither "libraries" or "packages" will | |
27 /// work, | |
28 /// * We do not assume a `node` JS installation, so we cannot easily reuse | |
29 /// existing tools for the "link" step, or assume users have a local | |
30 /// file server, | |
31 /// * We didn't have a file watcher API at first, | |
32 /// * We had no conventions about where compiled output should go (or even | |
33 /// that we would be compiling at all, vs running on an in-browser Dart VM), | |
34 /// * We wanted a good first impression with our simple examples, so we used | |
35 /// local file servers, and users have an expectation of it now, even though | |
36 /// it doesn't scale to typical apps that need their own real servers. | |
37 | 8 |
38 import 'dart:async'; | 9 import 'dart:async'; |
10 import 'dart:convert'; | |
39 import 'dart:io'; | 11 import 'dart:io'; |
12 import 'dart:isolate'; | |
40 import 'package:analyzer/file_system/physical_file_system.dart'; | 13 import 'package:analyzer/file_system/physical_file_system.dart'; |
41 import 'package:analyzer/src/command_line/arguments.dart'; | 14 import 'package:analyzer/src/command_line/arguments.dart'; |
42 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; | 15 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; |
43 import 'package:bazel_worker/bazel_worker.dart'; | 16 import 'package:bazel_worker/bazel_worker.dart'; |
44 import 'package:dev_compiler/src/compiler/command.dart'; | 17 import 'package:dev_compiler/src/compiler/command.dart'; |
45 | 18 |
46 Future main(List<String> args) async { | 19 Future main(List<String> args) async { |
47 // Always returns a new modifiable list. | 20 // Always returns a new modifiable list. |
48 args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args); | 21 args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args); |
49 | 22 |
50 if (args.contains('--persistent_worker')) { | 23 if (args.contains('--persistent_worker')) { |
51 new _CompilerWorker(args..remove('--persistent_worker')).run(); | 24 await new _CompilerWorker(args..remove('--persistent_worker')).run(); |
25 } else if (args.isNotEmpty && args.last == "--batch") { | |
26 await runBatch(args.sublist(0, args.length - 1)); | |
52 } else { | 27 } else { |
53 exitCode = compile(args); | 28 exitCode = compile(args); |
54 } | 29 } |
55 } | 30 } |
56 | 31 |
57 /// Runs the compiler worker loop. | 32 /// Runs the compiler worker loop. |
58 class _CompilerWorker extends AsyncWorkerLoop { | 33 class _CompilerWorker extends AsyncWorkerLoop { |
59 /// The original args supplied to the executable. | 34 /// The original args supplied to the executable. |
60 final List<String> _startupArgs; | 35 final List<String> _startupArgs; |
61 | 36 |
62 _CompilerWorker(this._startupArgs) : super(); | 37 _CompilerWorker(this._startupArgs) : super(); |
63 | 38 |
64 /// Performs each individual work request. | 39 /// Performs each individual work request. |
65 Future<WorkResponse> performRequest(WorkRequest request) async { | 40 Future<WorkResponse> performRequest(WorkRequest request) async { |
66 var args = _startupArgs.toList()..addAll(request.arguments); | 41 var args = _startupArgs.toList()..addAll(request.arguments); |
67 | 42 |
68 var output = new StringBuffer(); | 43 var output = new StringBuffer(); |
69 var exitCode = compile(args, printFn: output.writeln); | 44 var exitCode = compile(args, printFn: output.writeln); |
70 AnalysisEngine.instance.clearCaches(); | 45 AnalysisEngine.instance.clearCaches(); |
71 return new WorkResponse() | 46 return new WorkResponse() |
72 ..exitCode = exitCode | 47 ..exitCode = exitCode |
73 ..output = output.toString(); | 48 ..output = output.toString(); |
74 } | 49 } |
75 } | 50 } |
51 | |
52 Future runBatch(List<String> batchArgs) async { | |
53 int totalTests = 0; | |
54 int testsFailed = 0; | |
55 var watch = new Stopwatch()..start(); | |
56 print('>>> BATCH START'); | |
57 Stream input = stdin.transform(UTF8.decoder).transform(new LineSplitter()); | |
Bob Nystrom
2017/08/03 18:28:04
Can this stream be typed more precisely, or inferr
Jennifer Messerly
2017/08/03 19:43:05
I just copy+pasted this from the other impls of ba
Bob Nystrom
2017/08/03 20:19:48
It was added much later in dart:io's evolution tha
| |
58 await for (String line in input) { | |
59 if (line.isEmpty) { | |
60 int time = watch.elapsedMilliseconds; | |
61 print('>>> BATCH END ' | |
62 '(${totalTests - testsFailed})/$totalTests ${time}ms'); | |
63 break; | |
64 } | |
65 ++totalTests; | |
Bob Nystrom
2017/08/03 18:28:04
Random nit: Maybe it's just me, but I tend to thin
Jennifer Messerly
2017/08/03 19:43:06
again this is just copied code. I don't mind chang
| |
66 var args = batchArgs.toList()..addAll(line.split(new RegExp(r'\s+'))); | |
67 | |
68 // We don't try/catch here, since `compile` should handle that. | |
69 var compileExitCode = compile(args); | |
70 AnalysisEngine.instance.clearCaches(); | |
71 stderr.writeln('>>> EOF STDERR'); | |
72 var outcome = compileExitCode == 0 | |
73 ? 'PASS' | |
74 : compileExitCode == 70 ? 'CRASH' : 'FAIL'; | |
75 print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms'); | |
76 } | |
77 } | |
OLD | NEW |