OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, 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 library pub.barback; |
| 6 |
| 7 import 'dart:async'; |
| 8 |
| 9 import 'package:barback/barback.dart'; |
| 10 |
| 11 import 'barback/load_transformers.dart'; |
| 12 import 'barback/pub_package_provider.dart'; |
| 13 import 'barback/rewrite_import_transformer.dart'; |
| 14 import 'barback/server.dart'; |
| 15 import 'barback/watch_sources.dart'; |
| 16 import 'utils.dart'; |
| 17 |
| 18 /// Creates a [BarbackServer] serving on [host] and [port]. |
| 19 /// |
| 20 /// This transforms and serves all library and asset files in all packages in |
| 21 /// [graph]. It loads any transformer plugins defined in packages in [graph] and |
| 22 /// re-runs them as necessary when any input files change. |
| 23 Future<BarbackServer> createServer(String host, int port, PackageGraph graph) { |
| 24 var provider = new PubPackageProvider(graph); |
| 25 var barback = new Barback(provider); |
| 26 return BarbackServer.bind(host, port, barback, graph.entrypoint.root.name) |
| 27 .then((server) { |
| 28 watchSources(graph, barback); |
| 29 |
| 30 var completer = new Completer(); |
| 31 |
| 32 // If any errors get emitted either by barback or by the server, including |
| 33 // non-programmatic barback errors, they should take down the whole program. |
| 34 var subscriptions = [ |
| 35 server.barback.errors.listen((error) { |
| 36 if (error is TransformerException) error = error.error; |
| 37 if (!completer.isCompleted) completer.completeError(error); |
| 38 }), |
| 39 server.barback.results.listen((_) {}, onError: (error) { |
| 40 if (!completer.isCompleted) completer.completeError(error); |
| 41 }), |
| 42 server.results.listen((_) {}, onError: (error) { |
| 43 if (!completer.isCompleted) completer.completeError(error); |
| 44 }) |
| 45 ]; |
| 46 |
| 47 _loadTransformers(server, graph).then((_) { |
| 48 if (!completer.isCompleted) completer.complete(server); |
| 49 }).catchError((error) { |
| 50 if (!completer.isCompleted) completer.completeError(error); |
| 51 }); |
| 52 |
| 53 return completer.future.whenComplete(() { |
| 54 for (var subscription in subscriptions) { |
| 55 subscription.cancel(); |
| 56 } |
| 57 }); |
| 58 }); |
| 59 } |
| 60 |
| 61 /// Loads all transformers depended on by packages in [graph]. |
| 62 /// |
| 63 /// This uses [server] to serve the Dart files from which transformers are |
| 64 /// loaded, then adds the transformers to `server.barback`. |
| 65 Future _loadTransformers(BarbackServer server, PackageGraph graph) { |
| 66 // Add a rewrite transformer for each package, so that we can resolve |
| 67 // "package:" imports while loading transformers. |
| 68 var rewrite = new RewriteImportTransformer(); |
| 69 for (var package in graph.packages.values) { |
| 70 server.barback.updateTransformers(package.name, [[rewrite]]); |
| 71 } |
| 72 |
| 73 // A map from each transformer id to the set of packages that use it. |
| 74 var idsToPackages = new Map<AssetId, Set<String>>(); |
| 75 for (var package in graph.packages.values) { |
| 76 for (var id in unionAll(package.pubspec.transformers)) { |
| 77 idsToPackages.putIfAbsent(id, () => new Set<String>()).add(package.name); |
| 78 } |
| 79 } |
| 80 |
| 81 // TODO(nweiz): support transformers that (possibly transitively) |
| 82 // depend on other transformers. |
| 83 var transformersForId = new Map<AssetId, Set<Transformer>>(); |
| 84 return Future.wait(idsToPackages.keys.map((id) { |
| 85 return loadTransformers(server, id).then((transformers) { |
| 86 if (transformers.isEmpty) { |
| 87 var path = id.path.replaceFirst('lib/', ''); |
| 88 // Ensure that packages are listed in a deterministic order. |
| 89 var packages = idsToPackages[id].toList(); |
| 90 packages.sort(); |
| 91 throw new ApplicationException( |
| 92 "No transformers were defined in package:${id.package}/$path,\n" |
| 93 "required by ${packages.join(', ')}."); |
| 94 } |
| 95 |
| 96 transformersForId[id] = transformers; |
| 97 }); |
| 98 })).then((_) { |
| 99 for (var package in graph.packages.values) { |
| 100 var phases = package.pubspec.transformers.map((phase) { |
| 101 return unionAll(phase.map((id) => transformersForId[id])); |
| 102 }); |
| 103 server.barback.updateTransformers(package.name, phases); |
| 104 } |
| 105 }); |
| 106 } |
OLD | NEW |