1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
# frozen_string_literal: true
module Bundler
module GemHelpers
GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant
GENERICS = [
Gem::Platform::JAVA,
*Gem::Platform::WINDOWS,
].freeze
def generic(p)
GENERIC_CACHE[p] ||= begin
found = GENERICS.find do |match|
p === match
end
found || Gem::Platform::RUBY
end
end
module_function :generic
def generic_local_platform
generic(local_platform)
end
module_function :generic_local_platform
def local_platform
Bundler.local_platform
end
module_function :local_platform
def generic_local_platform_is_ruby?
generic_local_platform == Gem::Platform::RUBY
end
module_function :generic_local_platform_is_ruby?
def platform_specificity_match(spec_platform, user_platform)
spec_platform = Gem::Platform.new(spec_platform)
PlatformMatch.specificity_score(spec_platform, user_platform)
end
module_function :platform_specificity_match
def select_all_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
matching = if force_ruby
specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! }
else
specs.select {|spec| spec.match_platform(platform) }
end
if prefer_locked
locked_originally = matching.select {|spec| spec.is_a?(LazySpecification) }
return locked_originally if locked_originally.any?
end
matching
end
module_function :select_all_platform_match
def select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
matching = select_all_platform_match(specs, platform, force_ruby: force_ruby, prefer_locked: prefer_locked)
sort_and_filter_best_platform_match(matching, platform)
end
module_function :select_best_platform_match
def select_best_local_platform_match(specs, force_ruby: false)
matching = select_all_platform_match(specs, local_platform, force_ruby: force_ruby).filter_map(&:materialized_for_installation)
sort_best_platform_match(matching, local_platform)
end
module_function :select_best_local_platform_match
def sort_and_filter_best_platform_match(matching, platform)
return matching if matching.one?
exact = matching.select {|spec| spec.platform == platform }
return exact if exact.any?
sorted_matching = sort_best_platform_match(matching, platform)
exemplary_spec = sorted_matching.first
sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
end
module_function :sort_and_filter_best_platform_match
def sort_best_platform_match(matching, platform)
matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) }
end
module_function :sort_best_platform_match
class PlatformMatch
def self.specificity_score(spec_platform, user_platform)
return -1 if spec_platform == user_platform
return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
os_match(spec_platform, user_platform) +
cpu_match(spec_platform, user_platform) * 10 +
platform_version_match(spec_platform, user_platform) * 100
end
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
def same_specificity(platform, spec, exemplary_spec)
platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform)
end
module_function :same_specificity
def same_deps(spec, exemplary_spec)
same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort
same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version
same_runtime_deps && same_metadata_deps
end
module_function :same_deps
end
end
|