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

Side by Side Diff: pkg/polymer/lib/src/barback_helper.dart

Issue 23898009: Switch polymer's build.dart to use the new linter. This CL does the following (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * Definitions used to run the polymer linter and deploy tools without using
7 * pub serve or pub deploy.
8 */
9 library polymer.src.barback_helper;
Jennifer Messerly 2013/09/10 04:16:51 i'm not a huge fan of _helper, could we just call
Siggi Cherem (dart-lang) 2013/09/11 01:45:26 Not sure if that's too confusing. Other ideas: - u
10
11 import 'dart:async';
12 import 'dart:convert';
13 import 'dart:io';
14
15 import 'package:barback/barback.dart';
16 import 'package:path/path.dart' as path;
17 import 'package:stack_trace/stack_trace.dart';
18 import 'package:yaml/yaml.dart';
19 import 'package:args/args.dart';
Jennifer Messerly 2013/09/10 04:16:51 sort if you want :)
Siggi Cherem (dart-lang) 2013/09/11 01:45:26 doh. we need an autoformatter...
20
21
22 /** Collects different parameters needed to configure and run barback. */
Siggi Cherem (dart-lang) 2013/09/10 03:40:57 this configuration and runBarback are new.
23 class BarbackOptions {
24 /** Phases of transformers to run. */
25 final List<List<Transformer>> phases;
26
27 /** Package to treat as the current package in barback. */
28 final String currentPackage;
29
30 /**
31 * Mapping between package names and the path in the file system where
32 * to find the sources of such package.
33 */
34 final Map<String, String> packageDirs;
35
36 /** Whether to run transformers on the test folder. */
37 final bool transformTests;
38
39 /** Whether to apply transformers on polymer dependencies. */
40 final bool transformPolymerDependencies;
41
42 /** Directory where to generate code, if any. */
43 final String outDir;
44
45 BarbackOptions(this.phases, this.outDir, {currentPackage, packageDirs,
46 this.transformTests: false, this.transformPolymerDependencies: false})
47 : currentPackage = (currentPackage != null
48 ? currentPackage : readCurrentPackageFromPubspec()),
49 packageDirs = (packageDirs != null
50 ? packageDirs : _readPackageDirsFromPub(currentPackage));
51
52 }
53
54 /**
55 * Creates a barback system as specified by [options] and runs it. Returns a
56 * future that contains the list of assets generated after barback runs to
57 * completion.
58 */
59 Future<AssetSet> runBarback(BarbackOptions options) {
60 var barback = new Barback(new _PolymerPackageProvider(options.packageDirs));
61 _initBarback(barback, options);
62 _attachListeners(barback);
63 if (options.outDir == null) return barback.getAllAssets();
64 return _emitAllFiles(barback, options);
65 }
66
67 /** Extract the current package from the pubspec.yaml file. */
68 String readCurrentPackageFromPubspec() {
Siggi Cherem (dart-lang) 2013/09/10 03:40:57 the logic here and below is the same as before, wi
69 var pubspec = new File('pubspec.yaml');
70 if (!pubspec.existsSync()) {
71 print('error: pubspec.yaml file not found, please run this script from '
72 'your package root directory.');
73 return null;
74 }
75 return loadYaml(pubspec.readAsStringSync())['name'];
76 }
77
78 /**
79 * Extract a mapping between package names and the path in the file system where
80 * to find the sources of such package. This map will contain an entry for the
81 * current package and everything it depends on (extracted via `pub
82 * list-pacakge-dirs`).
83 */
84 Map<String, String> _readPackageDirsFromPub(String currentPackage) {
85 var dartExec = new Options().executable;
86 // If dartExec == dart, then dart and pub are in standard PATH.
87 var sdkDir = dartExec == 'dart' ? '' : path.dirname(dartExec);
88 var pub = path.join(sdkDir, Platform.isWindows ? 'pub.bat' : 'pub');
89 var result = Process.runSync(pub, ['list-package-dirs']);
90 if (result.exitCode != 0) {
91 print("unexpected error invoking 'pub':");
92 print(result.stdout);
93 print(result.stderr);
94 exit(result.exitCode);
95 }
96 var map = JSON.decode(result.stdout)["packages"];
97 map.forEach((k, v) { map[k] = path.dirname(v); });
98 map[currentPackage] = '.';
99 return map;
100 }
101
102 /** Internal packages used by polymer. */
103 // TODO(sigmund): consider computing this list by recursively parsing
104 // pubspec.yaml files in the `Options.packageDirs`.
105 final Set<String> _polymerPackageDependencies = (const [
Jennifer Messerly 2013/09/10 04:16:51 fyi -- I don't think you need the parens. also si
Siggi Cherem (dart-lang) 2013/09/11 01:45:26 good point. Done.
106 'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
107 'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
108 'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path', 'polymer',
109 'polymer_expressions', 'serialization', 'shadow_dom', 'source_maps',
110 'stack_trace', 'unittest', 'unmodifiable_collection', 'yaml']).toSet();
111
112 /** Return the relative path of each file under [subDir] in [package]. */
113 Iterable<String> _listPackageDir(String package, String subDir,
114 BarbackOptions options) {
115 var packageDir = options.packageDirs[package];
116 if (packageDir == null) return const [];
117 var dir = new Directory(path.join(packageDir, subDir));
118 if (!dir.existsSync()) return const [];
119 return dir.listSync(recursive: true, followLinks: false)
120 .where((f) => f is File)
121 .map((f) => path.relative(f.path, from: packageDir));
122 }
123
124 /** A simple provider that reads files directly from the pub cache. */
125 class _PolymerPackageProvider implements PackageProvider {
126 Map<String, String> packageDirs;
127 Iterable<String> get packages => packageDirs.keys;
128
129 _PolymerPackageProvider(this.packageDirs);
130
131 Future<Asset> getAsset(AssetId id) => new Future.value(
132 new Asset.fromPath(id, path.join(packageDirs[id.package],
133 // Assets always use the posix style paths
134 path.joinAll(path.posix.split(id.path)))));
135 }
136
137 /** Tell barback which transformers to use and which assets to process. */
138 void _initBarback(Barback barback, BarbackOptions options) {
139 var assets = [];
140 void addAssets(String package, String subDir) {
141 for (var filepath in _listPackageDir(package, subDir, options)) {
142 assets.add(new AssetId(package, filepath));
143 }
144 }
145
146 for (var package in options.packageDirs.keys) {
147 // There is nothing to do in the 'polymer' package and its dependencies.
148 if (!options.transformPolymerDependencies &&
149 _polymerPackageDependencies.contains(package)) continue;
150 barback.updateTransformers(package, options.phases);
151
152 // Notify barback to process anything under 'lib' and 'asset'.
153 addAssets(package, 'lib');
154 addAssets(package, 'asset');
155 }
156
157 // In case of the current package, include also 'web'.
158 addAssets(options.currentPackage, 'web');
159 if (options.transformTests) addAssets(options.currentPackage, 'test');
160
161 barback.updateSources(assets);
162 }
163
164 /** Attach error listeners on [barback] so we can report errors. */
165 void _attachListeners(Barback barback) {
166 // Listen for errors and results
167 barback.errors.listen((e) {
168 var trace = getAttachedStackTrace(e);
169 if (trace != null) {
170 print(Trace.format(trace));
171 }
172 print('error running barback: $e');
173 exit(1);
174 });
175
176 barback.results.listen((result) {
177 if (!result.succeeded) {
178 print("build failed with errors: ${result.errors}");
179 exit(1);
180 }
181 });
182 }
183
184 /**
185 * Emits all outputs of [barback] and copies files that we didn't process (like
186 * polymer's libraries).
187 */
188 Future _emitAllFiles(Barback barback, BarbackOptions options) {
189 return _emitFiles(barback, options, 'web').then((res) {
190 if (options.transformTests) return _emitFiles(barback, options, 'test');
191 return res;
192 });
193 }
194
195 Future _emitFiles(Barback barback, BarbackOptions options, String emitSubDir) {
196 return barback.getAllAssets().then((assets) {
197 // Copy all the assets we transformed
198 var futures = [];
199 for (var asset in assets) {
200 var id = asset.id;
201 var filepath;
202 if (id.package == options.currentPackage &&
203 id.path.startsWith('$emitSubDir/')) {
204 filepath = path.join(options.outDir, id.path);
205 } else if (id.path.startsWith('lib/')) {
206 filepath = path.join(options.outDir, emitSubDir, 'packages', id.package,
207 id.path.substring(4));
208 } else {
209 // TODO(sigmund): do something about other assets?
210 continue;
211 }
212
213 _ensureDir(path.dirname(filepath));
214 var writer = new File(filepath).openWrite();
215 futures.add(writer.addStream(asset.read()).then((_) => writer.close()));
216 }
217 return Future.wait(futures).then((_) {
218 // Copy also all the files we didn't process
219 var futures = [];
220 for (var package in _polymerPackageDependencies) {
221 for (var relpath in _listPackageDir(package, 'lib', options)) {
222 var inpath = path.join(options.packageDirs[package], relpath);
223 var outpath = path.join(options.outDir, emitSubDir,
224 'packages', package, relpath.substring(4));
225 _ensureDir(path.dirname(outpath));
226
227 var writer = new File(outpath).openWrite();
228 futures.add(writer.addStream(new File(inpath).openRead())
229 .then((_) => writer.close()));
230 }
231 }
232 return Future.wait(futures);
233 }).then((_) => assets);
234 });
235 }
236
237 /** Ensure [dirpath] exists. */
238 void _ensureDir(var dirpath) {
239 new Directory(dirpath).createSync(recursive: true);
240 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698