Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: sdk/lib/_internal/pub_generated/bin/async_compile.dart

Issue 747273003: Add a test for pub's async_await compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix a bug and rebuild. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:io'; 5 import 'dart:io';
6 6
7 import 'package:args/args.dart'; 7 import 'package:args/args.dart';
8 import 'package:analyzer/src/services/formatter_impl.dart'; 8 import 'package:analyzer/src/services/formatter_impl.dart';
9 import 'package:async_await/async_await.dart' as async_await; 9 import 'package:async_await/async_await.dart' as async_await;
10 import 'package:stack_trace/stack_trace.dart';
10 import 'package:path/path.dart' as p; 11 import 'package:path/path.dart' as p;
11 12
12 /// The path to pub's root directory (sdk/lib/_internal/pub) in the Dart repo. 13 /// The path to pub's root directory (sdk/lib/_internal/pub) in the Dart repo.
13 /// 14 ///
14 /// This assumes this script is itself being run from within the repo. 15 /// This assumes this script is itself being run from within the repo.
15 final sourceDir = p.dirname(p.dirname(p.fromUri(Platform.script))); 16 final sourceDir = p.dirname(p.dirname(p.fromUri(Platform.script)));
16 17
17 /// The [sourceDir] as a URL, for use in import strings. 18 /// The [sourceDir] as a URL, for use in import strings.
18 final sourceUrl = p.toUri(sourceDir).toString(); 19 final sourceUrl = p.toUri(sourceDir).toString();
19 20
20 /// The directory that compiler output should be written to. 21 /// The directory that compiler output should be written to.
21 final generatedDir = p.join(p.dirname(sourceDir), 'pub_generated'); 22 String generatedDir;
22 23
23 /// `true` if any file failed to compile. 24 /// `true` if any file failed to compile.
24 bool hadFailure = false; 25 bool hadFailure = false;
25 26
26 bool verbose = false; 27 bool verbose = false;
27 28
28 /// Prefix for imports in pub that import dart2js libraries. 29 /// Prefix for imports in pub that import dart2js libraries.
29 final _compilerPattern = new RegExp(r"import '(\.\./)+compiler"); 30 final _compilerPattern = new RegExp(r"import '(\.\./)+compiler");
30 31
31 /// Matches the Git commit hash of the compiler stored in the README.md file. 32 /// Matches the Git commit hash of the compiler stored in the README.md file.
32 /// 33 ///
33 /// This is used both to find the current commit and replace it with the new 34 /// This is used both to find the current commit and replace it with the new
34 /// one. 35 /// one.
35 final _commitPattern = new RegExp(r"[a-f0-9]{40}"); 36 final _commitPattern = new RegExp(r"[a-f0-9]{40}");
36 37
38 /// The template for the README that's added to the generated source.
39 ///
40 /// This is used to store the current commit of the async_await compiler.
41 const _README = """
42 Pub is currently dogfooding the new Dart async/await syntax. Since the Dart VM
43 doesn't natively support it yet, we are using the [async-await][] compiler
44 package.
45
46 [async-await]: https://github.com/dart-lang/async_await
47
48 We run that to compile pub-using-await from sdk/lib/_internal/pub down to
49 vanilla Dart code which is what you see here. To interoperate more easily with
50 the rest of the repositry, we check in that generated code.
51
52 When bug #104 is fixed, we can remove this entirely.
53
54 The code here was compiled using the async-await compiler at commit:
55
56 <<COMMIT>>
57
58 (Note: this file is also parsed by a tool to update the above commit, so be
59 careful not to reformat it.)
60 """;
61
37 /// This runs the async/await compiler on all of the pub source code. 62 /// This runs the async/await compiler on all of the pub source code.
38 /// 63 ///
39 /// It reads from the repo and writes the compiled output into the given build 64 /// It reads from the repo and writes the compiled output into the given build
40 /// directory (using the same file names and relative layout). Does not 65 /// directory (using the same file names and relative layout). Does not
41 /// compile files that haven't changed since the last time they were compiled. 66 /// compile files that haven't changed since the last time they were compiled.
42 // TODO(rnystrom): Remove this when #104 is fixed. 67 // TODO(rnystrom): Remove this when #104 is fixed.
43 void main(List<String> arguments) { 68 void main(List<String> arguments) {
44 var parser = new ArgParser(allowTrailingOptions: true); 69 var parser = new ArgParser(allowTrailingOptions: true);
45 70
46 parser.addFlag("verbose", callback: (value) => verbose = value); 71 parser.addFlag("verbose", callback: (value) => verbose = value);
47 72
48 var force = false; 73 var force = false;
49 parser.addFlag("force", callback: (value) => force = value); 74 parser.addFlag("force", callback: (value) => force = value);
50 75
51 var buildDir; 76 var buildDir;
77 parser.addOption("snapshot-build-dir", callback: (value) => buildDir = value);
52 78
53 try { 79 try {
54 var rest = parser.parse(arguments).rest; 80 var rest = parser.parse(arguments).rest;
55 if (rest.isEmpty) { 81 if (rest.isEmpty) {
56 throw new FormatException('Missing build directory.'); 82 throw new FormatException('Missing generated directory.');
57 } else if (rest.length > 1) { 83 } else if (rest.length > 1) {
58 throw new FormatException( 84 throw new FormatException(
59 'Unexpected arguments: ${rest.skip(1).join(" ")}.'); 85 'Unexpected arguments: ${rest.skip(1).join(" ")}.');
60 } 86 }
61 87
62 buildDir = rest.first; 88 generatedDir = rest.first;
63 } on FormatException catch (ex) { 89 } on FormatException catch (ex) {
64 print(ex); 90 stderr.writeln(ex);
65 print(); 91 stderr.writeln();
66 print("Usage: dart async_compile.dart [--verbose] [--force] <build dir>"); 92 stderr.writeln(
93 "Usage: dart async_compile.dart [--verbose] [--force] "
94 "[--snapshot-build-dir <dir>] <generated dir>");
67 exit(64); 95 exit(64);
68 } 96 }
69 97
70 // See what version (i.e. Git commit) of the async-await compiler we 98 // See what version (i.e. Git commit) of the async-await compiler we
71 // currently have. If this is different from the version that was used to 99 // currently have. If this is different from the version that was used to
72 // compile the sources, recompile everything. 100 // compile the sources, recompile everything.
73 var currentCommit = _getCurrentCommit(); 101 var currentCommit = _getCurrentCommit();
74 102
75 var readmePath = p.join(generatedDir, "README.md"); 103 var readmePath = p.join(generatedDir, "README.md");
76 var lastCommit; 104 var lastCommit;
77 var readme = new File(readmePath).readAsStringSync(); 105 try {
78 var match = _commitPattern.firstMatch(readme); 106 var readme = new File(readmePath).readAsStringSync();
79 if (match == null) { 107 var match = _commitPattern.firstMatch(readme);
80 print("Could not find compiler commit hash in README.md."); 108 if (match == null) {
81 exit(1); 109 stderr.writeln("Could not find compiler commit hash in README.md.");
110 exit(1);
111 }
112
113 lastCommit = match[0];
114 } on IOException catch (error, stackTrace) {
115 if (verbose) {
116 stderr.writeln(
117 "Failed to load $readmePath: $error\n" "${new Trace.from(stackTrace)}" );
118 }
82 } 119 }
83 120
84 lastCommit = match[0];
85
86 var numFiles = 0; 121 var numFiles = 0;
87 var numCompiled = 0; 122 var numCompiled = 0;
88 123
89 // Compile any modified or missing files. 124 // Compile any modified or missing files.
90 var sources = new Set(); 125 var sources = new Set();
91 for (var entry in new Directory(sourceDir).listSync(recursive: true)) { 126 for (var entry in new Directory(sourceDir).listSync(recursive: true)) {
92 if (p.extension(entry.path) != ".dart") continue; 127 if (p.extension(entry.path) != ".dart") continue;
93 128
94 numFiles++; 129 numFiles++;
95 var relative = p.relative(entry.path, from: sourceDir); 130 var relative = p.relative(entry.path, from: sourceDir);
(...skipping 19 matching lines...) Expand all
115 var relative = p.relative(entry.path, from: generatedDir); 150 var relative = p.relative(entry.path, from: generatedDir);
116 151
117 if (!sources.contains(relative)) { 152 if (!sources.contains(relative)) {
118 _deleteFile(entry.path); 153 _deleteFile(entry.path);
119 if (verbose) print("Deleted $relative"); 154 if (verbose) print("Deleted $relative");
120 } 155 }
121 } 156 }
122 157
123 // Update the README. 158 // Update the README.
124 if (currentCommit != lastCommit) { 159 if (currentCommit != lastCommit) {
125 readme = readme.replaceAll(_commitPattern, currentCommit); 160 _writeFile(readmePath, _README.replaceAll("<<COMMIT>>", currentCommit));
126 _writeFile(readmePath, readme);
127 if (verbose) print("Updated README.md"); 161 if (verbose) print("Updated README.md");
128 } 162 }
129 163
130 if (numCompiled > 0) _generateSnapshot(buildDir); 164 if (numCompiled > 0 && buildDir != null) _generateSnapshot(buildDir);
131 165
132 if (verbose) print("Compiled $numCompiled out of $numFiles files"); 166 if (verbose) print("Compiled $numCompiled out of $numFiles files");
133 167
134 if (hadFailure) exit(1); 168 if (hadFailure) exit(1);
135 } 169 }
136 170
137 String _getCurrentCommit() { 171 String _getCurrentCommit() {
138 var command = "git"; 172 var command = "git";
139 var args = ["rev-parse", "HEAD"]; 173 var args = ["rev-parse", "HEAD"];
140 174
141 // Spawning a process on Windows will not look for the executable in the 175 // Spawning a process on Windows will not look for the executable in the
142 // system path so spawn git through a shell to find it. 176 // system path so spawn git through a shell to find it.
143 if (Platform.operatingSystem == "windows") { 177 if (Platform.operatingSystem == "windows") {
144 command = "cmd"; 178 command = "cmd";
145 args = ["/c", "git"]..addAll(args); 179 args = ["/c", "git"]..addAll(args);
146 } 180 }
147 181
148 var result = Process.runSync( 182 var result = Process.runSync(
149 command, 183 command,
150 args, 184 args,
151 workingDirectory: p.join(sourceDir, "../../../../third_party/pkg/async_awa it")); 185 workingDirectory: p.join(sourceDir, "../../../../third_party/pkg/async_awa it"));
152 if (result.exitCode != 0) { 186 if (result.exitCode != 0) {
153 print("Could not get Git revision of async_await compiler."); 187 stderr.writeln("Could not get Git revision of async_await compiler.");
154 exit(1); 188 exit(1);
155 } 189 }
156 190
157 return result.stdout.trim(); 191 return result.stdout.trim();
158 } 192 }
159 193
160 void _compile(String sourcePath, String source, String destPath) { 194 void _compile(String sourcePath, String source, String destPath) {
161 var destDir = new Directory(p.dirname(destPath)); 195 var destDir = new Directory(p.dirname(destPath));
162 destDir.createSync(recursive: true); 196 destDir.createSync(recursive: true);
163 197
(...skipping 21 matching lines...) Expand all
185 219
186 try { 220 try {
187 source = async_await.compile(source); 221 source = async_await.compile(source);
188 222
189 // Reformat the result since the compiler ditches all whitespace. 223 // Reformat the result since the compiler ditches all whitespace.
190 // TODO(rnystrom): Remove when this is fixed: 224 // TODO(rnystrom): Remove when this is fixed:
191 // https://github.com/dart-lang/async_await/issues/12 225 // https://github.com/dart-lang/async_await/issues/12
192 var result = new CodeFormatter().format(CodeKind.COMPILATION_UNIT, source); 226 var result = new CodeFormatter().format(CodeKind.COMPILATION_UNIT, source);
193 return result.source; 227 return result.source;
194 } catch (ex) { 228 } catch (ex) {
195 print("Async compile failed on $sourcePath:\n$ex"); 229 stderr.writeln("Async compile failed on $sourcePath:\n$ex");
196 hadFailure = true; 230 hadFailure = true;
197 return null; 231 return null;
198 } 232 }
199 } 233 }
200 234
201 /// Fix relative imports to dart2js libraries. 235 /// Fix relative imports to dart2js libraries.
202 /// 236 ///
203 /// Pub imports dart2js using relative imports that reach outside of pub's 237 /// Pub imports dart2js using relative imports that reach outside of pub's
204 /// source tree. Since the build directory is in a different location, we need 238 /// source tree. Since the build directory is in a different location, we need
205 /// to fix those to be valid relative imports from the build directory. 239 /// to fix those to be valid relative imports from the build directory.
206 String _fixDart2jsImports(String sourcePath, String source, String destPath) { 240 String _fixDart2jsImports(String sourcePath, String source, String destPath) {
207 var compilerDir = p.url.join(sourceUrl, "../compiler"); 241 var compilerDir = p.url.join(sourceUrl, "../compiler");
208 var relative = 242 var relative =
209 p.url.relative(compilerDir, from: p.url.dirname(p.toUri(destPath).toString ())); 243 p.url.relative(compilerDir, from: p.url.dirname(p.toUri(destPath).toString ()));
210 return source.replaceAll(_compilerPattern, "import '$relative"); 244 return source.replaceAll(_compilerPattern, "import '$relative");
211 } 245 }
212 246
213 /// Regenerate the pub snapshot from the async/await-compiled output. We do 247 /// Regenerate the pub snapshot from the async/await-compiled output. We do
214 /// this here since the tests need it and it's faster than doing a full SDK 248 /// this here since the tests need it and it's faster than doing a full SDK
215 /// build. 249 /// build.
216 void _generateSnapshot(String buildDir) { 250 void _generateSnapshot(String buildDir) {
217 buildDir = p.normalize(buildDir); 251 buildDir = p.normalize(buildDir);
252 new Directory(dir).createSync(recursive: true);
218 253
219 var entrypoint = p.join(generatedDir, 'bin/pub.dart'); 254 var entrypoint = p.join(generatedDir, 'bin/pub.dart');
220 var packageRoot = p.join(buildDir, 'packages'); 255 var packageRoot = p.join(buildDir, 'packages');
221 var snapshot = p.join(buildDir, 'dart-sdk/bin/snapshots/pub.dart.snapshot'); 256 var snapshot = p.join(buildDir, 'dart-sdk/bin/snapshots/pub.dart.snapshot');
222 257
223 var result = Process.runSync( 258 var result = Process.runSync(
224 Platform.executable, 259 Platform.executable,
225 ["--package-root=$packageRoot", "--snapshot=$snapshot", entrypoint]); 260 ["--package-root=$packageRoot", "--snapshot=$snapshot", entrypoint]);
226 261
227 if (result.exitCode != 0) { 262 if (result.exitCode != 0) {
228 print("Failed to generate snapshot:"); 263 stderr.writeln("Failed to generate snapshot:");
229 if (result.stderr.trim().isNotEmpty) print(result.stderr); 264 if (result.stderr.trim().isNotEmpty) stderr.writeln(result.stderr);
230 if (result.stdout.trim().isNotEmpty) print(result.stdout); 265 if (result.stdout.trim().isNotEmpty) stderr.writeln(result.stdout);
231 exit(result.exitCode); 266 exit(result.exitCode);
232 } 267 }
233 268
234 if (verbose) print("Created pub snapshot"); 269 if (verbose) print("Created pub snapshot");
235 } 270 }
236 271
237 /// Deletes the file at [path], ignoring any IO errors that occur. 272 /// Deletes the file at [path], ignoring any IO errors that occur.
238 /// 273 ///
239 /// This swallows errors to accommodate multiple compilers running concurrently. 274 /// This swallows errors to accommodate multiple compilers running concurrently.
240 /// Since they will produce the same output anyway, a failure of one is fine. 275 /// Since they will produce the same output anyway, a failure of one is fine.
241 void _deleteFile(String path) { 276 void _deleteFile(String path) {
242 try { 277 try {
243 new File(path).deleteSync(); 278 new File(path).deleteSync();
244 } on IOException catch (ex) { 279 } on IOException catch (ex) {
245 // Do nothing. 280 // Do nothing.
246 } 281 }
247 } 282 }
248 283
249 /// Writes [contents] to [path], ignoring any IO errors that occur. 284 /// Writes [contents] to [path], ignoring any IO errors that occur.
250 /// 285 ///
251 /// This swallows errors to accommodate multiple compilers running concurrently. 286 /// This swallows errors to accommodate multiple compilers running concurrently.
252 /// Since they will produce the same output anyway, a failure of one is fine. 287 /// Since they will produce the same output anyway, a failure of one is fine.
253 void _writeFile(String path, String contents) { 288 void _writeFile(String path, String contents) {
254 try { 289 try {
255 new File(path).writeAsStringSync(contents); 290 new File(path).writeAsStringSync(contents);
256 } on IOException catch (ex) { 291 } on IOException catch (ex) {
257 // Do nothing. 292 // Do nothing.
258 } 293 }
259 } 294 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/pub/test/async_compile_test.dart ('k') | sdk/lib/_internal/pub_generated/lib/src/io.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698