| Index: utils/pub/version_solver.dart
|
| diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
|
| index e0cf2be80a586e80b9b6a3d99f41c5ad6ae7ff5f..31baa9ce9a9ee87e83d26acade99aa01cbca178e 100644
|
| --- a/utils/pub/version_solver.dart
|
| +++ b/utils/pub/version_solver.dart
|
| @@ -164,7 +164,8 @@ class VersionSolver {
|
| // TODO(rnystrom): Better exception.
|
| if (best == null) {
|
| if (tryUnlockDepender(dependency)) return null;
|
| - throw new NoVersionException(dependency.name, dependency.constraint);
|
| + throw new NoVersionException(dependency.name, dependency.constraint,
|
| + dependency._refs);
|
| } else if (!dependency.constraint.allows(best)) {
|
| if (tryUnlockDepender(dependency)) return null;
|
| throw new CouldNotUpdateException(
|
| @@ -353,7 +354,7 @@ abstract class ChangeConstraint implements WorkItem {
|
| return null;
|
| }
|
|
|
| - throw new DisjointConstraintException(name);
|
| + throw new DisjointConstraintException(name, newDependency._refs);
|
| }
|
|
|
| // If this constraint change didn't cause the overall constraint on the
|
| @@ -606,32 +607,36 @@ class Dependency {
|
| * Places [ref] as a constraint from [package] onto this.
|
| */
|
| void placeConstraint(String package, PackageRef ref) {
|
| - var required = _requiredRef();
|
| - if (required != null) {
|
| + var requiredDepender = _requiredDepender();
|
| + if (requiredDepender != null) {
|
| + var required = _refs[requiredDepender];
|
| if (required.source.name != ref.source.name) {
|
| - throw new SourceMismatchException(name, required.source, ref.source);
|
| + throw new SourceMismatchException(name,
|
| + requiredDepender, required.source, package, ref.source);
|
| } else if (!required.source.descriptionsEqual(
|
| required.description, ref.description)) {
|
| - throw new DescriptionMismatchException(
|
| - name, required.description, ref.description);
|
| + throw new DescriptionMismatchException(name,
|
| + requiredDepender, required.description, package, ref.description);
|
| }
|
| }
|
|
|
| _refs[package] = ref;
|
| }
|
|
|
| - /// Returns a PackageRef whose source and description any new constraints are
|
| - /// required to match. Returns null if there are no requirements on new
|
| - /// constraints.
|
| - PackageRef _requiredRef() {
|
| + /// Returns the name of a package whose constraint source and description
|
| + /// all other constraints must match. Returns null if there are no
|
| + /// requirements on new constraints.
|
| + String _requiredDepender() {
|
| if (_refs.isEmpty) return null;
|
| - var refs = _refs.values;
|
| - var first = refs[0];
|
| - if (refs.length == 1) {
|
| - if (first.source is RootSource) return null;
|
| - return first;
|
| +
|
| + var dependers = _refs.keys;
|
| + if (dependers.length == 1) {
|
| + var depender = dependers[0];
|
| + if (_refs[depender].source is RootSource) return null;
|
| + return depender;
|
| }
|
| - return refs[1];
|
| +
|
| + return dependers[1];
|
| }
|
|
|
| /**
|
| @@ -640,7 +645,6 @@ class Dependency {
|
| PackageRef removeConstraint(String package) => _refs.remove(package);
|
| }
|
|
|
| -// TODO(rnystrom): Report the last of depending packages and their constraints.
|
| /**
|
| * Exception thrown when the [VersionConstraint] used to match a package is
|
| * valid (i.e. non-empty), but there are no released versions of the package
|
| @@ -649,11 +653,25 @@ class Dependency {
|
| class NoVersionException implements Exception {
|
| final String package;
|
| final VersionConstraint constraint;
|
| + final Map<String, PackageRef> _dependencies;
|
|
|
| - NoVersionException(this.package, this.constraint);
|
| + NoVersionException(this.package, this.constraint, this._dependencies);
|
|
|
| - String toString() =>
|
| - "Package '$package' has no versions that match $constraint.";
|
| + String toString() {
|
| + var buffer = new StringBuffer();
|
| + buffer.add("Package '$package' has no versions that match $constraint "
|
| + "derived from:\n");
|
| +
|
| + var keys = new List.from(_dependencies.keys);
|
| + keys.sort();
|
| +
|
| + for (var key in keys) {
|
| + buffer.add("- '$key' depends on version "
|
| + "${_dependencies[key].constraint}\n");
|
| + }
|
| +
|
| + return buffer.toString();
|
| + }
|
| }
|
|
|
| // TODO(rnystrom): Report the list of depending packages and their constraints.
|
| @@ -672,7 +690,6 @@ class CouldNotUpdateException implements Exception {
|
| "The latest version of '$package', $best, does not match $constraint.";
|
| }
|
|
|
| -// TODO(rnystrom): Report the last of depending packages and their constraints.
|
| /**
|
| * Exception thrown when the [VersionConstraint] used to match a package is
|
| * the empty set: in other words, multiple packages depend on it and have
|
| @@ -680,11 +697,24 @@ class CouldNotUpdateException implements Exception {
|
| */
|
| class DisjointConstraintException implements Exception {
|
| final String package;
|
| + final Map<String, PackageRef> _dependencies;
|
|
|
| - DisjointConstraintException(this.package);
|
| + DisjointConstraintException(this.package, this._dependencies);
|
|
|
| - String toString() =>
|
| - "Package '$package' has disjoint constraints.";
|
| + String toString() {
|
| + var buffer = new StringBuffer();
|
| + buffer.add("Incompatible version constraints on '$package':\n");
|
| +
|
| + var keys = new List.from(_dependencies.keys);
|
| + keys.sort();
|
| +
|
| + for (var key in keys) {
|
| + buffer.add("- '$key' depends on version "
|
| + "${_dependencies[key].constraint}\n");
|
| + }
|
| +
|
| + return buffer.toString();
|
| + }
|
| }
|
|
|
| /**
|
| @@ -704,14 +734,18 @@ class CouldNotSolveException implements Exception {
|
| */
|
| class SourceMismatchException implements Exception {
|
| final String package;
|
| + final String depender1;
|
| final Source source1;
|
| + final String depender2;
|
| final Source source2;
|
|
|
| - SourceMismatchException(this.package, this.source1, this.source2);
|
| + SourceMismatchException(this.package, this.depender1, this.source1,
|
| + this.depender2, this.source2);
|
|
|
| String toString() {
|
| - return "Package '$package' is depended on from both sources "
|
| - "'${source1.name}' and '${source2.name}'.";
|
| + return "Incompatible dependencies on '$package':\n"
|
| + "- '$depender1' depends on it from source '$source1'\n"
|
| + "- '$depender2' depends on it from source '$source2'";
|
| }
|
| }
|
|
|
| @@ -721,13 +755,20 @@ class SourceMismatchException implements Exception {
|
| */
|
| class DescriptionMismatchException implements Exception {
|
| final String package;
|
| + final String depender1;
|
| final description1;
|
| + final String depender2;
|
| final description2;
|
|
|
| - DescriptionMismatchException(this.package, this.description1,
|
| - this.description2);
|
| + DescriptionMismatchException(this.package, this.depender1, this.description1,
|
| + this.depender2, this.description2);
|
|
|
| - // TODO(nweiz): Dump to YAML when that's supported
|
| - String toString() => "Package '$package' has conflicting descriptions "
|
| - "'${JSON.stringify(description1)}' and '${JSON.stringify(description2)}'";
|
| + String toString() {
|
| + // TODO(nweiz): Dump descriptions to YAML when that's supported.
|
| + return "Incompatible dependencies on '$package':\n"
|
| + "- '$depender1' depends on it with description "
|
| + "${JSON.stringify(description1)}\n"
|
| + "- '$depender2' depends on it with description "
|
| + "${JSON.stringify(description2)}";
|
| + }
|
| }
|
|
|