Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Unified Diff: sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart

Issue 557563002: Store the async-await compiled pub code directly in the repo. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
diff --git a/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart b/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
new file mode 100644
index 0000000000000000000000000000000000000000..99f15f55c7560a3c4e45ae6f0e9d369b9d87a5e0
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
@@ -0,0 +1,460 @@
+library pub.barback.asset_environment;
+import 'dart:async';
+import 'dart:io';
+import 'package:barback/barback.dart';
+import 'package:path/path.dart' as path;
+import 'package:watcher/watcher.dart';
+import '../entrypoint.dart';
+import '../exceptions.dart';
+import '../io.dart';
+import '../log.dart' as log;
+import '../package.dart';
+import '../package_graph.dart';
+import '../sdk.dart' as sdk;
+import '../source/cached.dart';
+import '../utils.dart';
+import 'admin_server.dart';
+import 'barback_server.dart';
+import 'dart_forwarding_transformer.dart';
+import 'dart2js_transformer.dart';
+import 'load_all_transformers.dart';
+import 'pub_package_provider.dart';
+import 'source_directory.dart';
+class AssetEnvironment {
+ static Future<AssetEnvironment> create(Entrypoint entrypoint,
+ BarbackMode mode, {WatcherType watcherType, String hostname, int basePort,
+ Iterable<String> packages, bool useDart2JS: true}) {
+ if (watcherType == null) watcherType = WatcherType.NONE;
+ if (hostname == null) hostname = "localhost";
+ if (basePort == null) basePort = 0;
+ return entrypoint.loadPackageGraph().then((graph) {
+ log.fine("Loaded package graph.");
+ var barback = new Barback(new PubPackageProvider(graph, packages));
+ barback.log.listen(_log);
+ var environment = new AssetEnvironment._(
+ graph,
+ barback,
+ mode,
+ watcherType,
+ hostname,
+ basePort,
+ packages);
+ return environment._load(useDart2JS: useDart2JS).then((_) => environment);
+ });
+ }
+ AdminServer _adminServer;
+ final _directories = new Map<String, SourceDirectory>();
+ final Barback barback;
+ Package get rootPackage => graph.entrypoint.root;
+ final PackageGraph graph;
+ final BarbackMode mode;
+ final _builtInTransformers = <Transformer>[];
+ final WatcherType _watcherType;
+ final String _hostname;
+ final int _basePort;
+ final Set<String> packages;
+ Set<AssetId> _modifiedSources;
+ AssetEnvironment._(PackageGraph graph, this.barback, this.mode,
+ this._watcherType, this._hostname, this._basePort, Iterable<String> packages)
+ : graph = graph,
+ packages = packages == null ?
+ graph.packages.keys.toSet() :
+ packages.toSet();
+ Iterable<Transformer> getBuiltInTransformers(Package package) {
+ if (package.name != rootPackage.name) return null;
+ if (_builtInTransformers.isEmpty) return null;
+ return _builtInTransformers;
+ }
+ Future<AdminServer> startAdminServer([int port]) {
+ assert(_adminServer == null);
+ if (port == null) port = _basePort == 0 ? 0 : _basePort - 1;
+ return AdminServer.bind(this, _hostname, port).then((server) => _adminServer =
+ server);
+ }
+ Future<BarbackServer> serveDirectory(String rootDirectory) {
+ var directory = _directories[rootDirectory];
+ if (directory != null) {
+ return directory.server.then((server) {
+ log.fine('Already serving $rootDirectory on ${server.url}.');
+ return server;
+ });
+ }
+ var overlapping = _directories.keys.where(
+ (directory) =>
+ path.isWithin(directory, rootDirectory) ||
+ path.isWithin(rootDirectory, directory)).toList();
+ if (overlapping.isNotEmpty) {
+ return new Future.error(
+ new OverlappingSourceDirectoryException(overlapping));
+ }
+ var port = _basePort;
+ if (port != 0) {
+ var boundPorts =
+ _directories.values.map((directory) => directory.port).toSet();
+ while (boundPorts.contains(port)) {
+ port++;
+ }
+ }
+ var sourceDirectory =
+ new SourceDirectory(this, rootDirectory, _hostname, port);
+ _directories[rootDirectory] = sourceDirectory;
+ return _provideDirectorySources(
+ rootPackage,
+ rootDirectory).then((subscription) {
+ sourceDirectory.watchSubscription = subscription;
+ return sourceDirectory.serve();
+ });
+ }
+ Future<BarbackServer> servePackageBinDirectory(String package) {
+ return _provideDirectorySources(
+ graph.packages[package],
+ "bin").then(
+ (_) =>
+ BarbackServer.bind(this, _hostname, 0, package: package, rootDirectory: "bin"));
+ }
+ Future precompileExecutables(String packageName, String directory,
+ {Iterable<AssetId> executableIds}) {
+ if (executableIds == null) {
+ executableIds = graph.packages[packageName].executableIds;
+ }
+ log.fine("executables for $packageName: $executableIds");
+ if (executableIds.isEmpty) return null;
+ var package = graph.packages[packageName];
+ return servePackageBinDirectory(packageName).then((server) {
+ return waitAndPrintErrors(executableIds.map((id) {
+ var basename = path.url.basename(id.path);
+ var snapshotPath = path.join(directory, "$basename.snapshot");
+ return runProcess(
+ Platform.executable,
+ [
+ '--snapshot=$snapshotPath',
+ server.url.resolve(basename).toString()]).then((result) {
+ if (result.success) {
+ log.message("Precompiled ${_formatExecutable(id)}.");
+ } else {
+ deleteEntry(snapshotPath);
+ throw new ApplicationException(
+ log.yellow("Failed to precompile " "${_formatExecutable(id)}:\n") +
+ result.stderr.join('\n'));
+ }
+ });
+ })).whenComplete(() {
+ server.close();
+ });
+ });
+ }
+ String _formatExecutable(AssetId id) =>
+ log.bold("${id.package}:${path.basenameWithoutExtension(id.path)}");
+ Future<Uri> unserveDirectory(String rootDirectory) {
+ log.fine("Unserving $rootDirectory.");
+ var directory = _directories.remove(rootDirectory);
+ if (directory == null) return new Future.value();
+ return directory.server.then((server) {
+ var url = server.url;
+ return directory.close().then((_) {
+ _removeDirectorySources(rootDirectory);
+ return url;
+ });
+ });
+ }
+ String getSourceDirectoryContaining(String assetPath) =>
+ _directories.values.firstWhere(
+ (dir) => path.isWithin(dir.directory, assetPath)).directory;
+ Future<List<Uri>> getUrlsForAssetPath(String assetPath) {
+ return _lookUpPathInServerRoot(assetPath).then((urls) {
+ if (urls.isNotEmpty) return urls;
+ return _lookUpPathInPackagesDirectory(assetPath);
+ }).then((urls) {
+ if (urls.isNotEmpty) return urls;
+ return _lookUpPathInDependency(assetPath);
+ });
+ }
+ Future<List<Uri>> _lookUpPathInServerRoot(String assetPath) {
+ return Future.wait(
+ _directories.values.where(
+ (dir) => path.isWithin(dir.directory, assetPath)).map((dir) {
+ var relativePath = path.relative(assetPath, from: dir.directory);
+ return dir.server.then(
+ (server) => server.url.resolveUri(path.toUri(relativePath)));
+ }));
+ }
+ Future<List<Uri>> _lookUpPathInPackagesDirectory(String assetPath) {
+ var components = path.split(path.relative(assetPath));
+ if (components.first != "packages") return new Future.value([]);
+ if (!packages.contains(components[1])) return new Future.value([]);
+ return Future.wait(_directories.values.map((dir) {
+ return dir.server.then(
+ (server) => server.url.resolveUri(path.toUri(assetPath)));
+ }));
+ }
+ Future<List<Uri>> _lookUpPathInDependency(String assetPath) {
+ for (var packageName in packages) {
+ var package = graph.packages[packageName];
+ var libDir = path.join(package.dir, 'lib');
+ var assetDir = path.join(package.dir, 'asset');
+ var uri;
+ if (path.isWithin(libDir, assetPath)) {
+ uri = path.toUri(
+ path.join('packages', package.name, path.relative(assetPath, from: libDir)));
+ } else if (path.isWithin(assetDir, assetPath)) {
+ uri = path.toUri(
+ path.join('assets', package.name, path.relative(assetPath, from: assetDir)));
+ } else {
+ continue;
+ }
+ return Future.wait(_directories.values.map((dir) {
+ return dir.server.then((server) => server.url.resolveUri(uri));
+ }));
+ }
+ return new Future.value([]);
+ }
+ Future<AssetId> getAssetIdForUrl(Uri url) {
+ return Future.wait(
+ _directories.values.map((dir) => dir.server)).then((servers) {
+ var server = servers.firstWhere((server) {
+ if (server.port != url.port) return false;
+ return isLoopback(server.address.host) == isLoopback(url.host) ||
+ server.address.host == url.host;
+ }, orElse: () => null);
+ if (server == null) return null;
+ return server.urlToId(url);
+ });
+ }
+ bool containsPath(String sourcePath) {
+ var directories = ["lib"];
+ directories.addAll(_directories.keys);
+ return directories.any((dir) => path.isWithin(dir, sourcePath));
+ }
+ void pauseUpdates() {
+ assert(_modifiedSources == null);
+ _modifiedSources = new Set<AssetId>();
+ }
+ void resumeUpdates() {
+ assert(_modifiedSources != null);
+ barback.updateSources(_modifiedSources);
+ _modifiedSources = null;
+ }
+ Future _load({bool useDart2JS}) {
+ return log.progress("Initializing barback", () {
+ var containsDart2JS = graph.entrypoint.root.pubspec.transformers.any(
+ (transformers) =>
+ transformers.any((config) => config.id.package == '\$dart2js'));
+ if (!containsDart2JS && useDart2JS) {
+ _builtInTransformers.addAll(
+ [new Dart2JSTransformer(this, mode), new DartForwardingTransformer(mode)]);
+ }
+ var dartPath = assetPath('dart');
+ var pubSources = listDir(
+ dartPath,
+ recursive: true).where(
+ (file) => path.extension(file) == ".dart").map((library) {
+ var idPath = path.join('lib', path.relative(library, from: dartPath));
+ return new AssetId('\$pub', path.toUri(idPath).toString());
+ });
+ var libPath = path.join(sdk.rootDirectory, "lib");
+ var sdkSources = listDir(
+ libPath,
+ recursive: true).where((file) => path.extension(file) == ".dart").map((file) {
+ var idPath =
+ path.join("lib", path.relative(file, from: sdk.rootDirectory));
+ return new AssetId('\$sdk', path.toUri(idPath).toString());
+ });
+ var transformerServer;
+ return BarbackServer.bind(this, _hostname, 0).then((server) {
+ transformerServer = server;
+ var errorStream = barback.errors.map((error) {
+ if (error is! AssetLoadException) throw error;
+ log.error(log.red(error.message));
+ log.fine(error.stackTrace.terse);
+ });
+ return _withStreamErrors(() {
+ return log.progress("Loading source assets", () {
+ barback.updateSources(pubSources);
+ barback.updateSources(sdkSources);
+ return _provideSources();
+ });
+ }, [errorStream, barback.results]);
+ }).then((_) {
+ log.fine("Provided sources.");
+ var completer = new Completer();
+ var errorStream = barback.errors.map((error) {
+ if (error is! TransformerException) throw error;
+ var message = error.error.toString();
+ if (error.stackTrace != null) {
+ message += "\n" + error.stackTrace.terse.toString();
+ }
+ _log(
+ new LogEntry(
+ error.transform,
+ error.transform.primaryId,
+ LogLevel.ERROR,
+ message,
+ null));
+ });
+ return _withStreamErrors(() {
+ return log.progress("Loading transformers", () {
+ return loadAllTransformers(
+ this,
+ transformerServer).then((_) => transformerServer.close());
+ }, fine: true);
+ }, [errorStream, barback.results, transformerServer.results]);
+ }).then((_) => barback.removeSources(pubSources));
+ }, fine: true);
+ }
+ Future _provideSources() {
+ return Future.wait(packages.map((package) {
+ return _provideDirectorySources(graph.packages[package], "lib");
+ }));
+ }
+ Future<StreamSubscription<WatchEvent>>
+ _provideDirectorySources(Package package, String dir) {
+ log.fine("Providing sources for ${package.name}|$dir.");
+ if (_watcherType == WatcherType.NONE) {
+ _updateDirectorySources(package, dir);
+ return new Future.value();
+ }
+ return _watchDirectorySources(package, dir).then((_) {
+ _updateDirectorySources(package, dir);
+ });
+ }
+ void _updateDirectorySources(Package package, String dir) {
+ var ids = _listDirectorySources(package, dir);
+ if (_modifiedSources == null) {
+ barback.updateSources(ids);
+ } else {
+ _modifiedSources.addAll(ids);
+ }
+ }
+ void _removeDirectorySources(String dir) {
+ var ids = _listDirectorySources(rootPackage, dir);
+ if (_modifiedSources == null) {
+ barback.removeSources(ids);
+ } else {
+ _modifiedSources.removeAll(ids);
+ }
+ }
+ Iterable<AssetId> _listDirectorySources(Package package, String dir) {
+ var subdirectory = path.join(package.dir, dir);
+ if (!dirExists(subdirectory)) return [];
+ return package.listFiles(beneath: subdirectory).map((file) {
+ var relative = path.relative(file, from: package.dir);
+ if (Platform.operatingSystem == 'windows') {
+ relative = relative.replaceAll("\\", "/");
+ }
+ var uri = new Uri(pathSegments: relative.split("/"));
+ return new AssetId(package.name, uri.toString());
+ });
+ }
+ Future<StreamSubscription<WatchEvent>> _watchDirectorySources(Package package,
+ String dir) {
+ var packageId = graph.lockFile.packages[package.name];
+ if (packageId != null &&
+ graph.entrypoint.cache.sources[packageId.source] is CachedSource) {
+ return new Future.value();
+ }
+ var subdirectory = path.join(package.dir, dir);
+ if (!dirExists(subdirectory)) return new Future.value();
+ var watcher = _watcherType.create(subdirectory);
+ var subscription = watcher.events.listen((event) {
+ var parts = path.split(event.path);
+ if (parts.contains("packages")) return;
+ if (event.path.endsWith(".dart.js")) return;
+ if (event.path.endsWith(".dart.js.map")) return;
+ if (event.path.endsWith(".dart.precompiled.js")) return;
+ var idPath = path.relative(event.path, from: package.dir);
+ var id = new AssetId(package.name, path.toUri(idPath).toString());
+ if (event.type == ChangeType.REMOVE) {
+ if (_modifiedSources != null) {
+ _modifiedSources.remove(id);
+ } else {
+ barback.removeSources([id]);
+ }
+ } else if (_modifiedSources != null) {
+ _modifiedSources.add(id);
+ } else {
+ barback.updateSources([id]);
+ }
+ });
+ return watcher.ready.then((_) => subscription);
+ }
+ Future _withStreamErrors(Future futureCallback(), List<Stream> streams) {
+ var completer = new Completer.sync();
+ var subscriptions = streams.map(
+ (stream) => stream.listen((_) {}, onError: completer.complete)).toList();
+ syncFuture(futureCallback).then((_) {
+ if (!completer.isCompleted) completer.complete();
+ }).catchError((error, stackTrace) {
+ if (!completer.isCompleted) completer.completeError(error, stackTrace);
+ });
+ return completer.future.whenComplete(() {
+ for (var subscription in subscriptions) {
+ subscription.cancel();
+ }
+ });
+ }
+}
+void _log(LogEntry entry) {
+ messageMentions(text) =>
+ entry.message.toLowerCase().contains(text.toLowerCase());
+ messageMentionsAsset(id) =>
+ messageMentions(id.toString()) ||
+ messageMentions(path.fromUri(entry.assetId.path));
+ var prefixParts = [];
+ if (!messageMentions(entry.level.name)) {
+ prefixParts.add("${entry.level} from");
+ }
+ prefixParts.add(entry.transform.transformer);
+ if (!messageMentionsAsset(entry.transform.primaryId)) {
+ prefixParts.add("on ${entry.transform.primaryId}");
+ }
+ if (entry.assetId != entry.transform.primaryId &&
+ !messageMentionsAsset(entry.assetId)) {
+ prefixParts.add("with input ${entry.assetId}");
+ }
+ var prefix = "[${prefixParts.join(' ')}]:";
+ var message = entry.message;
+ if (entry.span != null) {
+ message = entry.span.message(entry.message);
+ }
+ switch (entry.level) {
+ case LogLevel.ERROR:
+ log.error("${log.red(prefix)}\n$message");
+ break;
+ case LogLevel.WARNING:
+ log.warning("${log.yellow(prefix)}\n$message");
+ break;
+ case LogLevel.INFO:
+ log.message("${log.cyan(prefix)}\n$message");
+ break;
+ case LogLevel.FINE:
+ log.fine("${log.gray(prefix)}\n$message");
+ break;
+ }
+}
+class OverlappingSourceDirectoryException implements Exception {
+ final List<String> overlappingDirectories;
+ OverlappingSourceDirectoryException(this.overlappingDirectories);
+}
+abstract class WatcherType {
+ static const AUTO = const _AutoWatcherType();
+ static const POLLING = const _PollingWatcherType();
+ static const NONE = const _NoneWatcherType();
+ DirectoryWatcher create(String directory);
+ String toString();
+}
+class _AutoWatcherType implements WatcherType {
+ const _AutoWatcherType();
+ DirectoryWatcher create(String directory) => new DirectoryWatcher(directory);
+ String toString() => "auto";
+}
+class _PollingWatcherType implements WatcherType {
+ const _PollingWatcherType();
+ DirectoryWatcher create(String directory) =>
+ new PollingDirectoryWatcher(directory);
+ String toString() => "polling";
+}
+class _NoneWatcherType implements WatcherType {
+ const _NoneWatcherType();
+ DirectoryWatcher create(String directory) => null;
+ String toString() => "none";
+}

Powered by Google App Engine
This is Rietveld 408576698