| Index: sdk/lib/_internal/pub_generated/lib/src/solver/version_solver.dart
|
| diff --git a/sdk/lib/_internal/pub_generated/lib/src/solver/version_solver.dart b/sdk/lib/_internal/pub_generated/lib/src/solver/version_solver.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..907152078d11f09256842ddf3784a4ad4a011547
|
| --- /dev/null
|
| +++ b/sdk/lib/_internal/pub_generated/lib/src/solver/version_solver.dart
|
| @@ -0,0 +1,269 @@
|
| +library pub.solver.version_solver;
|
| +import 'dart:async';
|
| +import "dart:convert";
|
| +import 'package:stack_trace/stack_trace.dart';
|
| +import '../exceptions.dart';
|
| +import '../lock_file.dart';
|
| +import '../log.dart' as log;
|
| +import '../package.dart';
|
| +import '../pubspec.dart';
|
| +import '../source_registry.dart';
|
| +import '../version.dart';
|
| +import '../utils.dart';
|
| +import 'backtracking_solver.dart';
|
| +import 'solve_report.dart';
|
| +Future<SolveResult> resolveVersions(SolveType type, SourceRegistry sources,
|
| + Package root, {LockFile lockFile, List<String> useLatest}) {
|
| + if (lockFile == null) lockFile = new LockFile.empty();
|
| + if (useLatest == null) useLatest = [];
|
| + return log.progress('Resolving dependencies', () {
|
| + return new BacktrackingSolver(
|
| + type,
|
| + sources,
|
| + root,
|
| + lockFile,
|
| + useLatest).solve();
|
| + });
|
| +}
|
| +class SolveResult {
|
| + bool get succeeded => error == null;
|
| + final List<PackageId> packages;
|
| + final List<PackageDep> overrides;
|
| + final Map<String, Pubspec> pubspecs;
|
| + final Map<String, List<Version>> availableVersions;
|
| + final SolveFailure error;
|
| + final int attemptedSolutions;
|
| + final SourceRegistry _sources;
|
| + final Package _root;
|
| + final LockFile _previousLockFile;
|
| + Set<String> get changedPackages {
|
| + if (packages == null) return null;
|
| + var changed = packages.where(
|
| + (id) =>
|
| + !_sources.idsEqual(
|
| + _previousLockFile.packages[id.name],
|
| + id)).map((id) => id.name).toSet();
|
| + return changed.union(
|
| + _previousLockFile.packages.keys.where(
|
| + (package) => !availableVersions.containsKey(package)).toSet());
|
| + }
|
| + SolveResult.success(this._sources, this._root, this._previousLockFile,
|
| + this.packages, this.overrides, this.pubspecs, this.availableVersions,
|
| + this.attemptedSolutions)
|
| + : error = null;
|
| + SolveResult.failure(this._sources, this._root, this._previousLockFile,
|
| + this.overrides, this.error, this.attemptedSolutions)
|
| + : this.packages = null,
|
| + this.pubspecs = null,
|
| + this.availableVersions = {};
|
| + void showReport(SolveType type) {
|
| + new SolveReport(type, _sources, _root, _previousLockFile, this).show();
|
| + }
|
| + void summarizeChanges(SolveType type, {bool dryRun: false}) {
|
| + new SolveReport(
|
| + type,
|
| + _sources,
|
| + _root,
|
| + _previousLockFile,
|
| + this).summarize(dryRun: dryRun);
|
| + }
|
| + String toString() {
|
| + if (!succeeded) {
|
| + return 'Failed to solve after $attemptedSolutions attempts:\n' '$error';
|
| + }
|
| + return 'Took $attemptedSolutions tries to resolve to\n'
|
| + '- ${packages.join("\n- ")}';
|
| + }
|
| +}
|
| +class PubspecCache {
|
| + final SourceRegistry _sources;
|
| + final _versions = new Map<PackageRef, List<PackageId>>();
|
| + final _versionErrors = new Map<PackageRef, Pair<Object, Chain>>();
|
| + final _pubspecs = new Map<PackageId, Pubspec>();
|
| + final SolveType _type;
|
| + int _versionCacheMisses = 0;
|
| + int _versionCacheHits = 0;
|
| + int _pubspecCacheMisses = 0;
|
| + int _pubspecCacheHits = 0;
|
| + PubspecCache(this._type, this._sources);
|
| + void cache(PackageId id, Pubspec pubspec) {
|
| + _pubspecs[id] = pubspec;
|
| + }
|
| + Future<Pubspec> getPubspec(PackageId id) {
|
| + if (_pubspecs.containsKey(id)) {
|
| + _pubspecCacheHits++;
|
| + return new Future<Pubspec>.value(_pubspecs[id]);
|
| + }
|
| + _pubspecCacheMisses++;
|
| + var source = _sources[id.source];
|
| + return source.describe(id).then((pubspec) {
|
| + _pubspecs[id] = pubspec;
|
| + return pubspec;
|
| + });
|
| + }
|
| + Pubspec getCachedPubspec(PackageId id) => _pubspecs[id];
|
| + Future<List<PackageId>> getVersions(PackageRef package) {
|
| + if (package.isRoot) {
|
| + throw new StateError("Cannot get versions for root package $package.");
|
| + }
|
| + var versions = _versions[package];
|
| + if (versions != null) {
|
| + _versionCacheHits++;
|
| + return new Future.value(versions);
|
| + }
|
| + var error = _versionErrors[package];
|
| + if (error != null) {
|
| + _versionCacheHits++;
|
| + return new Future.error(error.first, error.last);
|
| + }
|
| + _versionCacheMisses++;
|
| + var source = _sources[package.source];
|
| + return source.getVersions(
|
| + package.name,
|
| + package.description).then((versions) {
|
| + versions.sort(
|
| + _type == SolveType.DOWNGRADE ? Version.antiPrioritize : Version.prioritize);
|
| + var ids =
|
| + versions.reversed.map((version) => package.atVersion(version)).toList();
|
| + _versions[package] = ids;
|
| + return ids;
|
| + }).catchError((error, trace) {
|
| + log.solver("Could not get versions for $package:\n$error\n\n$trace");
|
| + _versionErrors[package] = new Pair(error, new Chain.forTrace(trace));
|
| + throw error;
|
| + });
|
| + }
|
| + List<PackageId> getCachedVersions(PackageRef package) => _versions[package];
|
| + String describeResults() {
|
| + var results = '''- Requested $_versionCacheMisses version lists
|
| +- Looked up $_versionCacheHits cached version lists
|
| +- Requested $_pubspecCacheMisses pubspecs
|
| +- Looked up $_pubspecCacheHits cached pubspecs
|
| +''';
|
| + return results;
|
| + }
|
| + String _debugDescribePackageGraph() {
|
| + var packages = {};
|
| + _pubspecs.forEach((id, pubspec) {
|
| + var deps = {};
|
| + packages["${id.name} ${id.version}"] = deps;
|
| + for (var dep in pubspec.dependencies) {
|
| + deps[dep.name] = dep.constraint.toString();
|
| + }
|
| + });
|
| + _versions.forEach((ref, versions) {
|
| + for (var id in versions) {
|
| + packages.putIfAbsent("${id.name} ${id.version}", () => {});
|
| + }
|
| + });
|
| + return JSON.encode(packages);
|
| + }
|
| +}
|
| +class Dependency {
|
| + final String depender;
|
| + final Version dependerVersion;
|
| + final PackageDep dep;
|
| + bool get isMagic => depender.contains(" ");
|
| + Dependency(this.depender, this.dependerVersion, this.dep);
|
| + String toString() => '$depender $dependerVersion -> $dep';
|
| +}
|
| +class SolveType {
|
| + static const GET = const SolveType._("get");
|
| + static const UPGRADE = const SolveType._("upgrade");
|
| + static const DOWNGRADE = const SolveType._("downgrade");
|
| + final String _name;
|
| + const SolveType._(this._name);
|
| + String toString() => _name;
|
| +}
|
| +abstract class SolveFailure implements ApplicationException {
|
| + final String package;
|
| + final Iterable<Dependency> dependencies;
|
| + String get message => toString();
|
| + String get _message {
|
| + throw new UnimplementedError("Must override _message or toString().");
|
| + }
|
| + SolveFailure(this.package, Iterable<Dependency> dependencies)
|
| + : dependencies = dependencies != null ? dependencies : <Dependency>[];
|
| + String toString() {
|
| + if (dependencies.isEmpty) return _message;
|
| + var buffer = new StringBuffer();
|
| + buffer.write("$_message:");
|
| + var sorted = dependencies.toList();
|
| + sorted.sort((a, b) => a.depender.compareTo(b.depender));
|
| + for (var dep in sorted) {
|
| + buffer.writeln();
|
| + buffer.write("- ${log.bold(dep.depender)}");
|
| + if (!dep.isMagic) buffer.write(" ${dep.dependerVersion}");
|
| + buffer.write(" ${_describeDependency(dep.dep)}");
|
| + }
|
| + return buffer.toString();
|
| + }
|
| + String _describeDependency(PackageDep dep) =>
|
| + "depends on version ${dep.constraint}";
|
| +}
|
| +class BadSdkVersionException extends SolveFailure {
|
| + final String _message;
|
| + BadSdkVersionException(String package, String message)
|
| + : super(package, null),
|
| + _message = message;
|
| +}
|
| +class NoVersionException extends SolveFailure {
|
| + final VersionConstraint constraint;
|
| + final Version version;
|
| + NoVersionException(String package, this.version, this.constraint,
|
| + Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String get _message {
|
| + if (version == null) {
|
| + return "Package $package has no versions that match $constraint derived "
|
| + "from";
|
| + }
|
| + return "Package $package $version does not match $constraint derived from";
|
| + }
|
| +}
|
| +class CouldNotUpgradeException extends SolveFailure {
|
| + final VersionConstraint constraint;
|
| + final Version best;
|
| + CouldNotUpgradeException(String package, this.constraint, this.best)
|
| + : super(package, null);
|
| + String get _message =>
|
| + "The latest version of $package, $best, does not match $constraint.";
|
| +}
|
| +class DisjointConstraintException extends SolveFailure {
|
| + DisjointConstraintException(String package, Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String get _message => "Incompatible version constraints on $package";
|
| +}
|
| +class SourceMismatchException extends SolveFailure {
|
| + String get _message => "Incompatible dependencies on $package";
|
| + SourceMismatchException(String package, Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String _describeDependency(PackageDep dep) =>
|
| + "depends on it from source ${dep.source}";
|
| +}
|
| +class UnknownSourceException extends SolveFailure {
|
| + UnknownSourceException(String package, Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String toString() {
|
| + var dep = dependencies.single;
|
| + return 'Package ${dep.depender} depends on ${dep.dep.name} from unknown '
|
| + 'source "${dep.dep.source}".';
|
| + }
|
| +}
|
| +class DescriptionMismatchException extends SolveFailure {
|
| + String get _message => "Incompatible dependencies on $package";
|
| + DescriptionMismatchException(String package,
|
| + Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String _describeDependency(PackageDep dep) {
|
| + return "depends on it with description ${JSON.encode(dep.description)}";
|
| + }
|
| +}
|
| +class DependencyNotFoundException extends SolveFailure {
|
| + final PackageNotFoundException _innerException;
|
| + String get _message => "${_innerException.message}\nDepended on by";
|
| + DependencyNotFoundException(String package, this._innerException,
|
| + Iterable<Dependency> dependencies)
|
| + : super(package, dependencies);
|
| + String _describeDependency(PackageDep dep) => "";
|
| +}
|
|
|