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

Side by Side Diff: pkg/polymer/lib/src/build/runner.dart

Issue 157583007: Removing polymer-specific code from barback runner (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months 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
« no previous file with comments | « pkg/polymer/lib/src/build/common.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /** 5 /**
6 * Definitions used to run the polymer linter and deploy tools without using 6 * Definitions used to run the polymer linter and deploy tools without using
7 * pub serve or pub deploy. 7 * pub serve or pub deploy.
8 */ 8 */
9 library polymer.src.build.runner; 9 library polymer.src.build.runner;
10 10
11 import 'dart:async'; 11 import 'dart:async';
12 import 'dart:convert'; 12 import 'dart:convert';
13 import 'dart:io'; 13 import 'dart:io';
14 14
15 import 'package:barback/barback.dart'; 15 import 'package:barback/barback.dart';
16 import 'package:path/path.dart' as path; 16 import 'package:path/path.dart' as path;
17 import 'package:stack_trace/stack_trace.dart'; 17 import 'package:stack_trace/stack_trace.dart';
18 import 'package:yaml/yaml.dart'; 18 import 'package:yaml/yaml.dart';
19 19
20 20
21 /** Collects different parameters needed to configure and run barback. */ 21 /** Collects different parameters needed to configure and run barback. */
22 class BarbackOptions { 22 class BarbackOptions {
23 /** Phases of transformers to run. */ 23 /**
24 * Phases of transformers to run for the current package.
25 * Use packagePhases to specify phases for other packages.
26 */
24 final List<List<Transformer>> phases; 27 final List<List<Transformer>> phases;
25 28
26 /** Package to treat as the current package in barback. */ 29 /** Package to treat as the current package in barback. */
27 final String currentPackage; 30 final String currentPackage;
28 31
32 /** Directory root for the current package. */
33 final String packageHome;
34
29 /** 35 /**
30 * Mapping between package names and the path in the file system where 36 * Mapping between package names and the path in the file system where
31 * to find the sources of such package. 37 * to find the sources of such package.
32 */ 38 */
33 final Map<String, String> packageDirs; 39 final Map<String, String> packageDirs;
34 40
35 /** Whether to run transformers on the test folder. */ 41 /** Whether to run transformers on the test folder. */
36 final bool transformTests; 42 final bool transformTests;
37 43
38 /** Whether to apply transformers on polymer dependencies. */
39 final bool transformPolymerDependencies;
40
41 /** Directory where to generate code, if any. */ 44 /** Directory where to generate code, if any. */
42 final String outDir; 45 final String outDir;
43 46
44 /** 47 /**
45 * Whether to print error messages using a json-format that tools, such as the 48 * Whether to print error messages using a json-format that tools, such as the
46 * Dart Editor, can process. 49 * Dart Editor, can process.
47 */ 50 */
48 final bool machineFormat; 51 final bool machineFormat;
49 52
50 /** 53 /**
51 * Whether to follow symlinks when listing directories. By default this is 54 * Whether to follow symlinks when listing directories. By default this is
52 * false because directories have symlinks for the packages directory created 55 * false because directories have symlinks for the packages directory created
53 * by pub, but it can be turned on for custom uses of this library. 56 * by pub, but it can be turned on for custom uses of this library.
54 */ 57 */
55 final bool followLinks; 58 final bool followLinks;
56 59
57 BarbackOptions(this.phases, this.outDir, {currentPackage, packageDirs, 60 /**
58 this.transformTests: false, this.transformPolymerDependencies: false, 61 * Phases of transformers to apply to packages other than the current
59 this.machineFormat: false, this.followLinks: false}) 62 * package, keyed by the package name.
63 */
64 final Map<String, List<List<Transformer>>> packagePhases;
65
66 BarbackOptions(this.phases, this.outDir, {currentPackage, String packageHome,
67 packageDirs, this.transformTests: false, this.machineFormat: false,
68 this.followLinks: false,
69 this.packagePhases: const {}})
60 : currentPackage = (currentPackage != null 70 : currentPackage = (currentPackage != null
61 ? currentPackage : readCurrentPackageFromPubspec()), 71 ? currentPackage : readCurrentPackageFromPubspec()),
72 packageHome = packageHome,
62 packageDirs = (packageDirs != null 73 packageDirs = (packageDirs != null
63 ? packageDirs : _readPackageDirsFromPub(currentPackage)); 74 ? packageDirs : readPackageDirsFromPub(packageHome, currentPackage));
64 75
65 } 76 }
66 77
67 /** 78 /**
68 * Creates a barback system as specified by [options] and runs it. Returns a 79 * Creates a barback system as specified by [options] and runs it. Returns a
69 * future that contains the list of assets generated after barback runs to 80 * future that contains the list of assets generated after barback runs to
70 * completion. 81 * completion.
71 */ 82 */
72 Future<AssetSet> runBarback(BarbackOptions options) { 83 Future<AssetSet> runBarback(BarbackOptions options) {
73 var barback = new Barback(new _PolymerPackageProvider(options.packageDirs)); 84 var barback = new Barback(new _PackageProvider(options.packageDirs));
74 _initBarback(barback, options); 85 _initBarback(barback, options);
75 _attachListeners(barback, options); 86 _attachListeners(barback, options);
76 if (options.outDir == null) return barback.getAllAssets(); 87 if (options.outDir == null) return barback.getAllAssets();
77 return _emitAllFiles(barback, options); 88 return _emitAllFiles(barback, options);
78 } 89 }
79 90
80 /** Extract the current package from the pubspec.yaml file. */ 91 /** Extract the current package from the pubspec.yaml file. */
81 String readCurrentPackageFromPubspec([String dir]) { 92 String readCurrentPackageFromPubspec([String dir]) {
82 var pubspec = new File( 93 var pubspec = new File(
83 dir == null ? 'pubspec.yaml' : path.join(dir, 'pubspec.yaml')); 94 dir == null ? 'pubspec.yaml' : path.join(dir, 'pubspec.yaml'));
84 if (!pubspec.existsSync()) { 95 if (!pubspec.existsSync()) {
85 print('error: pubspec.yaml file not found, please run this script from ' 96 print('error: pubspec.yaml file not found, please run this script from '
86 'your package root directory.'); 97 'your package root directory.');
87 return null; 98 return null;
88 } 99 }
89 return loadYaml(pubspec.readAsStringSync())['name']; 100 return loadYaml(pubspec.readAsStringSync())['name'];
90 } 101 }
91 102
92 /** 103 /**
93 * Extract a mapping between package names and the path in the file system where 104 * Extract a mapping between package names and the path in the file system where
94 * to find the sources of such package. This map will contain an entry for the 105 * to find the sources of such package. This map will contain an entry for the
95 * current package and everything it depends on (extracted via `pub 106 * current package and everything it depends on (extracted via `pub
96 * list-package-dirs`). 107 * list-package-dirs`).
97 */ 108 */
98 Map<String, String> _readPackageDirsFromPub(String currentPackage) { 109 Map<String, String> readPackageDirsFromPub(
110 [String packageHome, String currentPackage]) {
111 var cachedDir = Directory.current;
112 if (packageHome != null) {
113 Directory.current = new Directory(packageHome);
114 } else {
115 packageHome = cachedDir.path;
116 }
117
99 var dartExec = Platform.executable; 118 var dartExec = Platform.executable;
100 // If dartExec == dart, then dart and pub are in standard PATH. 119 // If dartExec == dart, then dart and pub are in standard PATH.
101 var sdkDir = dartExec == 'dart' ? '' : path.dirname(dartExec); 120 var sdkDir = dartExec == 'dart' ? '' : path.dirname(dartExec);
102 var pub = path.join(sdkDir, Platform.isWindows ? 'pub.bat' : 'pub'); 121 var pub = path.join(sdkDir, Platform.isWindows ? 'pub.bat' : 'pub');
103 var result = Process.runSync(pub, ['list-package-dirs']); 122 var result = Process.runSync(pub, ['list-package-dirs']);
104 if (result.exitCode != 0) { 123 if (result.exitCode != 0) {
105 print("unexpected error invoking 'pub':"); 124 print("unexpected error invoking 'pub':");
106 print(result.stdout); 125 print(result.stdout);
107 print(result.stderr); 126 print(result.stderr);
108 exit(result.exitCode); 127 exit(result.exitCode);
109 } 128 }
110 var map = JSON.decode(result.stdout)["packages"]; 129 var map = JSON.decode(result.stdout)["packages"];
111 map.forEach((k, v) { map[k] = path.dirname(v); }); 130 map.forEach((k, v) { map[k] = path.absolute(packageHome, path.dirname(v)); });
112 map[currentPackage] = '.'; 131
132 if (currentPackage == null) {
133 currentPackage = readCurrentPackageFromPubspec(packageHome);
134 }
135 map[currentPackage] = packageHome;
136
137 Directory.current = cachedDir;
113 return map; 138 return map;
114 } 139 }
115 140
116 /** Internal packages used by polymer. */
117 // TODO(sigmund): consider computing this list by recursively parsing
118 // pubspec.yaml files in the `Options.packageDirs`.
119 final Set<String> _polymerPackageDependencies = [
120 'analyzer', 'args', 'barback', 'browser', 'html5lib',
121 'js', 'logging', 'mutation_observer', 'observe', 'path'
122 'polymer_expressions', 'serialization', 'source_maps',
123 'stack_trace', 'template_binding', 'unittest', 'web_components',
124 'yaml'].toSet();
125
126 /** Return the relative path of each file under [subDir] in [package]. */ 141 /** Return the relative path of each file under [subDir] in [package]. */
127 Iterable<String> _listPackageDir(String package, String subDir, 142 Iterable<String> _listPackageDir(String package, String subDir,
128 BarbackOptions options) { 143 BarbackOptions options) {
129 var packageDir = options.packageDirs[package]; 144 var packageDir = options.packageDirs[package];
130 if (packageDir == null) return const []; 145 if (packageDir == null) return const [];
131 var dir = new Directory(path.join(packageDir, subDir)); 146 var dir = new Directory(path.join(packageDir, subDir));
132 if (!dir.existsSync()) return const []; 147 if (!dir.existsSync()) return const [];
133 return dir.listSync(recursive: true, followLinks: options.followLinks) 148 return dir.listSync(recursive: true, followLinks: options.followLinks)
134 .where((f) => f is File) 149 .where((f) => f is File)
135 .map((f) => path.relative(f.path, from: packageDir)); 150 .map((f) => path.relative(f.path, from: packageDir));
136 } 151 }
137 152
138 /** A simple provider that reads files directly from the pub cache. */ 153 /** A simple provider that reads files directly from the pub cache. */
139 class _PolymerPackageProvider implements PackageProvider { 154 class _PackageProvider implements PackageProvider {
140 Map<String, String> packageDirs; 155 Map<String, String> packageDirs;
141 Iterable<String> get packages => packageDirs.keys; 156 Iterable<String> get packages => packageDirs.keys;
142 157
143 _PolymerPackageProvider(this.packageDirs); 158 _PackageProvider(this.packageDirs);
144 159
145 Future<Asset> getAsset(AssetId id) => new Future.value( 160 Future<Asset> getAsset(AssetId id) => new Future.value(
146 new Asset.fromPath(id, path.join(packageDirs[id.package], 161 new Asset.fromPath(id, path.join(packageDirs[id.package],
147 _toSystemPath(id.path)))); 162 _toSystemPath(id.path))));
148 } 163 }
149 164
150 /** Convert asset paths to system paths (Assets always use the posix style). */ 165 /** Convert asset paths to system paths (Assets always use the posix style). */
151 String _toSystemPath(String assetPath) { 166 String _toSystemPath(String assetPath) {
152 if (path.Style.platform != path.Style.windows) return assetPath; 167 if (path.Style.platform != path.Style.windows) return assetPath;
153 return path.joinAll(path.posix.split(assetPath)); 168 return path.joinAll(path.posix.split(assetPath));
154 } 169 }
155 170
156 /** Tell barback which transformers to use and which assets to process. */ 171 /** Tell barback which transformers to use and which assets to process. */
157 void _initBarback(Barback barback, BarbackOptions options) { 172 void _initBarback(Barback barback, BarbackOptions options) {
158 var assets = []; 173 var assets = [];
159 void addAssets(String package, String subDir) { 174 void addAssets(String package, String subDir) {
160 for (var filepath in _listPackageDir(package, subDir, options)) { 175 for (var filepath in _listPackageDir(package, subDir, options)) {
161 assets.add(new AssetId(package, filepath)); 176 assets.add(new AssetId(package, filepath));
162 } 177 }
163 } 178 }
164 179
165 for (var package in options.packageDirs.keys) { 180 for (var package in options.packageDirs.keys) {
166 // There is nothing to do in the polymer package dependencies.
167 // However: in Polymer package *itself*, we need to replace Observable
168 // with ChangeNotifier.
169 if (!options.transformPolymerDependencies &&
170 _polymerPackageDependencies.contains(package)) continue;
171 barback.updateTransformers(package, options.phases);
172
173 // Notify barback to process anything under 'lib' and 'asset'. 181 // Notify barback to process anything under 'lib' and 'asset'.
174 addAssets(package, 'lib'); 182 addAssets(package, 'lib');
175 addAssets(package, 'asset'); 183 addAssets(package, 'asset');
184
185 if (options.packagePhases.containsKey(package)) {
186 barback.updateTransformers(package, options.packagePhases[package]);
187 }
176 } 188 }
189 barback.updateTransformers(options.currentPackage, options.phases);
blois 2014/02/24 16:02:27 If Polymer is the currentPackage when building in
Jennifer Messerly 2014/02/24 20:02:41 aha! good catch :)
177 190
178 // In case of the current package, include also 'web'. 191 // In case of the current package, include also 'web'.
179 addAssets(options.currentPackage, 'web'); 192 addAssets(options.currentPackage, 'web');
180 if (options.transformTests) addAssets(options.currentPackage, 'test'); 193 if (options.transformTests) addAssets(options.currentPackage, 'test');
181 194
195 // Add the sources after the transformers so all transformers are present
196 // when barback starts processing the assets.
182 barback.updateSources(assets); 197 barback.updateSources(assets);
183 } 198 }
184 199
185 /** Attach error listeners on [barback] so we can report errors. */ 200 /** Attach error listeners on [barback] so we can report errors. */
186 void _attachListeners(Barback barback, BarbackOptions options) { 201 void _attachListeners(Barback barback, BarbackOptions options) {
187 // Listen for errors and results 202 // Listen for errors and results
188 barback.errors.listen((e) { 203 barback.errors.listen((e) {
189 var trace = null; 204 var trace = null;
190 if (e is Error) trace = e.stackTrace; 205 if (e is Error) trace = e.stackTrace;
191 if (trace != null) { 206 if (trace != null) {
(...skipping 14 matching lines...) Expand all
206 if (options.machineFormat) { 221 if (options.machineFormat) {
207 print(_jsonFormatter(entry)); 222 print(_jsonFormatter(entry));
208 } else { 223 } else {
209 print(_consoleFormatter(entry)); 224 print(_consoleFormatter(entry));
210 } 225 }
211 }); 226 });
212 } 227 }
213 228
214 /** 229 /**
215 * Emits all outputs of [barback] and copies files that we didn't process (like 230 * Emits all outputs of [barback] and copies files that we didn't process (like
216 * polymer's libraries). 231 * dependent package's libraries).
217 */ 232 */
218 Future _emitAllFiles(Barback barback, BarbackOptions options) { 233 Future _emitAllFiles(Barback barback, BarbackOptions options) {
219 return barback.getAllAssets().then((assets) { 234 return barback.getAllAssets().then((assets) {
220 // Delete existing output folder before we generate anything 235 // Delete existing output folder before we generate anything
221 var dir = new Directory(options.outDir); 236 var dir = new Directory(options.outDir);
222 if (dir.existsSync()) dir.deleteSync(recursive: true); 237 if (dir.existsSync()) dir.deleteSync(recursive: true);
223 return _emitPackagesDir(options) 238 return _emitPackagesDir(options)
224 .then((_) => _emitTransformedFiles(assets, options)) 239 .then((_) => _emitTransformedFiles(assets, options))
225 .then((_) => _addPackagesSymlinks(assets, options)) 240 .then((_) => _addPackagesSymlinks(assets, options))
226 .then((_) => assets); 241 .then((_) => assets);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 } 297 }
283 } 298 }
284 } 299 }
285 } 300 }
286 301
287 /** 302 /**
288 * Emits a 'packages' directory directly under `out/packages` with the contents 303 * Emits a 'packages' directory directly under `out/packages` with the contents
289 * of every file that was not transformed by barback. 304 * of every file that was not transformed by barback.
290 */ 305 */
291 Future _emitPackagesDir(BarbackOptions options) { 306 Future _emitPackagesDir(BarbackOptions options) {
292 if (options.transformPolymerDependencies) return new Future.value(null);
293 var outPackages = path.join(options.outDir, 'packages'); 307 var outPackages = path.join(options.outDir, 'packages');
294 _ensureDir(outPackages); 308 _ensureDir(outPackages);
295 309
296 // Copy all the files we didn't process 310 // Copy all the files we didn't process
297 var dirs = options.packageDirs; 311 var dirs = options.packageDirs;
298 312
299 return Future.forEach(_polymerPackageDependencies, (package) { 313 return Future.forEach(dirs.keys, (package) {
300 return Future.forEach(_listPackageDir(package, 'lib', options), (relpath) { 314 return Future.forEach(_listPackageDir(package, 'lib', options), (relpath) {
301 var inpath = path.join(dirs[package], relpath); 315 var inpath = path.join(dirs[package], relpath);
302 var outpath = path.join(outPackages, package, relpath.substring(4)); 316 var outpath = path.join(outPackages, package, relpath.substring(4));
303 return _copyFile(inpath, outpath); 317 return _copyFile(inpath, outpath);
304 }); 318 });
305 }); 319 });
306 } 320 }
307 321
308 /** Ensure [dirpath] exists. */ 322 /** Ensure [dirpath] exists. */
309 void _ensureDir(String dirpath) { 323 void _ensureDir(String dirpath) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 output.write(entry.span.getLocationMessage(entry.message, 389 output.write(entry.span.getLocationMessage(entry.message,
376 useColors: useColors, 390 useColors: useColors,
377 color: levelColor)); 391 color: levelColor));
378 } 392 }
379 return output.toString(); 393 return output.toString();
380 } 394 }
381 395
382 const String _RED_COLOR = '\u001b[31m'; 396 const String _RED_COLOR = '\u001b[31m';
383 const String _MAGENTA_COLOR = '\u001b[35m'; 397 const String _MAGENTA_COLOR = '\u001b[35m';
384 const String _NO_COLOR = '\u001b[0m'; 398 const String _NO_COLOR = '\u001b[0m';
OLDNEW
« no previous file with comments | « pkg/polymer/lib/src/build/common.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698