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

Side by Side Diff: observatory_pub_packages/polymer/builder.dart

Issue 816693004: Add observatory_pub_packages snapshot to third_party (Closed) Base URL: http://dart.googlecode.com/svn/third_party/
Patch Set: 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
(Empty)
1 // Copyright (c) 2012, 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 /// Common logic to make it easy to run the polymer linter and deploy tool.
6 ///
7 /// The functions in this library are designed to make it easier to create
8 /// `build.dart` files. A `build.dart` file is a Dart script that can be invoked
9 /// from the command line, but that can also invoked automatically by the Dart
10 /// Editor whenever a file in your project changes or when selecting some menu
11 /// options, such as 'Reanalyze Sources'.
12 ///
13 /// To work correctly, place the `build.dart` in the root of your project (where
14 /// pubspec.yaml lives). The file must be named exactly `build.dart`.
15 ///
16 /// It's quite likely that in the near future `build.dart` will be replaced with
17 /// something else. For example, `pub deploy` will deal with deploying
18 /// applications automatically, and the Dart Editor might provide other
19 /// mechanisms to hook linters.
20 ///
21 /// There are three important functions exposed by this library [build], [lint],
22 /// and [deploy]. The following examples show common uses of these functions
23 /// when writing a `build.dart` file.
24 ///
25 /// **Example 1**: Uses build.dart to run the linter tool.
26 ///
27 /// import 'dart:io';
28 /// import 'package:polymer/builder.dart';
29 ///
30 /// main() {
31 /// lint();
32 /// }
33 ///
34 /// **Example 2**: Runs the linter and creates a deployable version of the app
35 /// every time.
36 ///
37 /// import 'dart:io';
38 /// import 'package:polymer/builder.dart';
39 ///
40 /// main() {
41 /// deploy(); // deploy also calls the linter internally.
42 /// }
43 ///
44 /// **Example 3**: Always run the linter, but conditionally build a deployable
45 /// version. See [parseOptions] for a description of options parsed
46 /// automatically by this helper library.
47 ///
48 /// import 'dart:io';
49 /// import 'package:polymer/builder.dart';
50 ///
51 /// main(args) {
52 /// var options = parseOptions(args);
53 /// if (options.forceDeploy) {
54 /// deploy();
55 /// } else {
56 /// lint();
57 /// }
58 /// }
59 ///
60 /// **Example 4**: Same as above, but uses [build] (which internally calls
61 /// either [lint] or [deploy]).
62 ///
63 /// import 'dart:io';
64 /// import 'package:polymer/builder.dart';
65 ///
66 /// main(args) {
67 /// build(options: parseOptions(args));
68 /// }
69 ///
70 /// **Example 5**: Like the previous example, but indicates to the linter and
71 /// deploy tool which files are actually used as entry point files. See the
72 /// documentation of [build] below for more details.
73 ///
74 /// import 'dart:io';
75 /// import 'package:polymer/builder.dart';
76 ///
77 /// main(args) {
78 /// build(entryPoints: ['web/index.html'], options: parseOptions(args));
79 /// }
80 library polymer.builder;
81
82 import 'dart:async';
83 import 'dart:io';
84
85 import 'package:args/args.dart';
86 import 'package:path/path.dart' as path;
87 import 'package:yaml/yaml.dart';
88
89 import 'src/build/linter.dart';
90 import 'src/build/runner.dart';
91 import 'src/build/common.dart';
92
93 import 'transformer.dart';
94
95
96 /// Runs the polymer linter on any relevant file in your package, such as any
97 /// .html file under 'lib/', 'asset/', and 'web/'. And, if requested, creates a
98 /// directory suitable for deploying a Polymer application to a server.
99 ///
100 /// The [entryPoints] list contains files under web/ that should be treated as
101 /// entry points. Each entry on this list is a relative path from the package
102 /// root (for example 'web/index.html'). If null, all files under 'web/' are
103 /// treated as possible entry points.
104 ///
105 /// Options must be passed by
106 /// passing the [options] argument. The deploy operation is run only when the
107 /// command-line argument `--deploy` is present, or equivalently when
108 /// `options.forceDeploy` is true.
109 ///
110 /// The linter and deploy steps needs to know the name of the [currentPackage]
111 /// and the location where to find the code for any package it depends on
112 /// ([packageDirs]). This is inferred automatically, but can be overriden if
113 /// those arguments are provided.
114 Future build({List<String> entryPoints, CommandLineOptions options,
115 String currentPackage, Map<String, String> packageDirs}) {
116 if (options == null) {
117 print('warning: now that main takes arguments, you need to explicitly pass'
118 ' options to build(). Running as if no options were passed.');
119 options = parseOptions([]);
120 }
121 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
122
123 return options.forceDeploy
124 ? deploy(entryPoints: entryPoints, options: options,
125 currentPackage: currentPackage, packageDirs: packageDirs)
126 : lint(entryPoints: entryPoints, options: options,
127 currentPackage: currentPackage, packageDirs: packageDirs);
128 }
129
130
131 /// Runs the polymer linter on any relevant file in your package,
132 /// such as any .html file under 'lib/', 'asset/', and 'web/'.
133 ///
134 /// The [entryPoints] list contains files under web/ that should be treated as
135 /// entry points. Each entry on this list is a relative path from the package
136 /// root (for example 'web/index.html'). If null, all files under 'web/' are
137 /// treated as possible entry points.
138 ///
139 /// Options must be passed by passing the [options] argument.
140 ///
141 /// The linter needs to know the name of the [currentPackage] and the location
142 /// where to find the code for any package it depends on ([packageDirs]). This
143 /// is inferred automatically, but can be overriden by passing the arguments.
144 Future lint({List<String> entryPoints, CommandLineOptions options,
145 String currentPackage, Map<String, String> packageDirs}) {
146 if (options == null) {
147 print('warning: now that main takes arguments, you need to explicitly pass'
148 ' options to lint(). Running as if no options were passed.');
149 options = parseOptions([]);
150 }
151 if (currentPackage == null) currentPackage = readCurrentPackageFromPubspec();
152 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
153 var linterOptions = new TransformOptions(entryPoints: entryPoints);
154 var linter = new Linter(linterOptions);
155
156 return runBarback(new BarbackOptions([[linter]], null,
157 currentPackage: currentPackage, packageDirs: packageDirs,
158 machineFormat: options.machineFormat));
159 }
160
161 /// Creates a directory suitable for deploying a Polymer application to a
162 /// server.
163 ///
164 /// **Note**: this function will be replaced in the future by the `pub deploy`
165 /// command.
166 ///
167 /// The [entryPoints] list contains files under web/ that should be treated as
168 /// entry points. Each entry on this list is a relative path from the package
169 /// root (for example 'web/index.html'). If null, all files under 'web/' are
170 /// treated as possible entry points.
171 ///
172 /// Options must be passed by passing the [options] list.
173 ///
174 /// The deploy step needs to know the name of the [currentPackage] and the
175 /// location where to find the code for any package it depends on
176 /// ([packageDirs]). This is inferred automatically, but can be overriden if
177 /// those arguments are provided.
178 Future deploy({List<String> entryPoints, CommandLineOptions options,
179 String currentPackage, Map<String, String> packageDirs}) {
180 if (options == null) {
181 print('warning: now that main takes arguments, you need to explicitly pass'
182 ' options to deploy(). Running as if no options were passed.');
183 options = parseOptions([]);
184 }
185 if (currentPackage == null) currentPackage = readCurrentPackageFromPubspec();
186 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
187
188 var transformOptions = new TransformOptions(
189 entryPoints: entryPoints,
190 directlyIncludeJS: options.directlyIncludeJS,
191 contentSecurityPolicy: options.contentSecurityPolicy,
192 releaseMode: options.releaseMode);
193
194 var phases = new PolymerTransformerGroup(transformOptions).phases;
195 var barbackOptions = new BarbackOptions(
196 phases, options.outDir, currentPackage: currentPackage,
197 packageDirs: packageDirs, machineFormat: options.machineFormat,
198 // TODO(sigmund): include here also smoke transformer when it's on by
199 // default.
200 packagePhases: {'polymer': phasesForPolymer});
201 return runBarback(barbackOptions)
202 .then((_) => print('Done! All files written to "${options.outDir}"'));
203 }
204
205
206 /// Options that may be used either in build.dart or by the linter and deploy
207 /// tools.
208 class CommandLineOptions {
209 /// Files marked as changed.
210 final List<String> changedFiles;
211
212 /// Files marked as removed.
213 final List<String> removedFiles;
214
215 /// Whether to clean intermediate artifacts, if any.
216 final bool clean;
217
218 /// Whether to do a full build (as if all files have changed).
219 final bool full;
220
221 /// Whether to print results using a machine parseable format.
222 final bool machineFormat;
223
224 /// Whether the force deploy option was passed in the command line.
225 final bool forceDeploy;
226
227 /// Location where to generate output files.
228 final String outDir;
229
230 /// True to use the CSP-compliant JS file.
231 final bool contentSecurityPolicy;
232
233 /// True to include the JS script tag directly, without the
234 /// "packages/browser/dart.js" trampoline.
235 final bool directlyIncludeJS;
236
237 /// Run transformers in release mode. For instance, uses the minified versions
238 /// of the web_components polyfill.
239 final bool releaseMode;
240
241 CommandLineOptions(this.changedFiles, this.removedFiles, this.clean,
242 this.full, this.machineFormat, this.forceDeploy, this.outDir,
243 this.directlyIncludeJS, this.contentSecurityPolicy,
244 this.releaseMode);
245 }
246
247 /// Parse command-line arguments and return a [CommandLineOptions] object. The
248 /// following flags are parsed by this method.
249 ///
250 /// * `--changed file-path`: notify of a file change.
251 /// * `--removed file-path`: notify that a file was removed.
252 /// * `--clean`: remove temporary artifacts (if any)
253 /// * `--full`: build everything, similar to marking every file as changed
254 /// * `--machine`: produce output that can be parsed by tools, such as the
255 /// Dart Editor.
256 /// * `--deploy`: force deploy.
257 /// * `--no-js`: deploy replaces *.dart scripts with *.dart.js. You can turn
258 /// this feature off with --no-js, which leaves "packages/browser/dart.js".
259 /// * `--csp`: extracts inlined JavaScript code to comply with Content
260 /// Security Policy restrictions.
261 /// * `--help`: print documentation for each option and exit.
262 ///
263 /// Currently not all the flags are used by [lint] or [deploy] above, but they
264 /// are available so they can be used from your `build.dart`. For instance, see
265 /// the top-level library documentation for an example that uses the
266 /// force-deploy option to conditionally call [deploy].
267 ///
268 /// If this documentation becomes out of date, the best way to discover which
269 /// flags are supported is to invoke this function from your build.dart, and run
270 /// it with the `--help` command-line flag.
271 CommandLineOptions parseOptions([List<String> args]) {
272 if (args == null) {
273 print('warning: the list of arguments from main(List<String> args) now '
274 'needs to be passed explicitly to parseOptions.');
275 args = [];
276 }
277 var parser = new ArgParser()
278 ..addOption('changed', help: 'The file has changed since the last build.',
279 allowMultiple: true)
280 ..addOption('removed', help: 'The file was removed since the last build.',
281 allowMultiple: true)
282 ..addFlag('clean', negatable: false,
283 help: 'Remove any build artifacts (if any).')
284 ..addFlag('full', negatable: false, help: 'perform a full build')
285 ..addFlag('machine', negatable: false,
286 help: 'Produce warnings in a machine parseable format.')
287 ..addFlag('deploy', negatable: false,
288 help: 'Whether to force deploying.')
289 ..addOption('out', abbr: 'o', help: 'Directory to generate files into.',
290 defaultsTo: 'out')
291 ..addFlag('js', help:
292 'deploy replaces *.dart scripts with *.dart.js. This flag \n'
293 'leaves "packages/browser/dart.js" to do the replacement at runtime.',
294 defaultsTo: true)
295 ..addFlag('csp', help:
296 'extracts inlined JavaScript code to comply with \n'
297 'Content Security Policy restrictions.')
298 ..addFlag('debug', help:
299 'run in debug mode. For example, use the debug polyfill \n'
300 'web_components/webcomponents.js instead of the minified one.\n',
301 defaultsTo: false)
302 ..addFlag('help', abbr: 'h',
303 negatable: false, help: 'Displays this help and exit.');
304
305 showUsage() {
306 print('Usage: dart build.dart [options]');
307 print('\nThese are valid options expected by build.dart:');
308 print(parser.getUsage());
309 }
310
311 var res;
312 try {
313 res = parser.parse(args);
314 } on FormatException catch (e) {
315 print(e.message);
316 showUsage();
317 exit(1);
318 }
319 if (res['help']) {
320 print('A build script that invokes the polymer linter and deploy tools.');
321 showUsage();
322 exit(0);
323 }
324 return new CommandLineOptions(res['changed'], res['removed'], res['clean'],
325 res['full'], res['machine'], res['deploy'], res['out'], res['js'],
326 res['csp'], !res['debug']);
327 }
328
329 List<String> _parseEntryPointsFromPubspec() {
330 var entryPoints = [];
331 var pubspec = new File(path.join(
332 path.dirname(Platform.script.path), 'pubspec.yaml'));
333 if (!pubspec.existsSync()) {
334 print('error: pubspec.yaml file not found.');
335 return null;
336 }
337 var transformers = loadYaml(pubspec.readAsStringSync())['transformers'];
338 if (transformers == null) return null;
339 if (transformers is! List) {
340 print('Unexpected value for transformers, expected a List.');
341 return null;
342 }
343
344 transformers.forEach((t) {
345 if (t is! Map) return;
346 var polymer = t['polymer'];
347 if (polymer == null || polymer is! Map) return;
348
349 var parsedEntryPoints = readFileList(polymer['entry_points']);
350 if (parsedEntryPoints == null) return;
351
352 entryPoints.addAll(parsedEntryPoints);
353 });
354 return entryPoints.isEmpty ? null : entryPoints;
355 }
OLDNEW
« no previous file with comments | « observatory_pub_packages/polymer/boot.js ('k') | observatory_pub_packages/polymer/default_build.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698