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

Side by Side Diff: sdk/lib/_internal/pub/lib/src/solver/version_solver.dart

Issue 1140083005: Rewrite pub's version solver. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Nuke implicit deps. Created 5 years, 7 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
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 pub.solver.version_solver; 5 library pub.solver.version_solver;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import "dart:convert"; 8 import "dart:convert";
9 9
10 import 'package:pub_semver/pub_semver.dart'; 10 import 'package:pub_semver/pub_semver.dart';
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 /// 207 ///
208 /// Packages are sorted in descending version order with all "stable" 208 /// Packages are sorted in descending version order with all "stable"
209 /// versions (i.e. ones without a prerelease suffix) before pre-release 209 /// versions (i.e. ones without a prerelease suffix) before pre-release
210 /// versions. This ensures that the solver prefers stable packages over 210 /// versions. This ensures that the solver prefers stable packages over
211 /// unstable ones. 211 /// unstable ones.
212 Future<List<PackageId>> getVersions(PackageRef package) async { 212 Future<List<PackageId>> getVersions(PackageRef package) async {
213 if (package.isRoot) { 213 if (package.isRoot) {
214 throw new StateError("Cannot get versions for root package $package."); 214 throw new StateError("Cannot get versions for root package $package.");
215 } 215 }
216 216
217 if (package.isMagic) return [new PackageId.magic(package.name)];
218
217 // See if we have it cached. 219 // See if we have it cached.
218 var versions = _versions[package]; 220 var versions = _versions[package];
219 if (versions != null) { 221 if (versions != null) {
220 _versionCacheHits++; 222 _versionCacheHits++;
221 return versions; 223 return versions;
222 } 224 }
223 225
224 // See if we cached a failure. 226 // See if we cached a failure.
225 var error = _versionErrors[package]; 227 var error = _versionErrors[package];
226 if (error != null) { 228 if (error != null) {
227 _versionCacheHits++; 229 _versionCacheHits++;
228 await new Future.error(error.first, error.last); 230 await new Future.error(error.first, error.last);
229 } 231 }
230 232
231 _versionCacheMisses++; 233 _versionCacheMisses++;
232 234
233 var source = _sources[package.source]; 235 var source = _sources[package.source];
234 var pubspecs; 236 var pubspecs;
235 try { 237 try {
236 pubspecs = await source.getVersions(package.name, package.description); 238 pubspecs = await source.getVersions(package.name, package.description);
237 } catch (error, stackTrace) { 239 } catch (error, stackTrace) {
238 // If an error occurs, cache that too. We only want to do one request 240 // If an error occurs, cache that too. We only want to do one request
239 // for any given package, successful or not. 241 // for any given package, successful or not.
240 log.solver("Could not get versions for $package:\n$error\n\n$stackTrace"); 242 var chain = new Chain.forTrace(stackTrace);
241 _versionErrors[package] = new Pair(error, new Chain.forTrace(stackTrace)); 243 log.solver("Could not get versions for $package:\n$error\n\n" +
244 chain.terse.toString());
245 _versionErrors[package] = new Pair(error, chain);
242 throw error; 246 throw error;
243 } 247 }
244 248
245 // Sort by priority so we try preferred versions first. 249 // Sort by priority so we try preferred versions first.
246 pubspecs.sort((pubspec1, pubspec2) { 250 pubspecs.sort((pubspec1, pubspec2) {
247 return _type == SolveType.DOWNGRADE 251 return _type == SolveType.DOWNGRADE
248 ? Version.antiprioritize(pubspec1.version, pubspec2.version) 252 ? Version.antiprioritize(pubspec1.version, pubspec2.version)
249 : Version.prioritize(pubspec1.version, pubspec2.version); 253 : Version.prioritize(pubspec1.version, pubspec2.version);
250 }); 254 });
251 255
(...skipping 21 matching lines...) Expand all
273 277
274 // Uncomment this to dump the visited package graph to JSON. 278 // Uncomment this to dump the visited package graph to JSON.
275 //results += _debugWritePackageGraph(); 279 //results += _debugWritePackageGraph();
276 280
277 return results; 281 return results;
278 } 282 }
279 } 283 }
280 284
281 /// A reference from a depending package to a package that it depends on. 285 /// A reference from a depending package to a package that it depends on.
282 class Dependency { 286 class Dependency {
283 /// The name of the package that has this dependency. 287 /// The package that has this dependency.
284 final String depender; 288 final PackageId depender;
285
286 /// The version of the depender that has this dependency.
287 final Version dependerVersion;
288 289
289 /// The package being depended on. 290 /// The package being depended on.
290 final PackageDep dep; 291 final PackageDep dep;
291 292
292 /// Whether [depender] is a magic dependency (e.g. "pub itself" or "pub global 293 Dependency(this.depender, this.dep);
293 /// activate").
294 bool get isMagic => depender.contains(" ");
295 294
296 295 String toString() => '$depender -> $dep';
297 Dependency(this.depender, this.dependerVersion, this.dep);
298
299 String toString() => '$depender $dependerVersion -> $dep';
300 } 296 }
301 297
302 /// An enum for types of version resolution. 298 /// An enum for types of version resolution.
303 class SolveType { 299 class SolveType {
304 /// As few changes to the lockfile as possible to be consistent with the 300 /// As few changes to the lockfile as possible to be consistent with the
305 /// pubspec. 301 /// pubspec.
306 static const GET = const SolveType._("get"); 302 static const GET = const SolveType._("get");
307 303
308 /// Upgrade all packages or specific packages to the highest versions 304 /// Upgrade all packages or specific packages to the highest versions
309 /// possible, regardless of the lockfile. 305 /// possible, regardless of the lockfile.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 SolveFailure(this.package, Iterable<Dependency> dependencies) 338 SolveFailure(this.package, Iterable<Dependency> dependencies)
343 : dependencies = dependencies != null ? dependencies : <Dependency>[]; 339 : dependencies = dependencies != null ? dependencies : <Dependency>[];
344 340
345 String toString() { 341 String toString() {
346 if (dependencies.isEmpty) return _message; 342 if (dependencies.isEmpty) return _message;
347 343
348 var buffer = new StringBuffer(); 344 var buffer = new StringBuffer();
349 buffer.write("$_message:"); 345 buffer.write("$_message:");
350 346
351 var sorted = dependencies.toList(); 347 var sorted = dependencies.toList();
352 sorted.sort((a, b) => a.depender.compareTo(b.depender)); 348 sorted.sort((a, b) => a.depender.name.compareTo(b.depender.name));
353 349
354 for (var dep in sorted) { 350 for (var dep in sorted) {
355 buffer.writeln(); 351 buffer.writeln();
356 buffer.write("- ${log.bold(dep.depender)}"); 352 buffer.write("- ${log.bold(dep.depender.name)}");
357 if (!dep.isMagic) buffer.write(" ${dep.dependerVersion}"); 353 if (!dep.depender.isMagic && !dep.depender.isRoot) {
354 buffer.write(" ${dep.depender.version}");
355 }
358 buffer.write(" ${_describeDependency(dep.dep)}"); 356 buffer.write(" ${_describeDependency(dep.dep)}");
359 } 357 }
360 358
361 return buffer.toString(); 359 return buffer.toString();
362 } 360 }
363 361
364 /// Describes a dependency's reference in the output message. 362 /// Describes a dependency's reference in the output message.
365 /// 363 ///
366 /// Override this to highlight which aspect of [dep] led to the failure. 364 /// Override this to highlight which aspect of [dep] led to the failure.
367 String _describeDependency(PackageDep dep) => 365 String _describeDependency(PackageDep dep) =>
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 "depends on it from source ${dep.source}"; 441 "depends on it from source ${dep.source}";
444 } 442 }
445 443
446 /// Exception thrown when a dependency on an unknown source name is found. 444 /// Exception thrown when a dependency on an unknown source name is found.
447 class UnknownSourceException extends SolveFailure { 445 class UnknownSourceException extends SolveFailure {
448 UnknownSourceException(String package, Iterable<Dependency> dependencies) 446 UnknownSourceException(String package, Iterable<Dependency> dependencies)
449 : super(package, dependencies); 447 : super(package, dependencies);
450 448
451 String toString() { 449 String toString() {
452 var dep = dependencies.single; 450 var dep = dependencies.single;
453 return 'Package ${dep.depender} depends on ${dep.dep.name} from unknown ' 451 return 'Package ${dep.depender.name} depends on ${dep.dep.name} from '
454 'source "${dep.dep.source}".'; 452 'unknown source "${dep.dep.source}".';
455 } 453 }
456 } 454 }
457 455
458 /// Exception thrown when two packages with the same name and source but 456 /// Exception thrown when two packages with the same name and source but
459 /// different descriptions are depended upon. 457 /// different descriptions are depended upon.
460 class DescriptionMismatchException extends SolveFailure { 458 class DescriptionMismatchException extends SolveFailure {
461 String get _message => "Incompatible dependencies on $package"; 459 String get _message => "Incompatible dependencies on $package";
462 460
463 DescriptionMismatchException(String package, 461 DescriptionMismatchException(String package,
464 Iterable<Dependency> dependencies) 462 Iterable<Dependency> dependencies)
(...skipping 15 matching lines...) Expand all
480 478
481 DependencyNotFoundException(String package, this._innerException, 479 DependencyNotFoundException(String package, this._innerException,
482 Iterable<Dependency> dependencies) 480 Iterable<Dependency> dependencies)
483 : super(package, dependencies); 481 : super(package, dependencies);
484 482
485 /// The failure isn't because of the version of description of the package, 483 /// The failure isn't because of the version of description of the package,
486 /// it's the package itself that can't be found, so just show the name and no 484 /// it's the package itself that can't be found, so just show the name and no
487 /// descriptive details. 485 /// descriptive details.
488 String _describeDependency(PackageDep dep) => ""; 486 String _describeDependency(PackageDep dep) => "";
489 } 487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698