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

Unified Diff: lib/src/entrypoint.dart

Issue 1534093002: Improve the detection lockfile freshness. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | lib/src/global_packages.dart » ('j') | lib/src/lock_file.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/entrypoint.dart
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart
index 507b12cc3956b41636f2306a081717a03fc8d613..fad67e63d7b71906414ddba6b8e5427aedb70809 100644
--- a/lib/src/entrypoint.dart
+++ b/lib/src/entrypoint.dart
@@ -7,9 +7,10 @@ library pub.entrypoint;
import 'dart:async';
import 'dart:io';
+import 'package:barback/barback.dart';
import 'package:package_config/packages_file.dart' as packages_file;
import 'package:path/path.dart' as p;
-import 'package:barback/barback.dart';
+import 'package:pub_semver/pub_semver.dart';
import 'barback/asset_environment.dart';
import 'io.dart';
@@ -20,9 +21,13 @@ import 'package_graph.dart';
import 'sdk.dart' as sdk;
import 'solver/version_solver.dart';
import 'source/cached.dart';
+import 'source/unknown.dart';
import 'system_cache.dart';
import 'utils.dart';
+/// A RegExp to match the SDK constraint in a lock file.
+final _sdkConstraint = new RegExp(r'^sdk: "?([^"]*)"?$', multiLine: true);
+
/// The context surrounding the root package pub is operating on.
///
/// Pub operates over a directed graph of dependencies that starts at a root
@@ -86,10 +91,7 @@ class Entrypoint {
assertUpToDate();
var packages = new Map.fromIterable(lockFile.packages.values,
key: (id) => id.name,
- value: (id) {
- var dir = cache.sources[id.source].getDirectory(id);
- return new Package.load(id.name, dir, cache.sources);
- });
+ value: (id) => cache.sources.load(id));
packages[root.name] = root;
_packageGraph = new PackageGraph(this, lockFile, packages);
@@ -174,7 +176,7 @@ class Entrypoint {
}
await Future.wait(result.packages.map(_get));
- _saveLockFile(result.packages);
+ _saveLockFile(result);
if (_packageSymlinks) _linkSelf();
_linkOrDeleteSecondaryPackageDirs();
@@ -420,11 +422,17 @@ class Entrypoint {
dataError('No .packages file found, please run "pub get" first.');
}
+ // Manually parse the lockfile because a full YAML parse is relatively slow
+ // and this is on the hot path for "pub run".
+ var lockFileText = readTextFile(lockFilePath);
+ var hasPathDependencies = lockFileText.contains("\n source: path\n");
Bob Nystrom 2015/12/21 20:55:03 This feels really sketchy to me. We don't for cert
nweiz 2016/01/04 23:27:29 Discussed offline.
+
var pubspecModified = new File(pubspecPath).lastModifiedSync();
var lockFileModified = new File(lockFilePath).lastModifiedSync();
var touchedLockFile = false;
- if (lockFileModified.isBefore(pubspecModified)) {
+ if (lockFileModified.isBefore(pubspecModified) ||
+ hasPathDependencies) {
if (_isLockFileUpToDate() && _arePackagesAvailable()) {
touchedLockFile = true;
touch(lockFilePath);
@@ -445,41 +453,60 @@ class Entrypoint {
} else if (touchedLockFile) {
touch(packagesFile);
}
+
+ var sdkConstraint = _sdkConstraint.firstMatch(lockFileText);
+ if (sdkConstraint != null) {
+ var parsedConstraint = new VersionConstraint.parse(sdkConstraint[1]);
+ if (!parsedConstraint.allows(sdk.version)) {
+ dataError("Dart ${sdk.version} is incompatible with your dependencies' "
+ "SDK constraints. Please run \"pub get\" again.");
+ }
+ }
}
/// Determines whether or not the lockfile is out of date with respect to the
/// pubspec.
///
- /// This will be `false` if the pubspec contains dependencies that are not in
- /// the lockfile or that don't match what's in there.
+ /// This will be `false` if any mutable pubspec contains dependencies that are
+ /// not in the lockfile or that don't match what's in there.
bool _isLockFileUpToDate() {
- return root.immediateDependencies.every((package) {
- var locked = lockFile.packages[package.name];
- if (locked == null) return false;
+ if (!root.immediateDependencies.every(_isDependencyUpToDate)) return false;
- if (package.source != locked.source) return false;
+ var overrides = root.dependencyOverrides.map((dep) => dep.name).toSet();
- if (!package.constraint.allows(locked.version)) return false;
+ // Check that path dependencies' pubspecs are also still satisfied, since
+ // they're mutable and may have changed since the last get.
+ return lockFile.packages.values.every((id) {
+ if (id.source != 'path') return true;
Bob Nystrom 2015/12/21 20:55:03 Instead of checking for path specifically, how abo
nweiz 2016/01/04 23:27:29 Done.
- var source = cache.sources[package.source];
- if (source == null) return false;
-
- return source.descriptionsEqual(package.description, locked.description);
+ return cache.sources.load(id).dependencies.every((dep) {
+ if (overrides.contains(dep.name)) return true;
+ return _isDependencyUpToDate(dep);
+ });
Bob Nystrom 2015/12/21 20:55:03 return cache.sources.load(id).dependencies.every(
nweiz 2016/01/04 23:27:29 Done.
});
}
+ /// Returns whether the locked version of [dep] matches the dependency.
+ bool _isDependencyUpToDate(PackageDep dep) {
+ var locked = lockFile.packages[dep.name];
+ if (locked == null) return false;
+
+ if (dep.source != locked.source) return false;
+
+ if (!dep.constraint.allows(locked.version)) return false;
+
+ var source = cache.sources[dep.source];
+ if (source == null) return false;
+
+ return source.descriptionsEqual(dep.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`.
bool _arePackagesAvailable() {
return lockFile.packages.values.every((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);
+ if (source is UnknownSource) return false;
// 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
@@ -542,8 +569,8 @@ class Entrypoint {
}
/// Saves a list of concrete package versions to the `pubspec.lock` file.
- void _saveLockFile(List<PackageId> packageIds) {
- _lockFile = new LockFile(packageIds, cache.sources);
+ void _saveLockFile(SolveResult result) {
+ _lockFile = result.lockFile;
var lockFilePath = root.path('pubspec.lock');
writeTextFile(lockFilePath, _lockFile.serialize(root.dir));
}
« no previous file with comments | « no previous file | lib/src/global_packages.dart » ('j') | lib/src/lock_file.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698