Chromium Code Reviews| Index: sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| diff --git a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| index d96f1574e834822047737209da20d3131a302552..bc9a6c31dfb6d549184468cb5f2eec113db4acbc 100644 |
| --- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| +++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| @@ -534,62 +534,51 @@ class Traverser { |
| return resetStack(() { |
| return deps.advance().then((dep) { |
| - _validateDependency(dep, depender); |
| - |
| - // Add the dependency. |
| - var dependencies = _getDependencies(dep.name); |
| - dependencies.add(new Dependency(depender.name, depender.version, dep)); |
| - |
| - // If the package is barback, pub has an implicit version constraint on |
| - // it since pub itself uses barback too. Note that we don't check for |
| - // the hosted source here because we still want to do this even when |
| - // people on the Dart team are on the bleeding edge and have a path |
| - // dependency on the tip version of barback in the Dart repo. |
| - // |
| - // The length check here is to ensure we only add the barback |
| - // dependency once. |
| - if (dep.name == "barback" && dependencies.length == 1) { |
| - _solver.logSolve('add implicit ${barback.supportedVersions} pub ' |
| - 'dependency on barback'); |
| - |
| - // Use the same source and description as the explicit dependency. |
| - // That way, this doesn't fail with a source/desc conflict if users |
| - // (like Dart team members) use things like a path dependency to |
| - // find barback. |
| - var barbackDep = new PackageDep(dep.name, dep.source, |
| - barback.supportedVersions, dep.description); |
| - dependencies.add(new Dependency("pub itself", null, barbackDep)); |
| - } |
| - |
| - var constraint = _getConstraint(dep.name); |
| + var dependency = new Dependency(depender.name, depender.version, dep); |
| + return _registerDependency(dependency).then((_) { |
| + if (dep.name == "barback") return _addImplicitDependencies(); |
| + }); |
| + }).then((_) => _traverseDeps(depender, deps)); |
| + }); |
| + } |
| - // See if it's possible for a package to match that constraint. |
| - if (constraint.isEmpty) { |
| - var constraints = _getDependencies(dep.name) |
| - .map((dep) => " ${dep.dep.constraint} from ${dep.depender}") |
| - .join('\n'); |
| - _solver.logSolve( |
| - 'disjoint constraints on ${dep.name}:\n$constraints'); |
| - throw new DisjointConstraintException(dep.name, dependencies); |
| - } |
| + /// Register [dependency]'s constraints on the package it depends on and |
| + /// enqueues the package for processing if necessary. |
| + Future _registerDependency(Dependency dependency) { |
| + return syncFuture(() { |
| + _validateDependency(dependency); |
| + |
| + var dep = dependency.dep; |
| + var dependencies = _getDependencies(dep.name); |
| + dependencies.add(dependency); |
| + |
| + var constraint = _getConstraint(dep.name); |
| + |
| + // See if it's possible for a package to match that constraint. |
| + if (constraint.isEmpty) { |
| + var constraints = dependencies |
| + .map((dep) => " ${dep.dep.constraint} from ${dep.depender}") |
| + .join('\n'); |
| + _solver.logSolve( |
| + 'disjoint constraints on ${dep.name}:\n$constraints'); |
| + throw new DisjointConstraintException(dep.name, dependencies); |
| + } |
| - var selected = _validateSelected(dep, constraint); |
| - if (selected != null) { |
| - // The selected package version is good, so enqueue it to traverse |
| - // into it. |
| - _packages.add(selected); |
| - return _traverseDeps(depender, deps); |
| - } |
| + var selected = _validateSelected(dep, constraint); |
| + if (selected != null) { |
| + // The selected package version is good, so enqueue it to traverse |
| + // into it. |
| + _packages.add(selected); |
| + return null; |
| + } |
| - // We haven't selected a version. Try all of the versions that match |
| - // the constraints we currently have for this package. |
| - var locked = _getValidLocked(dep.name); |
| + // We haven't selected a version. Try all of the versions that match |
| + // the constraints we currently have for this package. |
| + var locked = _getValidLocked(dep.name); |
| - return VersionQueue.create(locked, |
| - () => _getAllowedVersions(dep)).then((versions) { |
| - _packages.add(_solver.select(versions)); |
| - }); |
| - }).then((_) => _traverseDeps(depender, deps)); |
| + return VersionQueue.create(locked, () { |
| + return _getAllowedVersions(dep); |
| + }).then((versions) => _packages.add(_solver.select(versions))); |
| }); |
| } |
| @@ -633,7 +622,9 @@ class Traverser { |
| /// |
| /// Throws a [SolveFailure] exception if not. Only validates sources and |
| /// descriptions, not the version. |
| - void _validateDependency(PackageDep dep, PackageId depender) { |
| + void _validateDependency(Dependency dependency) { |
| + var dep = dependency.dep; |
| + |
| // Make sure the dependencies agree on source and description. |
| var required = _getRequired(dep.name); |
| if (required == null) return; |
| @@ -642,8 +633,7 @@ class Traverser { |
| if (required.dep.source != dep.source) { |
| _solver.logSolve('source mismatch on ${dep.name}: ${required.dep.source} ' |
| '!= ${dep.source}'); |
| - throw new SourceMismatchException(dep.name, |
| - [required, new Dependency(depender.name, depender.version, dep)]); |
| + throw new SourceMismatchException(dep.name, [required, dependency]); |
| } |
| // Make sure all of the existing descriptions match the new reference. |
| @@ -651,8 +641,7 @@ class Traverser { |
| if (!source.descriptionsEqual(dep.description, required.dep.description)) { |
| _solver.logSolve('description mismatch on ${dep.name}: ' |
| '${required.dep.description} != ${dep.description}'); |
| - throw new DescriptionMismatchException(dep.name, |
| - [required, new Dependency(depender.name, depender.version, dep)]); |
| + throw new DescriptionMismatchException(dep.name, [required, dependency]); |
| } |
| } |
| @@ -676,6 +665,30 @@ class Traverser { |
| return selected; |
| } |
| + /// Register pub's implicit dependencies. |
| + /// |
| + /// Pub has an implicit version constraint on barback and various other |
| + /// packages used in barback's plugin isolate. |
| + Future _addImplicitDependencies() { |
| + /// Ensure we only add the barback dependency once. |
| + if (_getDependencies("barback").length != 1) return new Future.value(); |
| + |
| + return Future.wait(barback.pubConstraints.keys.map((depName) { |
| + var constraint = barback.pubConstraints[depName]; |
| + _solver.logSolve('add implicit $constraint pub dependency on ' |
| + '$depName'); |
| + |
| + var override = _solver._overrides[depName]; |
|
Bob Nystrom
2014/06/26 16:37:33
Nice. I didn't remember that the solver already ha
|
| + |
| + // Use the same source and description as the dependency override if |
| + // one exists. |
|
Bob Nystrom
2014/06/26 16:37:33
Document that this is mainly for the bots.
nweiz
2014/06/26 20:03:48
Done.
|
| + var pubDep = override == null ? |
| + new PackageDep(depName, "hosted", constraint, depName) : |
| + override.withConstraint(constraint); |
| + return _registerDependency(new Dependency("pub itself", null, pubDep)); |
| + })); |
| + } |
| + |
| /// Gets the list of dependencies for package [name]. |
| /// |
| /// Creates an empty list if needed. |