| Index: sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
|
| diff --git a/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart b/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
|
| index af2eae8c906043bad774c0258d8914ed871e643a..2870349dbe90d3c77519faef7b559f9395f26d71 100644
|
| --- a/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
|
| +++ b/sdk/lib/_internal/pub/lib/src/barback/build_environment.dart
|
| @@ -33,10 +33,16 @@ class BuildEnvironment {
|
| /// Creates a new build environment for working with the assets used by
|
| /// [entrypoint] and its dependencies.
|
| ///
|
| - /// Spawns an HTTP server on [hostname] and [port]. Loads all used
|
| - /// transformers using [mode] (including dart2js if [useDart2JS] is true).
|
| + /// Spawns an HTTP server for each directory in [rootDirectories]. These
|
| + /// servers will be on [hostname] and have ports based on [basePort].
|
| + /// [basePort] itself is reserved for "web/" and `basePort + 1` is reserved
|
| + /// for "test/"; further ports will be allocated for other root directories as
|
| + /// necessary. If [basePort] is zero, each server will have an ephemeral port.
|
| ///
|
| - /// Includes [buildDirectories] in the root package, as well as "lib" and
|
| + /// Loads all used transformers using [mode] (including dart2js if
|
| + /// [useDart2JS] is true).
|
| + ///
|
| + /// Includes [rootDirectories] in the root package, as well as "lib" and
|
| /// "asset".
|
| ///
|
| /// If [watcherType] is not [WatcherType.NONE], watches source assets for
|
| @@ -45,17 +51,17 @@ class BuildEnvironment {
|
| /// Returns a [Future] that completes to the environment once the inputs,
|
| /// transformers, and server are loaded and ready.
|
| static Future<BuildEnvironment> create(Entrypoint entrypoint,
|
| - String hostname, int port, BarbackMode mode, WatcherType watcherType,
|
| - Set<String> buildDirectories,
|
| + String hostname, int basePort, BarbackMode mode, WatcherType watcherType,
|
| + Iterable<String> rootDirectories,
|
| {bool useDart2JS: true}) {
|
| return entrypoint.loadPackageGraph().then((graph) {
|
| var barback = new Barback(new PubPackageProvider(graph));
|
| barback.log.listen(_log);
|
|
|
| - return BarbackServer.bind(hostname, port, barback,
|
| - graph.entrypoint.root.name).then((server) {
|
| - var environment = new BuildEnvironment._(graph, server, mode,
|
| - watcherType, buildDirectories);
|
| + return _startServers(hostname, basePort, mode, graph, barback,
|
| + rootDirectories).then((servers) {
|
| + var environment = new BuildEnvironment._(graph, servers, mode,
|
| + watcherType, rootDirectories);
|
|
|
| // If the entrypoint package manually configures the dart2js
|
| // transformer, don't include it in the built-in transformer list.
|
| @@ -78,11 +84,43 @@ class BuildEnvironment {
|
| });
|
| }
|
|
|
| - /// The server serving this environment's assets.
|
| - final BarbackServer server;
|
| + /// Start the [BarbackServer]s that will serve [rootDirectories].
|
| + static Future<List<BarbackServer>> _startServers(String hostname,
|
| + int basePort, BarbackMode mode, PackageGraph graph, Barback barback,
|
| + Iterable<String> rootDirectories) {
|
| + _bind(port, rootDirectory) {
|
| + if (basePort == 0) port = 0;
|
| + return BarbackServer.bind(hostname, port, barback,
|
| + graph.entrypoint.root.name, rootDirectory);
|
| + }
|
| +
|
| + rootDirectories = rootDirectories.toList();
|
| +
|
| + // For consistency, "web/" should always have the first available port and
|
| + // "test/" should always have the second. Other directories are assigned
|
| + // the following ports in alphabetical order.
|
| + var serverFutures = [];
|
| + if (rootDirectories.remove('web')) {
|
| + serverFutures.add(_bind(basePort, 'web'));
|
| + }
|
| + if (rootDirectories.remove('test')) {
|
| + serverFutures.add(_bind(basePort + 1, 'test'));
|
| + }
|
| +
|
| + var i = 0;
|
| + for (var dir in rootDirectories) {
|
| + serverFutures.add(_bind(basePort + 2 + i, dir));
|
| + i += 1;
|
| + }
|
| +
|
| + return Future.wait(serverFutures);
|
| + }
|
| +
|
| + /// The servers serving this environment's assets.
|
| + final List<BarbackServer> servers;
|
|
|
| /// The [Barback] instance used to process assets in this environment.
|
| - Barback get barback => server.barback;
|
| + Barback get barback => servers.first.barback;
|
|
|
| /// The root package being built.
|
| Package get rootPackage => graph.entrypoint.root;
|
| @@ -100,12 +138,13 @@ class BuildEnvironment {
|
| /// How source files should be watched.
|
| final WatcherType _watcherType;
|
|
|
| - /// The set of top-level directories in the entrypoint package that should be
|
| - /// built.
|
| - final Set<String> _buildDirectories;
|
| + /// The set of top-level directories in the entrypoint package that will be
|
| + /// exposed.
|
| + final Set<String> _rootDirectories;
|
|
|
| - BuildEnvironment._(this.graph, this.server, this.mode, this._watcherType,
|
| - this._buildDirectories);
|
| + BuildEnvironment._(this.graph, this.servers, this.mode, this._watcherType,
|
| + Iterable<String> rootDirectories)
|
| + : _rootDirectories = rootDirectories.toSet();
|
|
|
| /// Gets the built-in [Transformer]s that should be added to [package].
|
| ///
|
| @@ -121,7 +160,7 @@ class BuildEnvironment {
|
| return _builtInTransformers;
|
| }
|
|
|
| - /// Creates a [BarbackServer] for this environment.
|
| + /// Loads the assets and transformers for this environment.
|
| ///
|
| /// This transforms and serves all library and asset files in all packages in
|
| /// the environment's package graph. It loads any transformer plugins defined
|
| @@ -134,21 +173,24 @@ class BuildEnvironment {
|
| return _provideSources(barback).then((_) {
|
| var completer = new Completer();
|
|
|
| - // If any errors get emitted either by barback or by the server,
|
| + // If any errors get emitted either by barback or by the primary server,
|
| // including non-programmatic barback errors, they should take down the
|
| // whole program.
|
| var subscriptions = [
|
| - server.barback.errors.listen((error) {
|
| + barback.errors.listen((error) {
|
| if (error is TransformerException) error = error.error;
|
| if (!completer.isCompleted) {
|
| completer.completeError(error, new Chain.current());
|
| }
|
| }),
|
| - server.barback.results.listen((_) {}, onError: (error, stackTrace) {
|
| + barback.results.listen((_) {},
|
| + onError: (error, stackTrace) {
|
| if (completer.isCompleted) return;
|
| completer.completeError(error, stackTrace);
|
| }),
|
| - server.results.listen((_) {}, onError: (error, stackTrace) {
|
| + // We only listen to the first server here because that's the one used
|
| + // to initialize all the transformers during the initial load.
|
| + servers.first.results.listen((_) {}, onError: (error, stackTrace) {
|
| if (completer.isCompleted) return;
|
| completer.completeError(error, stackTrace);
|
| })
|
| @@ -296,7 +338,7 @@ class BuildEnvironment {
|
| var directories = ["asset", "lib"];
|
|
|
| if (package.name == entrypoint.root.name) {
|
| - directories.addAll(_buildDirectories);
|
| + directories.addAll(_rootDirectories);
|
| }
|
|
|
| return directories;
|
|
|