diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb index dce20d37ad..27f0e39d4c 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb @@ -164,7 +164,7 @@ module Bundler::PubGrub sorted_versions[high] end - range = VersionRange.new(min: low, max: high, include_min: true) + range = VersionRange.new(min: low, max: high, include_min: !low.nil?) self_constraint = VersionConstraint.new(package, range: range) diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb index 8d73c3f7b5..49dcf716a3 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb @@ -76,6 +76,9 @@ module Bundler::PubGrub end def initialize(min: nil, max: nil, include_min: false, include_max: false, name: nil) + raise ArgumentError, "Ranges without a lower bound cannot have include_min == true" if !min && include_min == true + raise ArgumentError, "Ranges without an upper bound cannot have include_max == true" if !max && include_max == true + @min = min @max = max @include_min = include_min @@ -311,10 +314,19 @@ module Bundler::PubGrub def contiguous_to?(other) return false if other.empty? + return true if any? - intersects?(other) || - (min == other.max && (include_min || other.include_max)) || - (max == other.min && (include_max || other.include_min)) + intersects?(other) || contiguous_below?(other) || contiguous_above?(other) + end + + def contiguous_below?(other) + return false if !max || !other.min + + max == other.min && (include_max || other.include_min) + end + + def contiguous_above?(other) + other.contiguous_below?(self) end def allows_all?(other) @@ -375,15 +387,15 @@ module Bundler::PubGrub def invert return self.class.empty if any? - low = VersionRange.new(max: min, include_max: !include_min) - high = VersionRange.new(min: max, include_min: !include_max) + low = -> { VersionRange.new(max: min, include_max: !include_min) } + high = -> { VersionRange.new(min: max, include_min: !include_max) } if !min - high + high.call elsif !max - low + low.call else - low.union(high) + low.call.union(high.call) end end diff --git a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb index 4caf6b355b..b56b8ce43e 100644 --- a/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +++ b/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb @@ -36,26 +36,25 @@ module Bundler::PubGrub # Returns true if there is more work to be done, false otherwise def work - return false if solved? - - next_package = choose_package_version - propagate(next_package) - - if solved? + unsatisfied_terms = solution.unsatisfied + if unsatisfied_terms.empty? logger.info { "Solution found after #{solution.attempted_solutions} attempts:" } solution.decisions.each do |package, version| next if Package.root?(package) logger.info { "* #{package} #{version}" } end - false - else - true + return false end + + next_package = choose_package_version_from(unsatisfied_terms) + propagate(next_package) + + true end def solve - work until solved? + while work; end solution.decisions end @@ -105,25 +104,21 @@ module Bundler::PubGrub unsatisfied.package end - def next_package_to_try - solution.unsatisfied.min_by do |term| + def next_term_to_try_from(unsatisfied_terms) + unsatisfied_terms.min_by do |term| package = term.package range = term.constraint.range 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.package + end end - def choose_package_version - if solution.unsatisfied.empty? - logger.info "No packages unsatisfied. Solving complete!" - return nil - end + def choose_package_version_from(unsatisfied_terms) + unsatisfied_term = next_term_to_try_from(unsatisfied_terms) + package = unsatisfied_term.package - package = next_package_to_try - unsatisfied_term = solution.unsatisfied.find { |t| t.package == package } version = source.versions_for(package, unsatisfied_term.constraint.range).first logger.debug { "attempting #{package} #{version}" } diff --git a/tool/bundler/vendor_gems.rb b/tool/bundler/vendor_gems.rb index bef955655f..16fe53a5d8 100644 --- a/tool/bundler/vendor_gems.rb +++ b/tool/bundler/vendor_gems.rb @@ -8,7 +8,7 @@ gem "net-http", "0.6.0" gem "net-http-persistent", "4.0.4" gem "net-protocol", "0.2.2" gem "optparse", "0.6.0" -gem "pub_grub", github: "jhawthorn/pub_grub" +gem "pub_grub", github: "jhawthorn/pub_grub", ref: "57d4f344366c8b86f7fe506e9bfa08f3c731e397" gem "resolv", "0.6.0" gem "securerandom", "0.4.1" gem "timeout", "0.4.3" diff --git a/tool/bundler/vendor_gems.rb.lock b/tool/bundler/vendor_gems.rb.lock index 3c3ec50832..79eca0e7c0 100644 --- a/tool/bundler/vendor_gems.rb.lock +++ b/tool/bundler/vendor_gems.rb.lock @@ -6,7 +6,8 @@ GIT GIT remote: https://github.com/jhawthorn/pub_grub.git - revision: 55a2d65c5c3176f72de5e25d59fb6f52b9fe60ef + revision: 57d4f344366c8b86f7fe506e9bfa08f3c731e397 + ref: 57d4f344366c8b86f7fe506e9bfa08f3c731e397 specs: pub_grub (0.5.0)