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

Side by Side Diff: utils/pub/solver/backtracking_solver.dart

Issue 14298006: Select packages that match SDK constraints. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix an import. Created 7 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | utils/pub/solver/version_solver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /// A back-tracking depth-first solver. Attempts to find the best solution for 5 /// A back-tracking depth-first solver. Attempts to find the best solution for
6 /// a root package's transitive dependency graph, where a "solution" is a set 6 /// a root package's transitive dependency graph, where a "solution" is a set
7 /// of concrete package versions. A valid solution will select concrete 7 /// of concrete package versions. A valid solution will select concrete
8 /// versions for every package reached from the root package's dependency graph, 8 /// versions for every package reached from the root package's dependency graph,
9 /// and each of those packages will fit the version constraints placed on it. 9 /// and each of those packages will fit the version constraints placed on it.
10 /// 10 ///
(...skipping 21 matching lines...) Expand all
32 /// a valid solution has been found or until all possible options for all 32 /// a valid solution has been found or until all possible options for all
33 /// speculative choices have been exhausted. 33 /// speculative choices have been exhausted.
34 library version_solver2; 34 library version_solver2;
35 35
36 import 'dart:async'; 36 import 'dart:async';
37 import 'dart:collection' show Queue; 37 import 'dart:collection' show Queue;
38 38
39 import '../lock_file.dart'; 39 import '../lock_file.dart';
40 import '../log.dart' as log; 40 import '../log.dart' as log;
41 import '../package.dart'; 41 import '../package.dart';
42 import '../pubspec.dart';
43 import '../sdk.dart' as sdk;
42 import '../source.dart'; 44 import '../source.dart';
43 import '../source_registry.dart'; 45 import '../source_registry.dart';
44 import '../utils.dart'; 46 import '../utils.dart';
45 import '../version.dart'; 47 import '../version.dart';
46 import 'version_solver.dart'; 48 import 'version_solver.dart';
47 49
48 /// The top-level solver. Keeps track of the current potential solution, and 50 /// The top-level solver. Keeps track of the current potential solution, and
49 /// the other possible versions for speculative package selections. Backtracks 51 /// the other possible versions for speculative package selections. Backtracks
50 /// and advances to the next potential solution in the case of a failure. 52 /// and advances to the next potential solution in the case of a failure.
51 class BacktrackingVersionSolver extends VersionSolver { 53 class BacktrackingVersionSolver extends VersionSolver {
(...skipping 15 matching lines...) Expand all
67 /// 69 ///
68 /// The solver tries versions in depth-first order, so only the last queue in 70 /// The solver tries versions in depth-first order, so only the last queue in
69 /// the list will have items removed from it. When a new constraint is placed 71 /// the list will have items removed from it. When a new constraint is placed
70 /// on an already-selected package, and that constraint doesn't match the 72 /// on an already-selected package, and that constraint doesn't match the
71 /// selected version, that will cause the current solution to fail and 73 /// selected version, that will cause the current solution to fail and
72 /// trigger backtracking. 74 /// trigger backtracking.
73 final _selected = <Queue<PackageId>>[]; 75 final _selected = <Queue<PackageId>>[];
74 76
75 /// The number of possible solutions that have been attempted. 77 /// The number of possible solutions that have been attempted.
76 int get attemptedSolutions => _attemptedSolutions; 78 int get attemptedSolutions => _attemptedSolutions;
77 var _attemptedSolutions = 0; 79 var _attemptedSolutions = 1;
78 80
79 BacktrackingVersionSolver(SourceRegistry sources, Package root, 81 BacktrackingVersionSolver(SourceRegistry sources, Package root,
80 LockFile lockFile, List<String> useLatest) 82 LockFile lockFile, List<String> useLatest)
81 : super(sources, root, lockFile, useLatest); 83 : super(sources, root, lockFile, useLatest);
82 84
83 void forceLatestVersion(String package) { 85 void forceLatestVersion(String package) {
84 _forceLatest.add(package); 86 _forceLatest.add(package);
85 } 87 }
86 88
87 Future<List<PackageId>> runSolver() => _traverseSolution(); 89 Future<List<PackageId>> runSolver() {
90 return new Future.sync(() {
91 _validateSdkConstraint(root.pubspec);
92 return _traverseSolution();
93 });
94 }
88 95
89 /// Adds [versions], which is the list of all allowed versions of a given 96 /// Adds [versions], which is the list of all allowed versions of a given
90 /// package, to the set of versions to consider for solutions. The first item 97 /// package, to the set of versions to consider for solutions. The first item
91 /// in the list will be the currently selected version of that package. 98 /// in the list will be the currently selected version of that package.
92 /// Subsequent items will be tried if it the current selection fails. Returns 99 /// Subsequent items will be tried if it the current selection fails. Returns
93 /// the first selected version. 100 /// the first selected version.
94 PackageId select(Iterable<PackageId> versions) { 101 PackageId select(Iterable<PackageId> versions) {
95 _selected.add(new Queue<PackageId>.from(versions)); 102 _selected.add(new Queue<PackageId>.from(versions));
96 logSolve(); 103 logSolve();
97 return versions.first; 104 return versions.first;
(...skipping 17 matching lines...) Expand all
115 /// `null` if it isn't in the lockfile (or has been unlocked). 122 /// `null` if it isn't in the lockfile (or has been unlocked).
116 PackageId getLocked(String package) => lockFile.packages[package]; 123 PackageId getLocked(String package) => lockFile.packages[package];
117 124
118 /// Traverses the root package's dependency graph using the current potential 125 /// Traverses the root package's dependency graph using the current potential
119 /// solution. If successful, completes to the solution. If not, backtracks 126 /// solution. If successful, completes to the solution. If not, backtracks
120 /// to the most recently selected version of a package and tries the next 127 /// to the most recently selected version of a package and tries the next
121 /// version of it. If there are no more versions, continues to backtrack to 128 /// version of it. If there are no more versions, continues to backtrack to
122 /// previous selections, and so on. If there is nothing left to backtrack to, 129 /// previous selections, and so on. If there is nothing left to backtrack to,
123 /// completes to the last failure that occurred. 130 /// completes to the last failure that occurred.
124 Future<List<PackageId>> _traverseSolution() { 131 Future<List<PackageId>> _traverseSolution() {
125 _attemptedSolutions++;
126
127 return new Traverser(this).traverse().catchError((error) { 132 return new Traverser(this).traverse().catchError((error) {
128 if (error is! SolveFailure) throw error; 133 if (error is! SolveFailure) throw error;
129 134
130 if (_backtrack(error)) return _traverseSolution(); 135 if (_backtrack(error)) {
136 _attemptedSolutions++;
137 return _traverseSolution();
138 }
131 139
132 // All out of solutions, so fail. 140 // All out of solutions, so fail.
133 throw error; 141 throw error;
134 }); 142 });
135 } 143 }
136 144
137 /// Backtracks from the current failed solution and determines the next 145 /// Backtracks from the current failed solution and determines the next
138 /// solution to try. If possible, it will backjump based on the cause of the 146 /// solution to try. If possible, it will backjump based on the cause of the
139 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to 147 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to
140 /// the next possible solution. 148 /// the next possible solution.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 298
291 var id = _packages.removeFirst(); 299 var id = _packages.removeFirst();
292 300
293 // Don't visit the same package twice. 301 // Don't visit the same package twice.
294 if (_visited.contains(id)) { 302 if (_visited.contains(id)) {
295 return _traversePackage(); 303 return _traversePackage();
296 } 304 }
297 _visited.add(id); 305 _visited.add(id);
298 306
299 return _solver.cache.getPubspec(id).then((pubspec) { 307 return _solver.cache.getPubspec(id).then((pubspec) {
308 _validateSdkConstraint(pubspec);
309
300 var refs = pubspec.dependencies.toList(); 310 var refs = pubspec.dependencies.toList();
301 311
302 // Include dev dependencies of the root package. 312 // Include dev dependencies of the root package.
303 if (id.isRoot) refs.addAll(pubspec.devDependencies); 313 if (id.isRoot) refs.addAll(pubspec.devDependencies);
304 314
305 // Given a package ref, returns a future that completes to a pair of the 315 // Given a package ref, returns a future that completes to a pair of the
306 // ref and the number of versions available for it. 316 // ref and the number of versions available for it.
307 getNumVersions(PackageRef ref) { 317 getNumVersions(PackageRef ref) {
308 // There is only ever one version of the root package. 318 // There is only ever one version of the root package.
309 if (ref.isRoot) { 319 if (ref.isRoot) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 537
528 var required = _getRequired(name); 538 var required = _getRequired(name);
529 if (required != null) { 539 if (required != null) {
530 if (package.source.name != required.ref.source.name) return null; 540 if (package.source.name != required.ref.source.name) return null;
531 if (!package.descriptionEquals(required.ref)) return null; 541 if (!package.descriptionEquals(required.ref)) return null;
532 } 542 }
533 543
534 return package; 544 return package;
535 } 545 }
536 } 546 }
547
548 /// Ensures that if [pubspec] has an SDK constraint, then it is compatible
549 /// with the current SDK. Throws a [SolverFailure] if not.
550 void _validateSdkConstraint(Pubspec pubspec) {
551 if (pubspec.environment.sdkVersion.allows(sdk.version)) return;
552
553 throw new CouldNotSolveException(
554 'Package ${pubspec.name} requires SDK version '
555 '${pubspec.environment.sdkVersion} but the current SDK is '
556 '${sdk.version}.');
557 }
OLDNEW
« no previous file with comments | « no previous file | utils/pub/solver/version_solver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698