OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Attempts to resolve a set of version constraints for a package dependency | 6 * Attempts to resolve a set of version constraints for a package dependency |
7 * graph and select an appropriate set of best specific versions for all | 7 * graph and select an appropriate set of best specific versions for all |
8 * dependent packages. It works iteratively and tries to reach a stable | 8 * dependent packages. It works iteratively and tries to reach a stable |
9 * solution where the constraints of all dependencies are met. If it fails to | 9 * solution where the constraints of all dependencies are met. If it fails to |
10 * reach a solution after a certain number of iterations, it assumes the | 10 * reach a solution after a certain number of iterations, it assumes the |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 // Kick off the work by adding the root package at its concrete version to | 95 // Kick off the work by adding the root package at its concrete version to |
96 // the dependency graph. | 96 // the dependency graph. |
97 var ref = new PackageRef( | 97 var ref = new PackageRef( |
98 _root.name, new RootSource(_root), _root.version, _root.name); | 98 _root.name, new RootSource(_root), _root.version, _root.name); |
99 enqueue(new AddConstraint('(entrypoint)', ref)); | 99 enqueue(new AddConstraint('(entrypoint)', ref)); |
100 _pubspecs.cache(ref.atVersion(_root.version), _root.pubspec); | 100 _pubspecs.cache(ref.atVersion(_root.version), _root.pubspec); |
101 | 101 |
102 Future processNextWorkItem(_) { | 102 Future processNextWorkItem(_) { |
103 while (true) { | 103 while (true) { |
104 // Stop if we are done. | 104 // Stop if we are done. |
105 if (_work.isEmpty()) return new Future.immediate(buildResults()); | 105 if (_work.isEmpty) return new Future.immediate(buildResults()); |
106 | 106 |
107 // If we appear to be stuck in a loop, then we probably have an unstable | 107 // If we appear to be stuck in a loop, then we probably have an unstable |
108 // graph, bail. We guess this based on a rough heuristic that it should | 108 // graph, bail. We guess this based on a rough heuristic that it should |
109 // only take a certain number of steps to solve a graph with a given | 109 // only take a certain number of steps to solve a graph with a given |
110 // number of connections. | 110 // number of connections. |
111 // TODO(rnystrom): These numbers here are magic and arbitrary. Tune | 111 // TODO(rnystrom): These numbers here are magic and arbitrary. Tune |
112 // when we have a better picture of real-world package topologies. | 112 // when we have a better picture of real-world package topologies. |
113 _numIterations++; | 113 _numIterations++; |
114 if (_numIterations > max(50, _packages.length * 5)) { | 114 if (_numIterations > max(50, _packages.length * 5)) { |
115 throw new CouldNotSolveException(); | 115 throw new CouldNotSolveException(); |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 /** | 538 /** |
539 * Whether this dependency should always select the latest version. | 539 * Whether this dependency should always select the latest version. |
540 */ | 540 */ |
541 bool useLatestVersion = false; | 541 bool useLatestVersion = false; |
542 | 542 |
543 /** | 543 /** |
544 * Gets whether or not any other packages are currently depending on this | 544 * Gets whether or not any other packages are currently depending on this |
545 * one. If `false`, then it means this package is not part of the dependency | 545 * one. If `false`, then it means this package is not part of the dependency |
546 * graph and should be omitted. | 546 * graph and should be omitted. |
547 */ | 547 */ |
548 bool get isDependedOn => !_refs.isEmpty(); | 548 bool get isDependedOn => !_refs.isEmpty; |
549 | 549 |
550 /** The names of all the packages that depend on this dependency. */ | 550 /** The names of all the packages that depend on this dependency. */ |
551 Collection<String> get dependers => _refs.getKeys(); | 551 Collection<String> get dependers => _refs.getKeys(); |
552 | 552 |
553 /** | 553 /** |
554 * Gets the overall constraint that all packages are placing on this one. | 554 * Gets the overall constraint that all packages are placing on this one. |
555 * If no packages have a constraint on this one (which can happen when this | 555 * If no packages have a constraint on this one (which can happen when this |
556 * package is in the process of being added to the graph), returns `null`. | 556 * package is in the process of being added to the graph), returns `null`. |
557 */ | 557 */ |
558 VersionConstraint get constraint { | 558 VersionConstraint get constraint { |
559 if (_refs.isEmpty()) return null; | 559 if (_refs.isEmpty) return null; |
560 return new VersionConstraint.intersect( | 560 return new VersionConstraint.intersect( |
561 _refs.getValues().map((ref) => ref.constraint)); | 561 _refs.getValues().map((ref) => ref.constraint)); |
562 } | 562 } |
563 | 563 |
564 /// The source of this dependency's package. | 564 /// The source of this dependency's package. |
565 Source get source { | 565 Source get source { |
566 var canonical = _canonicalRef(); | 566 var canonical = _canonicalRef(); |
567 if (canonical == null) return null; | 567 if (canonical == null) return null; |
568 return canonical.source; | 568 return canonical.source; |
569 } | 569 } |
570 | 570 |
571 /// The description of this dependency's package. | 571 /// The description of this dependency's package. |
572 get description { | 572 get description { |
573 var canonical = _canonicalRef(); | 573 var canonical = _canonicalRef(); |
574 if (canonical == null) return null; | 574 if (canonical == null) return null; |
575 return canonical.description; | 575 return canonical.description; |
576 } | 576 } |
577 | 577 |
578 /// Return the PackageRef that has the canonical source and description for | 578 /// Return the PackageRef that has the canonical source and description for |
579 /// this package. If any dependency requires that this package come from a | 579 /// this package. If any dependency requires that this package come from a |
580 /// [RootSource], that will be used; otherwise, it will be the source and | 580 /// [RootSource], that will be used; otherwise, it will be the source and |
581 /// description that all dependencies agree upon. | 581 /// description that all dependencies agree upon. |
582 PackageRef _canonicalRef() { | 582 PackageRef _canonicalRef() { |
583 if (_refs.isEmpty()) return null; | 583 if (_refs.isEmpty) return null; |
584 var refs = _refs.getValues(); | 584 var refs = _refs.getValues(); |
585 for (var ref in refs) { | 585 for (var ref in refs) { |
586 if (ref is RootSource) return ref; | 586 if (ref is RootSource) return ref; |
587 } | 587 } |
588 return refs[0]; | 588 return refs[0]; |
589 } | 589 } |
590 | 590 |
591 Dependency(this.name) | 591 Dependency(this.name) |
592 : _refs = <String, PackageRef>{}; | 592 : _refs = <String, PackageRef>{}; |
593 | 593 |
(...skipping 23 matching lines...) Expand all Loading... |
617 } | 617 } |
618 } | 618 } |
619 | 619 |
620 _refs[package] = ref; | 620 _refs[package] = ref; |
621 } | 621 } |
622 | 622 |
623 /// Returns a PackageRef whose source and description any new constraints are | 623 /// Returns a PackageRef whose source and description any new constraints are |
624 /// required to match. Returns null if there are no requirements on new | 624 /// required to match. Returns null if there are no requirements on new |
625 /// constraints. | 625 /// constraints. |
626 PackageRef _requiredRef() { | 626 PackageRef _requiredRef() { |
627 if (_refs.isEmpty()) return null; | 627 if (_refs.isEmpty) return null; |
628 var refs = _refs.getValues(); | 628 var refs = _refs.getValues(); |
629 var first = refs[0]; | 629 var first = refs[0]; |
630 if (refs.length == 1) { | 630 if (refs.length == 1) { |
631 if (first.source is RootSource) return null; | 631 if (first.source is RootSource) return null; |
632 return first; | 632 return first; |
633 } | 633 } |
634 return refs[1]; | 634 return refs[1]; |
635 } | 635 } |
636 | 636 |
637 /** | 637 /** |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 final description1; | 724 final description1; |
725 final description2; | 725 final description2; |
726 | 726 |
727 DescriptionMismatchException(this.package, this.description1, | 727 DescriptionMismatchException(this.package, this.description1, |
728 this.description2); | 728 this.description2); |
729 | 729 |
730 // TODO(nweiz): Dump to YAML when that's supported | 730 // TODO(nweiz): Dump to YAML when that's supported |
731 String toString() => "Package '$package' has conflicting descriptions " | 731 String toString() => "Package '$package' has conflicting descriptions " |
732 "'${JSON.stringify(description1)}' and '${JSON.stringify(description2)}'"; | 732 "'${JSON.stringify(description1)}' and '${JSON.stringify(description2)}'"; |
733 } | 733 } |
OLD | NEW |