diff options
Diffstat (limited to 'lib/bundler/resolver/strategy.rb')
| -rw-r--r-- | lib/bundler/resolver/strategy.rb | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/bundler/resolver/strategy.rb b/lib/bundler/resolver/strategy.rb new file mode 100644 index 0000000000..7519d38968 --- /dev/null +++ b/lib/bundler/resolver/strategy.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Bundler + class Resolver + class Strategy + def initialize(source) + @source = source + @package_priority_cache = {} + end + + def next_package_and_version(unsatisfied) + package, range = next_term_to_try_from(unsatisfied) + + [package, most_preferred_version_of(package, range).first] + end + + private + + def next_term_to_try_from(unsatisfied) + unsatisfied.min_by do |package, range| + @package_priority_cache[[package, range]] ||= begin + matching_versions = @source.versions_for(package, range) + higher_versions = @source.versions_for(package, range.upper_invert) + + [matching_versions.count <= 1 ? 0 : 1, higher_versions.count] + end + end + end + + def most_preferred_version_of(package, range) + versions = @source.versions_for(package, range) + + # Conditional avoids (among other things) calling + # sort_versions_by_preferred with the root package + if versions.size > 1 + @source.sort_versions_by_preferred(package, versions) + else + versions + end + end + end + end +end |
