| 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()); | 
| } | 
|  |