Index: sdk/lib/_internal/pub/lib/src/barback.dart |
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..36de8dc664bb995f2ed200a8014b59ab597085e8 |
--- /dev/null |
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart |
@@ -0,0 +1,106 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library pub.barback; |
+ |
+import 'dart:async'; |
+ |
+import 'package:barback/barback.dart'; |
+ |
+import 'barback/load_transformers.dart'; |
+import 'barback/pub_package_provider.dart'; |
+import 'barback/rewrite_import_transformer.dart'; |
+import 'barback/server.dart'; |
+import 'barback/watch_sources.dart'; |
+import 'utils.dart'; |
+ |
+/// Creates a [BarbackServer] serving on [host] and [port]. |
+/// |
+/// This transforms and serves all library and asset files in all packages in |
+/// [graph]. It loads any transformer plugins defined in packages in [graph] and |
+/// re-runs them as necessary when any input files change. |
+Future<BarbackServer> createServer(String host, int port, PackageGraph graph) { |
+ var provider = new PubPackageProvider(graph); |
+ var barback = new Barback(provider); |
+ return BarbackServer.bind(host, port, barback, graph.entrypoint.root.name) |
+ .then((server) { |
+ watchSources(graph, barback); |
+ |
+ var completer = new Completer(); |
+ |
+ // If any errors get emitted either by barback or by the server, including |
+ // non-programmatic barback errors, they should take down the whole program. |
+ var subscriptions = [ |
+ server.barback.errors.listen((error) { |
+ if (error is TransformerException) error = error.error; |
+ if (!completer.isCompleted) completer.completeError(error); |
+ }), |
+ server.barback.results.listen((_) {}, onError: (error) { |
+ if (!completer.isCompleted) completer.completeError(error); |
+ }), |
+ server.results.listen((_) {}, onError: (error) { |
+ if (!completer.isCompleted) completer.completeError(error); |
+ }) |
+ ]; |
+ |
+ _loadTransformers(server, graph).then((_) { |
+ if (!completer.isCompleted) completer.complete(server); |
+ }).catchError((error) { |
+ if (!completer.isCompleted) completer.completeError(error); |
+ }); |
+ |
+ return completer.future.whenComplete(() { |
+ for (var subscription in subscriptions) { |
+ subscription.cancel(); |
+ } |
+ }); |
+ }); |
+} |
+ |
+/// Loads all transformers depended on by packages in [graph]. |
+/// |
+/// This uses [server] to serve the Dart files from which transformers are |
+/// loaded, then adds the transformers to `server.barback`. |
+Future _loadTransformers(BarbackServer server, PackageGraph graph) { |
+ // Add a rewrite transformer for each package, so that we can resolve |
+ // "package:" imports while loading transformers. |
+ var rewrite = new RewriteImportTransformer(); |
+ for (var package in graph.packages.values) { |
+ server.barback.updateTransformers(package.name, [[rewrite]]); |
+ } |
+ |
+ // A map from each transformer id to the set of packages that use it. |
+ var idsToPackages = new Map<AssetId, Set<String>>(); |
+ for (var package in graph.packages.values) { |
+ for (var id in unionAll(package.pubspec.transformers)) { |
+ idsToPackages.putIfAbsent(id, () => new Set<String>()).add(package.name); |
+ } |
+ } |
+ |
+ // TODO(nweiz): support transformers that (possibly transitively) |
+ // depend on other transformers. |
+ var transformersForId = new Map<AssetId, Set<Transformer>>(); |
+ return Future.wait(idsToPackages.keys.map((id) { |
+ return loadTransformers(server, id).then((transformers) { |
+ if (transformers.isEmpty) { |
+ var path = id.path.replaceFirst('lib/', ''); |
+ // Ensure that packages are listed in a deterministic order. |
+ var packages = idsToPackages[id].toList(); |
+ packages.sort(); |
+ throw new ApplicationException( |
+ "No transformers were defined in package:${id.package}/$path,\n" |
+ "required by ${packages.join(', ')}."); |
+ } |
+ |
+ transformersForId[id] = transformers; |
+ }); |
+ })).then((_) { |
+ for (var package in graph.packages.values) { |
+ var phases = package.pubspec.transformers.map((phase) { |
+ return unionAll(phase.map((id) => transformersForId[id])); |
+ }); |
+ server.barback.updateTransformers(package.name, phases); |
+ } |
+ }); |
+} |