ruby/lib/bundler/gem_helpers.rb

102 строки
3.2 KiB
Ruby

# frozen_string_literal: true
module Bundler
module GemHelpers
GENERIC_CACHE = {} # rubocop:disable MutableConstant
GENERICS = [
[Gem::Platform.new("java"), Gem::Platform.new("java")],
[Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
[Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")],
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze
def generic(p)
return p if p == Gem::Platform::RUBY
GENERIC_CACHE[p] ||= begin
_, found = GENERICS.find do |match, _generic|
p.os == match.os && (!match.cpu || p.cpu == match.cpu)
end
found || Gem::Platform::RUBY
end
end
module_function :generic
def generic_local_platform
generic(Bundler.local_platform)
end
module_function :generic_local_platform
def platform_specificity_match(spec_platform, user_platform)
spec_platform = Gem::Platform.new(spec_platform)
return PlatformMatch::EXACT_MATCH if spec_platform == user_platform
return PlatformMatch::WORST_MATCH if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
PlatformMatch.new(
PlatformMatch.os_match(spec_platform, user_platform),
PlatformMatch.cpu_match(spec_platform, user_platform),
PlatformMatch.platform_version_match(spec_platform, user_platform)
)
end
module_function :platform_specificity_match
def select_best_platform_match(specs, platform)
specs.select {|spec| spec.match_platform(platform) }.
min_by {|spec| platform_specificity_match(spec.platform, platform) }
end
module_function :select_best_platform_match
PlatformMatch = Struct.new(:os_match, :cpu_match, :platform_version_match)
class PlatformMatch
def <=>(other)
return nil unless other.is_a?(PlatformMatch)
m = os_match <=> other.os_match
return m unless m.zero?
m = cpu_match <=> other.cpu_match
return m unless m.zero?
m = platform_version_match <=> other.platform_version_match
m
end
EXACT_MATCH = new(-1, -1, -1).freeze
WORST_MATCH = new(1_000_000, 1_000_000, 1_000_000).freeze
def self.os_match(spec_platform, user_platform)
if spec_platform.os == user_platform.os
0
else
1
end
end
def self.cpu_match(spec_platform, user_platform)
if spec_platform.cpu == user_platform.cpu
0
elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm")
0
elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal"
1
else
2
end
end
def self.platform_version_match(spec_platform, user_platform)
if spec_platform.version == user_platform.version
0
elsif spec_platform.version.nil?
1
else
2
end
end
end
end
end