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

Side by Side Diff: packages/polymer/lib/builder.dart

Issue 2312183003: Removed Polymer from Observatory deps (Closed)
Patch Set: Created 4 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
« no previous file with comments | « packages/polymer/lib/auto_binding.dart ('k') | packages/polymer/lib/default_build.dart » ('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) 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 /// Runs the polymer linter on any relevant file in your package, such as any
96 /// .html file under 'lib/', 'asset/', and 'web/'. And, if requested, creates a
97 /// directory suitable for deploying a Polymer application to a server.
98 ///
99 /// The [entryPoints] list contains files under web/ that should be treated as
100 /// entry points. Each entry on this list is a relative path from the package
101 /// root (for example 'web/index.html'). If null, all files under 'web/' are
102 /// treated as possible entry points.
103 ///
104 /// Options must be passed by
105 /// passing the [options] argument. The deploy operation is run only when the
106 /// command-line argument `--deploy` is present, or equivalently when
107 /// `options.forceDeploy` is true.
108 ///
109 /// The linter and deploy steps needs to know the name of the [currentPackage]
110 /// and the location where to find the code for any package it depends on
111 /// ([packageDirs]). This is inferred automatically, but can be overriden if
112 /// those arguments are provided.
113 Future build({List<String> entryPoints, CommandLineOptions options,
114 String currentPackage, Map<String, String> packageDirs}) {
115 if (options == null) {
116 print('warning: now that main takes arguments, you need to explicitly pass'
117 ' options to build(). Running as if no options were passed.');
118 options = parseOptions([]);
119 }
120 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
121
122 return options.forceDeploy
123 ? deploy(
124 entryPoints: entryPoints,
125 options: options,
126 currentPackage: currentPackage,
127 packageDirs: packageDirs)
128 : lint(
129 entryPoints: entryPoints,
130 options: options,
131 currentPackage: currentPackage,
132 packageDirs: packageDirs);
133 }
134
135 /// Runs the polymer linter on any relevant file in your package,
136 /// such as any .html file under 'lib/', 'asset/', and 'web/'.
137 ///
138 /// The [entryPoints] list contains files under web/ that should be treated as
139 /// entry points. Each entry on this list is a relative path from the package
140 /// root (for example 'web/index.html'). If null, all files under 'web/' are
141 /// treated as possible entry points.
142 ///
143 /// Options must be passed by passing the [options] argument.
144 ///
145 /// The linter needs to know the name of the [currentPackage] and the location
146 /// where to find the code for any package it depends on ([packageDirs]). This
147 /// is inferred automatically, but can be overriden by passing the arguments.
148 Future lint({List<String> entryPoints, CommandLineOptions options,
149 String currentPackage, Map<String, String> packageDirs}) {
150 if (options == null) {
151 print('warning: now that main takes arguments, you need to explicitly pass'
152 ' options to lint(). Running as if no options were passed.');
153 options = parseOptions([]);
154 }
155 if (currentPackage == null) currentPackage = readCurrentPackageFromPubspec();
156 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
157 var linterOptions = new TransformOptions(entryPoints: entryPoints);
158 var linter = new Linter(linterOptions, skipMissingElementWarning: true);
159
160 return runBarback(new BarbackOptions([[linter]], null,
161 currentPackage: currentPackage,
162 packageDirs: packageDirs,
163 machineFormat: options.machineFormat));
164 }
165
166 /// Creates a directory suitable for deploying a Polymer application to a
167 /// server.
168 ///
169 /// **Note**: this function will be replaced in the future by the `pub deploy`
170 /// command.
171 ///
172 /// The [entryPoints] list contains files under web/ that should be treated as
173 /// entry points. Each entry on this list is a relative path from the package
174 /// root (for example 'web/index.html'). If null, all files under 'web/' are
175 /// treated as possible entry points.
176 ///
177 /// Options must be passed by passing the [options] list.
178 ///
179 /// The deploy step needs to know the name of the [currentPackage] and the
180 /// location where to find the code for any package it depends on
181 /// ([packageDirs]). This is inferred automatically, but can be overriden if
182 /// those arguments are provided.
183 Future deploy({List<String> entryPoints, CommandLineOptions options,
184 String currentPackage, Map<String, String> packageDirs}) {
185 if (options == null) {
186 print('warning: now that main takes arguments, you need to explicitly pass'
187 ' options to deploy(). Running as if no options were passed.');
188 options = parseOptions([]);
189 }
190 if (currentPackage == null) currentPackage = readCurrentPackageFromPubspec();
191 if (entryPoints == null) entryPoints = _parseEntryPointsFromPubspec();
192
193 var transformOptions = new TransformOptions(
194 entryPoints: entryPoints,
195 directlyIncludeJS: options.directlyIncludeJS,
196 contentSecurityPolicy: options.contentSecurityPolicy,
197 releaseMode: options.releaseMode);
198
199 var phases = new PolymerTransformerGroup(transformOptions).phases;
200 var barbackOptions = new BarbackOptions(phases, options.outDir,
201 currentPackage: currentPackage,
202 packageDirs: packageDirs,
203 machineFormat: options.machineFormat,
204 // TODO(sigmund): include here also smoke transformer when it's on by
205 // default.
206 packagePhases: {'polymer': phasesForPolymer});
207 return runBarback(barbackOptions)
208 .then((_) => print('Done! All files written to "${options.outDir}"'));
209 }
210
211 /// Options that may be used either in build.dart or by the linter and deploy
212 /// tools.
213 class CommandLineOptions {
214 /// Files marked as changed.
215 final List<String> changedFiles;
216
217 /// Files marked as removed.
218 final List<String> removedFiles;
219
220 /// Whether to clean intermediate artifacts, if any.
221 final bool clean;
222
223 /// Whether to do a full build (as if all files have changed).
224 final bool full;
225
226 /// Whether to print results using a machine parseable format.
227 final bool machineFormat;
228
229 /// Whether the force deploy option was passed in the command line.
230 final bool forceDeploy;
231
232 /// Location where to generate output files.
233 final String outDir;
234
235 /// True to use the CSP-compliant JS file.
236 final bool contentSecurityPolicy;
237
238 /// True to include the JS script tag directly, without the
239 /// "packages/browser/dart.js" trampoline.
240 final bool directlyIncludeJS;
241
242 /// Run transformers in release mode. For instance, uses the minified versions
243 /// of the web_components polyfill.
244 final bool releaseMode;
245
246 CommandLineOptions(this.changedFiles, this.removedFiles, this.clean,
247 this.full, this.machineFormat, this.forceDeploy, this.outDir,
248 this.directlyIncludeJS, this.contentSecurityPolicy, this.releaseMode);
249 }
250
251 /// Parse command-line arguments and return a [CommandLineOptions] object. The
252 /// following flags are parsed by this method.
253 ///
254 /// * `--changed file-path`: notify of a file change.
255 /// * `--removed file-path`: notify that a file was removed.
256 /// * `--clean`: remove temporary artifacts (if any)
257 /// * `--full`: build everything, similar to marking every file as changed
258 /// * `--machine`: produce output that can be parsed by tools, such as the
259 /// Dart Editor.
260 /// * `--deploy`: force deploy.
261 /// * `--no-js`: deploy replaces *.dart scripts with *.dart.js. You can turn
262 /// this feature off with --no-js, which leaves "packages/browser/dart.js".
263 /// * `--csp`: extracts inlined JavaScript code to comply with Content
264 /// Security Policy restrictions.
265 /// * `--help`: print documentation for each option and exit.
266 ///
267 /// Currently not all the flags are used by [lint] or [deploy] above, but they
268 /// are available so they can be used from your `build.dart`. For instance, see
269 /// the top-level library documentation for an example that uses the
270 /// force-deploy option to conditionally call [deploy].
271 ///
272 /// If this documentation becomes out of date, the best way to discover which
273 /// flags are supported is to invoke this function from your build.dart, and run
274 /// it with the `--help` command-line flag.
275 CommandLineOptions parseOptions([List<String> args]) {
276 if (args == null) {
277 print('warning: the list of arguments from main(List<String> args) now '
278 'needs to be passed explicitly to parseOptions.');
279 args = [];
280 }
281 var parser = new ArgParser()
282 ..addOption('changed',
283 help: 'The file has changed since the last build.', allowMultiple: true)
284 ..addOption('removed',
285 help: 'The file was removed since the last build.', allowMultiple: true)
286 ..addFlag('clean',
287 negatable: false, help: 'Remove any build artifacts (if any).')
288 ..addFlag('full', negatable: false, help: 'perform a full build')
289 ..addFlag('machine',
290 negatable: false,
291 help: 'Produce warnings in a machine parseable format.')
292 ..addFlag('deploy', negatable: false, help: 'Whether to force deploying.')
293 ..addOption('out',
294 abbr: 'o', help: 'Directory to generate files into.', defaultsTo: 'out')
295 ..addFlag('js',
296 help: 'deploy replaces *.dart scripts with *.dart.js. This flag \n'
297 'leaves "packages/browser/dart.js" to do the replacement at runtime.',
298 defaultsTo: true)
299 ..addFlag('csp', help: 'extracts inlined JavaScript code to comply with \n'
300 'Content Security Policy restrictions.')
301 ..addFlag('debug',
302 help: 'run in debug mode. For example, use the debug polyfill \n'
303 'web_components/webcomponents.js instead of the minified one.\n',
304 defaultsTo: false)
305 ..addFlag('help',
306 abbr: 'h', negatable: false, help: 'Displays this help and exit.');
307
308 showUsage() {
309 print('Usage: dart build.dart [options]');
310 print('\nThese are valid options expected by build.dart:');
311 print(parser.getUsage());
312 }
313
314 var res;
315 try {
316 res = parser.parse(args);
317 } on FormatException catch (e) {
318 print(e.message);
319 showUsage();
320 exit(1);
321 }
322 if (res['help']) {
323 print('A build script that invokes the polymer linter and deploy tools.');
324 showUsage();
325 exit(0);
326 }
327 return new CommandLineOptions(res['changed'], res['removed'], res['clean'],
328 res['full'], res['machine'], res['deploy'], res['out'], res['js'],
329 res['csp'], !res['debug']);
330 }
331
332 List<String> _parseEntryPointsFromPubspec() {
333 var entryPoints = [];
334 var pubspec =
335 new File(path.join(path.dirname(Platform.script.path), 'pubspec.yaml'));
336 if (!pubspec.existsSync()) {
337 print('error: pubspec.yaml file not found.');
338 return null;
339 }
340 var transformers = loadYaml(pubspec.readAsStringSync())['transformers'];
341 if (transformers == null) return null;
342 if (transformers is! List) {
343 print('Unexpected value for transformers, expected a List.');
344 return null;
345 }
346
347 transformers.forEach((t) {
348 if (t is! Map) return;
349 var polymer = t['polymer'];
350 if (polymer == null || polymer is! Map) return;
351
352 var parsedEntryPoints = readFileList(polymer['entry_points']);
353 if (parsedEntryPoints == null) return;
354
355 entryPoints.addAll(parsedEntryPoints);
356 });
357 return entryPoints.isEmpty ? null : entryPoints;
358 }
OLDNEW
« no previous file with comments | « packages/polymer/lib/auto_binding.dart ('k') | packages/polymer/lib/default_build.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698