diff options
Diffstat (limited to 'lib/bundler/resolver/candidate.rb')
-rw-r--r-- | lib/bundler/resolver/candidate.rb | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/bundler/resolver/candidate.rb b/lib/bundler/resolver/candidate.rb new file mode 100644 index 0000000000..9e8b913335 --- /dev/null +++ b/lib/bundler/resolver/candidate.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require_relative "spec_group" + +module Bundler + class Resolver + # + # This class is a PubGrub compatible "Version" class that takes Bundler + # resolution complexities into account. + # + # Each Resolver::Candidate has a underlying `Gem::Version` plus a set of + # platforms. For example, 1.1.0-x86_64-linux is a different resolution candidate + # from 1.1.0 (generic). This is because different platform variants of the + # same gem version can bring different dependencies, so they need to be + # considered separately. + # + # Some candidates may also keep some information explicitly about the + # package they refer to. These candidates are referred to as "canonical" and + # are used when materializing resolution results back into RubyGems + # specifications that can be installed, written to lock files, and so on. + # + class Candidate + include Comparable + + attr_reader :version + + def initialize(version, specs: []) + @spec_group = Resolver::SpecGroup.new(specs) + @version = Gem::Version.new(version) + @ruby_only = specs.map(&:platform).uniq == [Gem::Platform::RUBY] + end + + def dependencies + @spec_group.dependencies + end + + def to_specs(package) + return [] if package.meta? + + @spec_group.to_specs(package.force_ruby_platform?) + end + + def generic! + @ruby_only = true + + self + end + + def platform_specific! + @ruby_only = false + + self + end + + def prerelease? + @version.prerelease? + end + + def segments + @version.segments + end + + def sort_obj + [@version, @ruby_only ? -1 : 1] + end + + def <=>(other) + return unless other.is_a?(self.class) + + sort_obj <=> other.sort_obj + end + + def ==(other) + return unless other.is_a?(self.class) + + sort_obj == other.sort_obj + end + + def eql?(other) + return unless other.is_a?(self.class) + + sort_obj.eql?(other.sort_obj) + end + + def hash + sort_obj.hash + end + + def to_s + @version.to_s + end + end + end +end |