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

Unified Diff: sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart

Issue 657673002: Regenerate pub sources. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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/entrypoint.dart
diff --git a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
index eadf9a997c76aec1888035644eb5d7fcd0ff9d6b..58498435690fcff2a053983daf72ebb67f4cfc11 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
@@ -1,7 +1,14 @@
+// Copyright (c) 2012, 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.entrypoint;
+
import 'dart:async';
+
import 'package:path/path.dart' as path;
import 'package:barback/barback.dart';
+
import 'barback/asset_environment.dart';
import 'io.dart';
import 'lock_file.dart';
@@ -13,31 +20,96 @@ import 'solver/version_solver.dart';
import 'source/cached.dart';
import 'system_cache.dart';
import 'utils.dart';
+
+/// The context surrounding the root package pub is operating on.
+///
+/// Pub operates over a directed graph of dependencies that starts at a root
+/// "entrypoint" package. This is typically the package where the current
+/// working directory is located. An entrypoint knows the [root] package it is
+/// associated with and is responsible for managing the "packages" directory
+/// for it.
+///
+/// That directory contains symlinks to all packages used by an app. These links
+/// point either to the [SystemCache] or to some other location on the local
+/// filesystem.
+///
+/// While entrypoints are typically applications, a pure library package may end
+/// up being used as an entrypoint. Also, a single package may be used as an
+/// entrypoint in one context but not in another. For example, a package that
+/// contains a reusable library may not be the entrypoint when used by an app,
+/// but may be the entrypoint when you're running its tests.
class Entrypoint {
+ /// The root package this entrypoint is associated with.
final Package root;
+
+ /// The system-wide cache which caches packages that need to be fetched over
+ /// the network.
final SystemCache cache;
+
+ /// Whether to create and symlink a "packages" directory containing links to
+ /// the installed packages.
final bool _packageSymlinks;
+
+ /// The lockfile for the entrypoint.
+ ///
+ /// If not provided to the entrypoint, it will be laoded lazily from disc.
LockFile _lockFile;
+
+ /// The graph of all packages reachable from the entrypoint.
PackageGraph _packageGraph;
+
+ /// Loads the entrypoint from a package at [rootDir].
+ ///
+ /// If [packageSymlinks] is `true`, this will create a "packages" directory
+ /// with symlinks to the installed packages. This directory will be symlinked
+ /// into any directory that might contain an entrypoint.
Entrypoint(String rootDir, SystemCache cache, {bool packageSymlinks: true})
: root = new Package.load(null, rootDir, cache.sources),
cache = cache,
_packageSymlinks = packageSymlinks;
+
+ /// Creates an entrypoint given package and lockfile objects.
Entrypoint.inMemory(this.root, this._lockFile, this.cache)
: _packageSymlinks = false;
+
+ /// The path to the entrypoint's "packages" directory.
String get packagesDir => root.path('packages');
+
+ /// `true` if the entrypoint package currently has a lock file.
bool get lockFileExists => _lockFile != null || entryExists(lockFilePath);
+
LockFile get lockFile {
if (_lockFile != null) return _lockFile;
+
if (!lockFileExists) {
_lockFile = new LockFile.empty();
} else {
_lockFile = new LockFile.load(lockFilePath, cache.sources);
}
+
return _lockFile;
}
+
+ /// The path to the entrypoint package's pubspec.
String get pubspecPath => root.path('pubspec.yaml');
+
+ /// The path to the entrypoint package's lockfile.
String get lockFilePath => root.path('pubspec.lock');
+
+ /// Gets all dependencies of the [root] package.
+ ///
+ /// Performs version resolution according to [SolveType].
+ ///
+ /// [useLatest], if provided, defines a list of packages that will be
+ /// unlocked and forced to their latest versions. If [upgradeAll] is
+ /// true, the previous lockfile is ignored and all packages are re-resolved
+ /// from scratch. Otherwise, it will attempt to preserve the versions of all
+ /// previously locked packages.
+ ///
+ /// Shows a report of the changes made relative to the previous lockfile. If
+ /// this is an upgrade or downgrade, all transitive dependencies are shown in
+ /// the report. Otherwise, only dependencies that were changed are shown. If
+ /// [dryRun] is `true`, no physical changes are made.
Future acquireDependencies(SolveType type, {List<String> useLatest,
bool dryRun: false}) {
final completer0 = new Completer();
@@ -74,12 +146,10 @@ class Entrypoint {
})).catchError(((error, stackTrace) {
log.exception(error, stackTrace);
})));
- } catch (e2) {
- completer0.completeError(e2);
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e3) {
- completer0.completeError(e3);
- });
+ }, onError: completer0.completeError);
}
if (_packageSymlinks) {
_linkSelf();
@@ -87,12 +157,10 @@ class Entrypoint {
} else {
join3();
}
- } catch (e1) {
- completer0.completeError(e1);
+ } catch (e1, s1) {
+ completer0.completeError(e1, s1);
}
- }, onError: (e4) {
- completer0.completeError(e4);
- });
+ }, onError: completer0.completeError);
}
if (_packageSymlinks) {
cleanDir(packagesDir);
@@ -110,22 +178,26 @@ class Entrypoint {
}
}
if (!result.succeeded) {
- completer0.completeError(result.error);
+ throw result.error;
+ join0();
} else {
join0();
}
- } catch (e0) {
- completer0.completeError(e0);
+ } catch (e2, s2) {
+ completer0.completeError(e2, s2);
}
- }, onError: (e5) {
- completer0.completeError(e5);
- });
- } catch (e6) {
- completer0.completeError(e6);
+ }, onError: completer0.completeError);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
}
+
+ /// Precompile any transformed dependencies of the entrypoint.
+ ///
+ /// If [changed] is passed, only dependencies whose contents might be changed
+ /// if one of the given packages changes will be recompiled.
Future precompileDependencies({Iterable<String> changed}) {
final completer0 = new Completer();
scheduleMicrotask(() {
@@ -145,17 +217,20 @@ class Entrypoint {
graph.transitiveDependencies(
package.name).map((package) => package.name).toSet(),
changed);
- })).map(((package) => package.name)).toSet();
+ })).map(((package) {
+ return package.name;
+ })).toSet();
join1() {
log.progress("Precompiling dependencies", (() {
final completer0 = new Completer();
scheduleMicrotask(() {
try {
var packagesToLoad = unionAll(
- dependenciesToPrecompile.map(
- graph.transitiveDependencies)).map(((package) => package.name)).toSet();
+ dependenciesToPrecompile.map(graph.transitiveDependencies)).map(((package) {
+ return package.name;
+ })).toSet();
var it0 = dependenciesToPrecompile.iterator;
- break0(x4) {
+ break0() {
AssetEnvironment.create(
this,
BarbackMode.DEBUG,
@@ -163,7 +238,8 @@ class Entrypoint {
useDart2JS: false).then((x0) {
try {
var environment = x0;
- environment.barback.errors.listen(((_) {}));
+ environment.barback.errors.listen(((_) {
+ }));
environment.barback.getAllAssets().then((x1) {
try {
var assets = x1;
@@ -180,13 +256,11 @@ class Entrypoint {
destPath).then((x0) {
try {
x0;
- completer0.complete(null);
- } catch (e0) {
- completer0.completeError(e0);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e1) {
- completer0.completeError(e1);
- });
+ }, onError: completer0.completeError);
}
if (!dependenciesToPrecompile.contains(
asset.id.package)) {
@@ -194,8 +268,8 @@ class Entrypoint {
} else {
join0();
}
- } catch (e2) {
- completer0.completeError(e2);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
@@ -206,70 +280,61 @@ class Entrypoint {
"Precompiled " +
toSentence(ordered(dependenciesToPrecompile).map(log.bold)) +
".");
- completer0.complete(null);
- } catch (e2) {
- completer0.completeError(e2);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e3) {
- completer0.completeError(e3);
- });
- } catch (e1) {
- completer0.completeError(e1);
+ }, onError: completer0.completeError);
+ } catch (e1, s1) {
+ completer0.completeError(e1, s1);
}
- }, onError: (e4) {
- completer0.completeError(e4);
- });
- } catch (e0) {
- completer0.completeError(e0);
+ }, onError: completer0.completeError);
+ } catch (e2, s2) {
+ completer0.completeError(e2, s2);
}
- }, onError: (e5) {
- completer0.completeError(e5);
- });
+ }, onError: completer0.completeError);
}
- continue0(x5) {
+ var trampoline0;
+ continue0() {
+ trampoline0 = null;
if (it0.moveNext()) {
- Future.wait([]).then((x3) {
- var package = it0.current;
- deleteEntry(path.join(depsDir, package));
- continue0(null);
- });
+ var package = it0.current;
+ deleteEntry(path.join(depsDir, package));
+ trampoline0 = continue0;
} else {
- break0(null);
+ break0();
}
}
- continue0(null);
- } catch (e6) {
- completer0.completeError(e6);
+ trampoline0 = continue0;
+ do trampoline0(); while (trampoline0 != null);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
})).catchError(((error) {
- for (var package in dependenciesToPrecompile) {
+ for (package in dependenciesToPrecompile) {
deleteEntry(path.join(depsDir, package));
}
throw error;
})).then((x1) {
try {
x1;
- completer0.complete(null);
- } catch (e1) {
- completer0.completeError(e1);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e2) {
- completer0.completeError(e2);
- });
+ }, onError: completer0.completeError);
}
if (dependenciesToPrecompile.isEmpty) {
completer0.complete(null);
} else {
join1();
}
- } catch (e0) {
- completer0.completeError(e0);
+ } catch (e1, s1) {
+ completer0.completeError(e1, s1);
}
- }, onError: (e3) {
- completer0.completeError(e3);
- });
+ }, onError: completer0.completeError);
}
if (changed != null) {
changed = changed.toSet();
@@ -277,12 +342,15 @@ class Entrypoint {
} else {
join0();
}
- } catch (e4) {
- completer0.completeError(e4);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
}
+
+ /// Precompiles all executables from dependencies that don't transitively
+ /// depend on [this] or on a path dependency.
Future precompileExecutables({Iterable<String> changed}) {
final completer0 = new Completer();
scheduleMicrotask(() {
@@ -297,12 +365,14 @@ class Entrypoint {
loadPackageGraph().then((x0) {
try {
var graph = x0;
- var executables = new Map.fromIterable(
- root.immediateDependencies,
- key: ((dep) => dep.name),
- value: ((dep) => _executablesForPackage(graph, dep.name, changed)));
+ var executables =
+ new Map.fromIterable(root.immediateDependencies, key: ((dep) {
+ return dep.name;
+ }), value: ((dep) {
+ return _executablesForPackage(graph, dep.name, changed);
+ }));
var it0 = executables.keys.toList().iterator;
- break0(x3) {
+ break0() {
join2() {
join3() {
log.progress("Precompiling executables", (() {
@@ -311,11 +381,14 @@ class Entrypoint {
try {
ensureDir(binDir);
writeTextFile(sdkVersionPath, "${sdk.version}\n");
- var packagesToLoad = unionAll(
- executables.keys.map(
- graph.transitiveDependencies)).map(((package) => package.name)).toSet();
+ var packagesToLoad =
+ unionAll(executables.keys.map(graph.transitiveDependencies)).map(((package) {
+ return package.name;
+ })).toSet();
var executableIds =
- unionAll(executables.values.map(((ids) => ids.toSet())));
+ unionAll(executables.values.map(((ids) {
+ return ids.toSet();
+ })));
AssetEnvironment.create(
this,
BarbackMode.RELEASE,
@@ -340,49 +413,41 @@ class Entrypoint {
executableIds: executables[package]).then((x0) {
try {
x0;
- completer0.complete(null);
- } catch (e0) {
- completer0.completeError(e0);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e1) {
- completer0.completeError(e1);
- });
- } catch (e2) {
- completer0.completeError(e2);
+ }, onError: completer0.completeError);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
}))).then((x1) {
try {
x1;
- completer0.complete(null);
- } catch (e1) {
- completer0.completeError(e1);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e2) {
- completer0.completeError(e2);
- });
- } catch (e0) {
- completer0.completeError(e0);
+ }, onError: completer0.completeError);
+ } catch (e1, s1) {
+ completer0.completeError(e1, s1);
}
- }, onError: (e3) {
- completer0.completeError(e3);
- });
- } catch (e4) {
- completer0.completeError(e4);
+ }, onError: completer0.completeError);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
})).then((x1) {
try {
x1;
- completer0.complete(null);
- } catch (e1) {
- completer0.completeError(e1);
+ completer0.complete();
+ } catch (e0, s0) {
+ completer0.completeError(e0, s0);
}
- }, onError: (e2) {
- completer0.completeError(e2);
- });
+ }, onError: completer0.completeError);
}
if (executables.isEmpty) {
completer0.complete(null);
@@ -397,31 +462,30 @@ class Entrypoint {
join2();
}
}
- continue0(x4) {
+ var trampoline0;
+ continue0() {
+ trampoline0 = null;
if (it0.moveNext()) {
- Future.wait([]).then((x2) {
- var package = it0.current;
- join4() {
- continue0(null);
- }
- if (executables[package].isEmpty) {
- executables.remove(package);
- join4();
- } else {
- join4();
- }
- });
+ var package = it0.current;
+ join4() {
+ trampoline0 = continue0;
+ }
+ if (executables[package].isEmpty) {
+ executables.remove(package);
+ join4();
+ } else {
+ join4();
+ }
} else {
- break0(null);
+ break0();
}
}
- continue0(null);
- } catch (e0) {
- completer0.completeError(e0);
+ trampoline0 = continue0;
+ do trampoline0(); while (trampoline0 != null);
+ } catch (e1, s1) {
+ completer0.completeError(e1, s1);
}
- }, onError: (e3) {
- completer0.completeError(e3);
- });
+ }, onError: completer0.completeError);
}
if (!sdkMatches) {
changed = null;
@@ -436,24 +500,40 @@ class Entrypoint {
} else {
join0();
}
- } catch (e4) {
- completer0.completeError(e4);
+ } catch (e, s) {
+ completer0.completeError(e, s);
}
});
return completer0.future;
}
+
+ /// Returns the list of all executable assets for [packageName] that should be
+ /// precompiled.
+ ///
+ /// If [changed] isn't `null`, executables for [packageName] will only be
+ /// compiled if they might depend on a package in [changed].
List<AssetId> _executablesForPackage(PackageGraph graph, String packageName,
Set<String> changed) {
var package = graph.packages[packageName];
var binDir = package.path('bin');
if (!dirExists(binDir)) return [];
if (graph.isPackageMutable(packageName)) return [];
+
var executables = package.executableIds;
+
+ // If we don't know which packages were changed, always precompile the
+ // executables.
if (changed == null) return executables;
+
+ // If any of the package's dependencies changed, recompile the executables.
if (graph.transitiveDependencies(
packageName).any((package) => changed.contains(package.name))) {
return executables;
}
+
+ // If any executables doesn't exist, precompile them regardless of what
+ // changed. Since we delete the bin directory before recompiling, we need to
+ // recompile all executables.
var executablesExist = executables.every(
(executable) =>
fileExists(
@@ -463,46 +543,87 @@ class Entrypoint {
packageName,
"${path.url.basename(executable.path)}.snapshot")));
if (!executablesExist) return executables;
+
+ // Otherwise, we don't need to recompile.
return [];
}
+
+ /// Makes sure the package at [id] is locally available.
+ ///
+ /// This automatically downloads the package to the system-wide cache as well
+ /// if it requires network access to retrieve (specifically, if the package's
+ /// source is a [CachedSource]).
Future<PackageId> _get(PackageId id) {
if (id.isRoot) return new Future.value(id);
+
var source = cache.sources[id.source];
return new Future.sync(() {
if (!_packageSymlinks) {
if (source is! CachedSource) return null;
return source.downloadToSystemCache(id);
}
+
var packageDir = path.join(packagesDir, id.name);
if (entryExists(packageDir)) deleteEntry(packageDir);
return source.get(id, packageDir);
}).then((_) => source.resolveId(id));
}
+
+ /// Determines whether or not the lockfile is out of date with respect to the
+ /// pubspec.
+ ///
+ /// This will be `false` if there is no lockfile at all, or if the pubspec
+ /// contains dependencies that are not in the lockfile or that don't match
+ /// what's in there.
bool _isLockFileUpToDate(LockFile lockFile) {
return root.immediateDependencies.every((package) {
var locked = lockFile.packages[package.name];
if (locked == null) return false;
+
if (package.source != locked.source) return false;
if (!package.constraint.allows(locked.version)) return false;
+
var source = cache.sources[package.source];
if (source == null) return false;
+
return source.descriptionsEqual(package.description, locked.description);
});
}
+
+ /// Determines whether all of the packages in the lockfile are already
+ /// installed and available.
+ ///
+ /// Note: this assumes [isLockFileUpToDate] has already been called and
+ /// returned `true`.
Future<bool> _arePackagesAvailable(LockFile lockFile) {
return Future.wait(lockFile.packages.values.map((package) {
var source = cache.sources[package.source];
+
+ // This should only be called after [_isLockFileUpToDate] has returned
+ // `true`, which ensures all of the sources in the lock file are valid.
assert(source != null);
+
+ // We only care about cached sources. Uncached sources aren't "installed".
+ // If one of those is missing, we want to show the user the file not
+ // found error later since installing won't accomplish anything.
if (source is! CachedSource) return new Future.value(true);
+
+ // Get the directory.
return source.getDirectory(package).then((dir) {
+ // See if the directory is there and looks like a package.
return dirExists(dir) || fileExists(path.join(dir, "pubspec.yaml"));
});
})).then((results) {
+ // Make sure they are all true.
return results.every((result) => result);
});
}
+
+ /// Gets dependencies if the lockfile is out of date with respect to the
+ /// pubspec.
Future ensureLockFileIsUpToDate() {
return new Future.sync(() {
+ // If we don't have a current lock file, we definitely need to install.
if (!_isLockFileUpToDate(lockFile)) {
if (lockFileExists) {
log.message(
@@ -511,13 +632,19 @@ class Entrypoint {
log.message(
"You don't have a lockfile, so we need to generate that:");
}
+
return false;
}
+
+ // If we do have a lock file, we still need to make sure the packages
+ // are actually installed. The user may have just gotten a package that
+ // includes a lockfile.
return _arePackagesAvailable(lockFile).then((available) {
if (!available) {
log.message(
"You are missing some dependencies, so we need to install them " "first:");
}
+
return available;
});
}).then((upToDate) {
@@ -525,8 +652,16 @@ class Entrypoint {
return acquireDependencies(SolveType.GET);
});
}
+
+ /// Loads the package graph for the application and all of its transitive
+ /// dependencies.
+ ///
+ /// If [result] is passed, this loads the graph from it without re-parsing the
+ /// lockfile or any pubspecs. Otherwise, before loading, this makes sure the
+ /// lockfile and dependencies are installed and up to date.
Future<PackageGraph> loadPackageGraph([SolveResult result]) {
if (_packageGraph != null) return new Future.value(_packageGraph);
+
return new Future.sync(() {
if (result != null) {
return Future.wait(result.packages.map((id) {
@@ -556,13 +691,19 @@ class Entrypoint {
return graph;
});
}
+
+ /// Saves a list of concrete package versions to the `pubspec.lock` file.
void _saveLockFile(List<PackageId> packageIds) {
_lockFile = new LockFile(packageIds);
var lockFilePath = root.path('pubspec.lock');
writeTextFile(lockFilePath, _lockFile.serialize(root.dir, cache.sources));
}
+
+ /// Creates a self-referential symlink in the `packages` directory that allows
+ /// a package to import its own files using `package:`.
void _linkSelf() {
var linkPath = path.join(packagesDir, root.name);
+ // Create the symlink if it doesn't exist.
if (entryExists(linkPath)) return;
ensureDir(packagesDir);
createPackageSymlink(
@@ -572,19 +713,39 @@ class Entrypoint {
isSelfLink: true,
relative: true);
}
+
+ /// If [packageSymlinks] is true, add "packages" directories to the whitelist
+ /// of directories that may contain Dart entrypoints.
+ ///
+ /// Otherwise, delete any "packages" directories in the whitelist of
+ /// directories that may contain Dart entrypoints.
void _linkOrDeleteSecondaryPackageDirs() {
+ // Only the main "bin" directory gets a "packages" directory, not its
+ // subdirectories.
var binDir = root.path('bin');
if (dirExists(binDir)) _linkOrDeleteSecondaryPackageDir(binDir);
+
+ // The others get "packages" directories in subdirectories too.
for (var dir in ['benchmark', 'example', 'test', 'tool', 'web']) {
_linkOrDeleteSecondaryPackageDirsRecursively(root.path(dir));
}
}
+
+ /// If [packageSymlinks] is true, creates a symlink to the "packages"
+ /// directory in [dir] and all its subdirectories.
+ ///
+ /// Otherwise, deletes any "packages" directories in [dir] and all its
+ /// subdirectories.
void _linkOrDeleteSecondaryPackageDirsRecursively(String dir) {
if (!dirExists(dir)) return;
_linkOrDeleteSecondaryPackageDir(dir);
_listDirWithoutPackages(
dir).where(dirExists).forEach(_linkOrDeleteSecondaryPackageDir);
}
+
+ // TODO(nweiz): roll this into [listDir] in io.dart once issue 4775 is fixed.
+ /// Recursively lists the contents of [dir], excluding hidden `.DS_Store`
+ /// files and `package` files.
List<String> _listDirWithoutPackages(dir) {
return flatten(listDir(dir).map((file) {
if (path.basename(file) == 'packages') return [];
@@ -594,6 +755,11 @@ class Entrypoint {
return fileAndSubfiles;
}));
}
+
+ /// If [packageSymlinks] is true, creates a symlink to the "packages"
+ /// directory in [dir].
+ ///
+ /// Otherwise, deletes a "packages" directories in [dir] if one exists.
void _linkOrDeleteSecondaryPackageDir(String dir) {
var symlink = path.join(dir, 'packages');
if (entryExists(symlink)) deleteEntry(symlink);
« no previous file with comments | « sdk/lib/_internal/pub_generated/lib/src/dart.dart ('k') | sdk/lib/_internal/pub_generated/lib/src/error_group.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698