Chromium Code Reviews| Index: pkg/polymer/lib/deploy.dart |
| diff --git a/pkg/polymer/lib/deploy.dart b/pkg/polymer/lib/deploy.dart |
| index 4c5b564d41e986850a8413b40b1386ed3956f927..82a5c72d58aff17cd251eb46bae699ca7828470a 100644 |
| --- a/pkg/polymer/lib/deploy.dart |
| +++ b/pkg/polymer/lib/deploy.dart |
| @@ -16,38 +16,40 @@ |
| * |
| * This library should go away once `pub deploy` can be configured to run |
| * barback transformers. |
| + * |
| + * **Note**: If you already have a `build.dart` in your application, we |
|
Jennifer Messerly
2013/09/10 04:16:51
suggestion: move up front
Siggi Cherem (dart-lang)
2013/09/11 01:45:26
Done.
|
| + * recommend to use the `build_helper.dart` library instead. |
| */ |
| 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:polymer/src/transform.dart'; |
| +import 'package:polymer/src/barback_helper.dart'; |
| import 'package:args/args.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) { |
|
Siggi Cherem (dart-lang)
2013/09/10 03:40:57
most code below here basically moved to lib/src/ba
|
| - 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); |
| -} |
| - |
| -/** |
| - * 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))))); |
| +void _reportErrorAndExit(e) { |
| + var trace = getAttachedStackTrace(e); |
| + print('Uncaught error: $e'); |
| + if (trace != null) print(trace); |
| + exit(1); |
| } |
| - |
| -/** 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 where to generate files.', |
|
Jennifer Messerly
2013/09/10 04:16:51
"directory to generate files" ?
or "directory to g
Siggi Cherem (dart-lang)
2013/09/11 01:45:26
Done.
|
| 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/ ' |
|
Jennifer Messerly
2013/09/10 04:16:51
is the --package-root actually required? even for
Siggi Cherem (dart-lang)
2013/09/11 01:45:26
Yeah, this is because the 'package-root' is resolv
Jennifer Messerly
2013/09/11 20:07:54
strange :| perhaps we should just tell people to r
|
| + 'package:polymer/deploy.dart [options]'); |
| print(parser.getUsage()); |
| } |