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

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

Issue 14232023: Switch to backtracking solver. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 | « utils/pub/solver/greedy_solver.dart ('k') | utils/tests/pub/sdk_constraint_test.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 library version_solver; 5 library version_solver;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:json' as json; 8 import 'dart:json' as json;
9 9
10 import '../lock_file.dart'; 10 import '../lock_file.dart';
11 import '../log.dart' as log; 11 import '../log.dart' as log;
12 import '../package.dart'; 12 import '../package.dart';
13 import '../pubspec.dart'; 13 import '../pubspec.dart';
14 import '../source.dart'; 14 import '../source.dart';
15 import '../source_registry.dart'; 15 import '../source_registry.dart';
16 import '../version.dart'; 16 import '../version.dart';
17 import 'backtracking_solver.dart'; 17 import 'backtracking_solver.dart';
18 import 'greedy_solver.dart';
19 18
20 /// Attempts to select the best concrete versions for all of the transitive 19 /// Attempts to select the best concrete versions for all of the transitive
21 /// dependencies of [root] taking into account all of the [VersionConstraint]s 20 /// dependencies of [root] taking into account all of the [VersionConstraint]s
22 /// that those dependencies place on each other and the requirements imposed by 21 /// that those dependencies place on each other and the requirements imposed by
23 /// [lockFile]. 22 /// [lockFile].
24 /// 23 ///
25 /// If [useLatest] is given, then only the latest versions of the referenced 24 /// If [useLatest] is given, then only the latest versions of the referenced
26 /// packages will be used. This is for forcing an update to one or more 25 /// packages will be used. This is for forcing an update to one or more
27 /// packages. 26 /// packages.
28 ///
29 /// If [allowBacktracking] is `true` the backtracking version solver will
30 /// be used. Otherwise, the non-backtracking one will be.
31 Future<SolveResult> resolveVersions(SourceRegistry sources, Package root, 27 Future<SolveResult> resolveVersions(SourceRegistry sources, Package root,
32 {LockFile lockFile, bool allowBacktracking, List<PackageRef> useLatest}) { 28 {LockFile lockFile, List<PackageRef> useLatest}) {
33 log.message('Resolving dependencies...'); 29 log.message('Resolving dependencies...');
34 30
35 if (allowBacktracking == null) allowBacktracking = false;
36 if (lockFile == null) lockFile = new LockFile.empty(); 31 if (lockFile == null) lockFile = new LockFile.empty();
37 if (useLatest == null) useLatest = []; 32 if (useLatest == null) useLatest = [];
38 33
39 var solver; 34 return new BacktrackingSolver(sources, root, lockFile, useLatest).solve();
40 if (allowBacktracking) {
41 solver = new BacktrackingVersionSolver(sources, root, lockFile, useLatest);
42 } else {
43 solver = new GreedyVersionSolver(sources, root, lockFile, useLatest);
44 }
45
46 return solver.solve();
47 }
48
49 /// Base class for an implementation of the version constraint solver.
50 class VersionSolver {
51 final SourceRegistry sources;
52 final Package root;
53 final LockFile lockFile;
54 final PubspecCache cache;
55
56 VersionSolver(SourceRegistry sources, this.root, this.lockFile,
57 List<String> useLatest)
58 : sources = sources,
59 cache = new PubspecCache(sources) {
60 for (var package in useLatest) {
61 forceLatestVersion(package);
62 lockFile.packages.remove(package);
63 }
64 }
65
66 /// The number of solutions the solver has tried so far.
67 int get attemptedSolutions;
68
69 /// Force the solver to upgrade [package] to the latest available version.
70 void forceLatestVersion(String package);
71
72 /// Run the solver. Completes with a list of specific package versions if
73 /// successful or an error if it failed to find a solution.
74 Future<SolveResult> solve() {
75 var stopwatch = new Stopwatch();
76
77 return new Future(() {
78 stopwatch.start();
79
80 // Pre-cache the root package's known pubspec.
81 cache.cache(new PackageId.root(root), root.pubspec);
82 return runSolver();
83 }).then((packages) {
84 return new SolveResult(packages, null, attemptedSolutions);
85 }).catchError((error) {
86 if (error is! SolveFailure) throw error;
87
88 // Wrap a failure in a result so we can attach some other data.
89 return new SolveResult(null, error, attemptedSolutions);
90 }).whenComplete(() {
91 // Gather some solving metrics.
92 var buffer = new StringBuffer();
93 buffer.writeln('${runtimeType} took ${stopwatch.elapsed} seconds.');
94 buffer.writeln(
95 '- Requested ${cache.versionCacheMisses} version lists');
96 buffer.writeln(
97 '- Looked up ${cache.versionCacheHits} cached version lists');
98 buffer.writeln(
99 '- Requested ${cache.pubspecCacheMisses} pubspecs');
100 buffer.writeln(
101 '- Looked up ${cache.pubspecCacheHits} cached pubspecs');
102 log.solver(buffer);
103 });
104 }
105
106 /// Entrypoint for subclasses to actually begin solving. External code should
107 /// call [solve()].
108 Future<List<PackageId>> runSolver();
109 } 35 }
110 36
111 /// The result of a version resolution. 37 /// The result of a version resolution.
112 class SolveResult { 38 class SolveResult {
113 /// Whether the solver found a complete solution or failed. 39 /// Whether the solver found a complete solution or failed.
114 bool get succeeded => error == null; 40 bool get succeeded => error == null;
115 41
116 /// The list of concrete package versions that were selected for each package 42 /// The list of concrete package versions that were selected for each package
117 /// reachable from the root, or `null` if the solver failed. 43 /// reachable from the root, or `null` if the solver failed.
118 final List<PackageId> packages; 44 final List<PackageId> packages;
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 Iterable<Dependency> dependencies) 299 Iterable<Dependency> dependencies)
374 : super(package, dependencies); 300 : super(package, dependencies);
375 301
376 String get _message => "Incompatible dependencies on '$package'"; 302 String get _message => "Incompatible dependencies on '$package'";
377 303
378 String _describeDependency(PackageRef ref) { 304 String _describeDependency(PackageRef ref) {
379 // TODO(nweiz): Dump descriptions to YAML when that's supported. 305 // TODO(nweiz): Dump descriptions to YAML when that's supported.
380 return "depends on it with description ${json.stringify(ref.description)}"; 306 return "depends on it with description ${json.stringify(ref.description)}";
381 } 307 }
382 } 308 }
OLDNEW
« no previous file with comments | « utils/pub/solver/greedy_solver.dart ('k') | utils/tests/pub/sdk_constraint_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698