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

Side by Side Diff: pkg/polymer/lib/deploy.dart

Issue 23189016: Add a deploy script based on polymer's transformers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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 | « no previous file | pkg/polymer/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 * Temporary deploy command used to create a version of the app that can be
7 * compiled with dart2js and deployed. This library should go away once `pub
8 * deploy` can be configured to run barback transformers.
9 *
10 * From an application package you can run this program by calling dart with a
11 * 'package:' url to this file:
12 *
13 * dart package:polymer/deploy.dart
14 */
15 library polymer.deploy;
16
17 import 'dart:async';
18 import 'dart:io';
19 import 'dart:json' as json;
20
21 import 'package:barback/barback.dart';
22 import 'package:path/path.dart' as path;
23 import 'package:polymer/src/transform.dart' show phases;
24 import 'package:stack_trace/stack_trace.dart';
25 import 'package:yaml/yaml.dart';
26 import 'package:args/args.dart';
27
28 main() {
29 var args = _parseArgs();
30 if (args == null) return;
31 print('polymer/deploy.dart: creating a deploy target for "$_currentPackage"');
32 var barback = new Barback(new _PolymerDeployProvider());
33 _initializeBarback(barback);
34 _attachListeners(barback);
35 _emitAllFiles(barback, args['out']);
36 }
37
38 /** Tell barback which transformers to use and which assets to process. */
39 void _initializeBarback(Barback barback) {
40 var assets = [];
41 for (var package in _packageDirs.keys) {
42 // Do not process packages like 'polymer' where there is nothing to do.
43 if (_ignoredPackages.contains(package)) continue;
44 barback.updateTransformers(package, phases);
45
46 // notify barback to process anything under 'lib' and 'asset'
47 for (var filepath in _listDir(package, 'lib')) {
48 assets.add(new AssetId(package, filepath));
49 }
50
51 for (var filepath in _listDir(package, 'asset')) {
52 assets.add(new AssetId(package, filepath));
53 }
54 }
55
56 // In case of the current package, include also 'web'.
57 for (var filepath in _listDir(_currentPackage, 'web')) {
58 assets.add(new AssetId(_currentPackage, filepath));
59 }
60 barback.updateSources(assets);
61 }
62
63 /** Return the relative path of each file under [subDir] in a [package]. */
64 Iterable<String> _listDir(String package, String subDir) {
65 var packageDir = _packageDirs[package];
66 if (packageDir == null) return const [];
67 var dir = new Directory(path.join(packageDir, subDir));
68 if (!dir.existsSync()) return const [];
69 return dir.listSync(recursive: true, followLinks: false)
70 .where((f) => f is File)
71 .map((f) => path.relative(f.path, from: packageDir));
72 }
73
74 /** Attach error listeners on [barback] so we can report errors. */
75 void _attachListeners(Barback barback) {
76 // Listen for errors and results
77 barback.errors.listen((e) {
78 var trace = getAttachedStackTrace(e);
79 if (trace != null) {
80 print(Trace.format(trace));
81 }
82 print('error running barback: $e');
83 exit(1);
84 });
85
86 barback.results.listen((result) {
87 if (!result.succeeded) {
88 print("build failed with errors: ${result.errors}");
89 exit(1);
90 }
91 });
92 }
93
94 /** Ensure [dirpath] exists. */
95 void _ensureDir(var dirpath) {
96 new Directory(dirpath).createSync(recursive: true);
97 }
98
99 /**
100 * Emits all outputs of [barback] and copies files that we didn't process (like
101 * polymer's libraries).
102 */
103 Future _emitAllFiles(Barback barback, String outDir) {
104 return barback.getAllAssets().then((assets) {
105 // Copy all the assets we transformed
106 var futures = [];
107 for (var asset in assets) {
108 var id = asset.id;
109 var filepath;
110 if (id.package == _currentPackage && id.path.startsWith('web/')) {
111 filepath = path.join(outDir, id.path);
112 } else if (id.path.startsWith('lib/')) {
113 filepath = path.join(outDir, 'web', 'packages', id.package,
114 id.path.substring(4));
115 } else {
116 // TODO(sigmund): do something about other assets?
117 continue;
118 }
119
120 _ensureDir(path.dirname(filepath));
121 futures.add(asset.readAsString()
122 .then((content) => new File(filepath).writeAsStringSync(content)));
123 }
124 return Future.wait(futures);
125 }).then((_) {
126 // Copy also all the files we didn't process
127 var futures = [];
128 for (var package in _ignoredPackages) {
129 for (var relpath in _listDir(package, 'lib')) {
130 var inpath = path.join(_packageDirs[package], relpath);
131 var outpath = path.join(outDir, 'web', 'packages', package,
132 relpath.substring(4));
133 _ensureDir(path.dirname(outpath));
134
135 var writer = new File(outpath).openWrite();
136 futures.add(writer.addStream(new File(inpath).openRead())
137 .then((_) => writer.close()));
138 }
139 }
140 return Future.wait(futures)
141 .then((_) => print('Done! All files written to "$outDir"'));
142 });
143 }
144
145 /** A simple provider that reads files directly from the pub cache. */
146 class _PolymerDeployProvider implements PackageProvider {
147
148 Iterable<String> get packages => _packageDirs.keys;
149 _PolymerDeployProvider();
150
151 Future<Asset> getAsset(AssetId id) =>
152 new Future.value(new Asset.fromPath(id, path.join(
153 _packageDirs[id.package],
154 // Assets always use the posix style paths
155 path.joinAll(path.posix.split(id.path)))));
156 }
157
158
159 /** The current package extracted from the pubspec.yaml file. */
160 String _currentPackage = () {
161 var pubspec = new File('pubspec.yaml');
162 if (!pubspec.existsSync()) {
163 print('error: pubspec.yaml file not found, please run this script from '
164 'your package root directory.');
165 return null;
166 }
167 return loadYaml(pubspec.readAsStringSync())['name'];
168 }();
169
170 /**
171 * Maps package names to the path in the file system where to find the sources
172 * of such package. This map will contain an entry for the current package and
173 * everything it depends on (extracted via `pub list-pacakge-dirs`).
174 */
175 Map<String, String> _packageDirs = () {
176 var pub = path.join(path.dirname(new Options().executable),
177 Platform.isWindows ? 'pub.bat' : 'pub');
178 var result = Process.runSync(pub, ['list-package-dirs']);
179 if (result.exitCode != 0) {
180 print("unexpected error invoking 'pub':");
181 print(result.stdout);
182 print(result.stderr);
183 exit(result.exitCode);
184 }
185 var map = json.parse(result.stdout)["packages"];
186 map.forEach((k, v) { map[k] = path.dirname(v); });
187 map[_currentPackage] = '.';
188 return map;
189 }();
190
191 /**
192 * Internal packages used by polymer which we can copy directly to the output
193 * folder without having to process them with barback.
194 */
195 // TODO(sigmund): consider computing this list by recursively parsing
196 // pubspec.yaml files in the [_packageDirs].
197 Set<String> _ignoredPackages =
198 (const [ 'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
199 'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
200 'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path',
201 'polymer', 'polymer_expressions', 'serialization', 'shadow_dom',
202 'source_maps', 'stack_trace', 'unittest',
203 'unmodifiable_collection', 'yaml'
204 ]).toSet();
205
206 ArgResults _parseArgs() {
207 var parser = new ArgParser()
208 ..addFlag('help', abbr: 'h', help: 'Displays this help message',
209 defaultsTo: false, negatable: false)
210 ..addOption('out', abbr: 'o', help: 'Directory where to generated files',
211 defaultsTo: 'out');
212 try {
213 var results = parser.parse(new Options().arguments);
214 if (results['help']) {
215 _showUsage(parser);
216 return null;
217 }
218 return results;
219 } on FormatException catch (e) {
220 print(e.message);
221 _showUsage(parser);
222 return null;
223 }
224 }
225
226 _showUsage(parser) {
227 print('Usage: dart package:polymer/deploy.dart [options]');
228 print(parser.getUsage());
229 }
OLDNEW
« no previous file with comments | « no previous file | pkg/polymer/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698