| Index: pkg/polymer/lib/deploy.dart
|
| diff --git a/pkg/polymer/lib/deploy.dart b/pkg/polymer/lib/deploy.dart
|
| index 4c5b564d41e986850a8413b40b1386ed3956f927..6cb49ced45146b060c8c60e5af7e11428695d6f5 100644
|
| --- a/pkg/polymer/lib/deploy.dart
|
| +++ b/pkg/polymer/lib/deploy.dart
|
| @@ -3,6 +3,9 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| /**
|
| + * **Note**: If you already have a `build.dart` in your application, we
|
| + * recommend to use the `package:polymer/builder.dart` library instead.
|
| +
|
| * Temporary deploy command used to create a version of the app that can be
|
| * compiled with dart2js and deployed. Following pub layout conventions, this
|
| * script will treat any HTML file under a package 'web/' and 'test/'
|
| @@ -20,34 +23,33 @@
|
| library polymer.deploy;
|
|
|
| import 'dart:async';
|
| -import 'dart:convert';
|
| import 'dart:io';
|
|
|
| -import 'package:barback/barback.dart';
|
| -import 'package:path/path.dart' as path;
|
| -import 'package:polymer/src/transform.dart' show phases;
|
| -import 'package:stack_trace/stack_trace.dart';
|
| -import 'package:yaml/yaml.dart';
|
| import 'package:args/args.dart';
|
| +import 'package:path/path.dart' as path;
|
| +import 'package:polymer/src/barback_runner.dart';
|
| +import 'package:polymer/src/transform.dart';
|
|
|
| main() {
|
| var args = _parseArgs(new Options().arguments);
|
| - if (args == null) return;
|
| + if (args == null) exit(1);
|
|
|
| var test = args['test'];
|
| - if (test != null) {
|
| - _initForTest(test);
|
| - }
|
| -
|
| - print('polymer/deploy.dart: creating a deploy target for "$_currentPackage"');
|
| var outDir = args['out'];
|
| - _run(outDir, test != null).then(
|
| - (_) => print('Done! All files written to "$outDir"'));
|
| + var options = (test == null)
|
| + ? new BarbackOptions(createDeployPhases(new TransformOptions()), outDir)
|
| + : _createTestOptions(test, outDir);
|
| + if (options == null) exit(1);
|
| +
|
| + print('polymer/deploy.dart: creating a deploy target for '
|
| + '"${options.currentPackage}"');
|
| +
|
| + runBarback(options)
|
| + .then((_) => print('Done! All files written to "$outDir"'))
|
| + .catchError(_reportErrorAndExit);
|
| }
|
|
|
| -// TODO(jmesserly): the current deploy/barback architecture is very unfriendly
|
| -// to deploying a single test. We need to fix it somehow but it isn't clear yet.
|
| -void _initForTest(String testFile) {
|
| +BarbackOptions _createTestOptions(String testFile, String outDir) {
|
| var testDir = path.normalize(path.dirname(testFile));
|
|
|
| // A test must be allowed to import things in the package.
|
| @@ -57,11 +59,15 @@ void _initForTest(String testFile) {
|
| if (pubspecDir == null) {
|
| print('error: pubspec.yaml file not found, please run this script from '
|
| 'your package root directory or a subdirectory.');
|
| - exit(1);
|
| + return null;
|
| }
|
|
|
| - _currentPackage = '_test';
|
| - _packageDirs = {'_test' : pubspecDir};
|
| + var phases = createDeployPhases(new TransformOptions(
|
| + '_test', [path.relative(testFile, from: pubspecDir)]));
|
| + return new BarbackOptions(phases, outDir,
|
| + currentPackage: '_test',
|
| + packageDirs: {'_test' : pubspecDir},
|
| + transformTests: true);
|
| }
|
|
|
| String _findDirWithFile(String dir, String filename) {
|
| @@ -74,208 +80,18 @@ String _findDirWithFile(String dir, String filename) {
|
| return dir;
|
| }
|
|
|
| -/**
|
| - * API exposed for testing purposes. Runs this deploy command but prentend that
|
| - * the sources under [webDir] belong to package 'test'.
|
| - */
|
| -Future runForTest(String webDir, String outDir) {
|
| - _currentPackage = 'test';
|
| -
|
| - // associate package dirs with their location in the repo:
|
| - _packageDirs = {'test' : '.'};
|
| - _addPackages('..');
|
| - _addPackages('../third_party');
|
| - _addPackages('../../third_party/pkg');
|
| - return _run(webDir, outDir);
|
| -}
|
| -
|
| -_addPackages(String dir) {
|
| - for (var packageDir in new Directory(dir).listSync().map((d) => d.path)) {
|
| - _packageDirs[path.basename(packageDir)] = packageDir;
|
| - }
|
| -}
|
| -
|
| -Future _run(String outDir, bool includeTests) {
|
| - var barback = new Barback(new _PolymerDeployProvider());
|
| - _initializeBarback(barback, includeTests);
|
| - _attachListeners(barback);
|
| - return _emitAllFiles(barback, 'web', outDir).then(
|
| - (_) => includeTests ? _emitAllFiles(barback, 'test', outDir) : null);
|
| -}
|
| -
|
| -/** Tell barback which transformers to use and which assets to process. */
|
| -void _initializeBarback(Barback barback, bool includeTests) {
|
| - var assets = [];
|
| - void addAssets(String package, String subDir) {
|
| - for (var filepath in _listDir(package, subDir)) {
|
| - assets.add(new AssetId(package, filepath));
|
| - }
|
| - }
|
| -
|
| - for (var package in _packageDirs.keys) {
|
| - // Do not process packages like 'polymer' where there is nothing to do.
|
| - if (_ignoredPackages.contains(package)) continue;
|
| - barback.updateTransformers(package, phases);
|
| -
|
| - // notify barback to process anything under 'lib' and 'asset'
|
| - addAssets(package, 'lib');
|
| - addAssets(package, 'asset');
|
| - }
|
| -
|
| - // In case of the current package, include also 'web'.
|
| - addAssets(_currentPackage, 'web');
|
| - if (includeTests) addAssets(_currentPackage, 'test');
|
| -
|
| - barback.updateSources(assets);
|
| -}
|
| -
|
| -/** Return the relative path of each file under [subDir] in a [package]. */
|
| -Iterable<String> _listDir(String package, String subDir) {
|
| - var packageDir = _packageDirs[package];
|
| - if (packageDir == null) return const [];
|
| - var dir = new Directory(path.join(packageDir, subDir));
|
| - if (!dir.existsSync()) return const [];
|
| - return dir.listSync(recursive: true, followLinks: false)
|
| - .where((f) => f is File)
|
| - .map((f) => path.relative(f.path, from: packageDir));
|
| -}
|
| -
|
| -/** Attach error listeners on [barback] so we can report errors. */
|
| -void _attachListeners(Barback barback) {
|
| - // Listen for errors and results
|
| - barback.errors.listen((e) {
|
| - var trace = getAttachedStackTrace(e);
|
| - if (trace != null) {
|
| - print(Trace.format(trace));
|
| - }
|
| - print('error running barback: $e');
|
| - exit(1);
|
| - });
|
| -
|
| - barback.results.listen((result) {
|
| - if (!result.succeeded) {
|
| - print("build failed with errors: ${result.errors}");
|
| - exit(1);
|
| - }
|
| - });
|
| -}
|
| -
|
| -/** Ensure [dirpath] exists. */
|
| -void _ensureDir(var dirpath) {
|
| - new Directory(dirpath).createSync(recursive: true);
|
| +void _reportErrorAndExit(e) {
|
| + var trace = getAttachedStackTrace(e);
|
| + print('Uncaught error: $e');
|
| + if (trace != null) print(trace);
|
| + exit(1);
|
| }
|
|
|
| -/**
|
| - * Emits all outputs of [barback] and copies files that we didn't process (like
|
| - * polymer's libraries).
|
| - */
|
| -Future _emitAllFiles(Barback barback, String webDir, String outDir) {
|
| - return barback.getAllAssets().then((assets) {
|
| - // Copy all the assets we transformed
|
| - var futures = [];
|
| - for (var asset in assets) {
|
| - var id = asset.id;
|
| - var filepath;
|
| - if (id.package == _currentPackage && id.path.startsWith('$webDir/')) {
|
| - filepath = path.join(outDir, id.path);
|
| - } else if (id.path.startsWith('lib/')) {
|
| - filepath = path.join(outDir, webDir, 'packages', id.package,
|
| - id.path.substring(4));
|
| - } else {
|
| - // TODO(sigmund): do something about other assets?
|
| - continue;
|
| - }
|
| -
|
| - _ensureDir(path.dirname(filepath));
|
| - var writer = new File(filepath).openWrite();
|
| - futures.add(writer.addStream(asset.read()).then((_) => writer.close()));
|
| - }
|
| - return Future.wait(futures);
|
| - }).then((_) {
|
| - // Copy also all the files we didn't process
|
| - var futures = [];
|
| - for (var package in _ignoredPackages) {
|
| - for (var relpath in _listDir(package, 'lib')) {
|
| - var inpath = path.join(_packageDirs[package], relpath);
|
| - var outpath = path.join(outDir, webDir, 'packages', package,
|
| - relpath.substring(4));
|
| - _ensureDir(path.dirname(outpath));
|
| -
|
| - var writer = new File(outpath).openWrite();
|
| - futures.add(writer.addStream(new File(inpath).openRead())
|
| - .then((_) => writer.close()));
|
| - }
|
| - }
|
| - return Future.wait(futures);
|
| - });
|
| -}
|
| -
|
| -/** A simple provider that reads files directly from the pub cache. */
|
| -class _PolymerDeployProvider implements PackageProvider {
|
| -
|
| - Iterable<String> get packages => _packageDirs.keys;
|
| - _PolymerDeployProvider();
|
| -
|
| - Future<Asset> getAsset(AssetId id) =>
|
| - new Future.value(new Asset.fromPath(id, path.join(
|
| - _packageDirs[id.package],
|
| - // Assets always use the posix style paths
|
| - path.joinAll(path.posix.split(id.path)))));
|
| -}
|
| -
|
| -
|
| -/** The current package extracted from the pubspec.yaml file. */
|
| -String _currentPackage = () {
|
| - var pubspec = new File('pubspec.yaml');
|
| - if (!pubspec.existsSync()) {
|
| - print('error: pubspec.yaml file not found, please run this script from '
|
| - 'your package root directory.');
|
| - return null;
|
| - }
|
| - return loadYaml(pubspec.readAsStringSync())['name'];
|
| -}();
|
| -
|
| -/**
|
| - * Maps package names to the path in the file system where to find the sources
|
| - * of such package. This map will contain an entry for the current package and
|
| - * everything it depends on (extracted via `pub list-pacakge-dirs`).
|
| - */
|
| -Map<String, String> _packageDirs = () {
|
| - var pub = path.join(path.dirname(new Options().executable),
|
| - Platform.isWindows ? 'pub.bat' : 'pub');
|
| - var result = Process.runSync(pub, ['list-package-dirs']);
|
| - if (result.exitCode != 0) {
|
| - print("unexpected error invoking 'pub':");
|
| - print(result.stdout);
|
| - print(result.stderr);
|
| - exit(result.exitCode);
|
| - }
|
| - var map = JSON.decode(result.stdout)["packages"];
|
| - map.forEach((k, v) { map[k] = path.dirname(v); });
|
| - map[_currentPackage] = '.';
|
| - return map;
|
| -}();
|
| -
|
| -/**
|
| - * Internal packages used by polymer which we can copy directly to the output
|
| - * folder without having to process them with barback.
|
| - */
|
| -// TODO(sigmund): consider computing this list by recursively parsing
|
| -// pubspec.yaml files in the [_packageDirs].
|
| -final Set<String> _ignoredPackages =
|
| - (const [ 'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
|
| - 'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
|
| - 'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path',
|
| - 'polymer', 'polymer_expressions', 'serialization', 'shadow_dom',
|
| - 'source_maps', 'stack_trace', 'unittest',
|
| - 'unmodifiable_collection', 'yaml'
|
| - ]).toSet();
|
| -
|
| ArgResults _parseArgs(arguments) {
|
| var parser = new ArgParser()
|
| ..addFlag('help', abbr: 'h', help: 'Displays this help message.',
|
| defaultsTo: false, negatable: false)
|
| - ..addOption('out', abbr: 'o', help: 'Directory where to generated files.',
|
| + ..addOption('out', abbr: 'o', help: 'Directory to generate files into.',
|
| defaultsTo: 'out')
|
| ..addOption('test', help: 'Deploy the test at the given path.\n'
|
| 'Note: currently this will deploy all tests in its directory,\n'
|
| @@ -295,6 +111,7 @@ ArgResults _parseArgs(arguments) {
|
| }
|
|
|
| _showUsage(parser) {
|
| - print('Usage: dart package:polymer/deploy.dart [options]');
|
| + print('Usage: dart --package-root=packages/ '
|
| + 'package:polymer/deploy.dart [options]');
|
| print(parser.getUsage());
|
| }
|
|
|