1# frozen_string_literal: true 2require "rubygems/deprecate" 3 4## 5# Available list of platforms for targeting Gem installations. 6# 7# See `gem help platform` for information on platform matching. 8 9class Gem::Platform 10 11 @local = nil 12 13 attr_accessor :cpu 14 15 attr_accessor :os 16 17 attr_accessor :version 18 19 def self.local 20 arch = RbConfig::CONFIG['arch'] 21 arch = "#{arch}_60" if arch =~ /mswin(?:32|64)$/ 22 @local ||= new(arch) 23 end 24 25 def self.match(platform) 26 Gem.platforms.any? do |local_platform| 27 platform.nil? or 28 local_platform == platform or 29 (local_platform != Gem::Platform::RUBY and local_platform =~ platform) 30 end 31 end 32 33 def self.installable?(spec) 34 if spec.respond_to? :installable_platform? 35 spec.installable_platform? 36 else 37 match spec.platform 38 end 39 end 40 41 def self.new(arch) # :nodoc: 42 case arch 43 when Gem::Platform::CURRENT then 44 Gem::Platform.local 45 when Gem::Platform::RUBY, nil, '' then 46 Gem::Platform::RUBY 47 else 48 super 49 end 50 end 51 52 def initialize(arch) 53 case arch 54 when Array then 55 @cpu, @os, @version = arch 56 when String then 57 arch = arch.split '-' 58 59 if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu 60 extra = arch.pop 61 arch.last << "-#{extra}" 62 end 63 64 cpu = arch.shift 65 66 @cpu = case cpu 67 when /i\d86/ then 'x86' 68 else cpu 69 end 70 71 if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ # for command-line 72 @os, @version = arch 73 return 74 end 75 76 os, = arch 77 @cpu, os = nil, cpu if os.nil? # legacy jruby 78 79 @os, @version = case os 80 when /aix(\d+)?/ then [ 'aix', $1 ] 81 when /cygwin/ then [ 'cygwin', nil ] 82 when /darwin(\d+)?/ then [ 'darwin', $1 ] 83 when /^macruby$/ then [ 'macruby', nil ] 84 when /freebsd(\d+)?/ then [ 'freebsd', $1 ] 85 when /hpux(\d+)?/ then [ 'hpux', $1 ] 86 when /^java$/, /^jruby$/ then [ 'java', nil ] 87 when /^java([\d.]*)/ then [ 'java', $1 ] 88 when /^dalvik(\d+)?$/ then [ 'dalvik', $1 ] 89 when /^dotnet$/ then [ 'dotnet', nil ] 90 when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ] 91 when /linux/ then [ 'linux', $1 ] 92 when /mingw32/ then [ 'mingw32', nil ] 93 when /(mswin\d+)(\_(\d+))?/ then 94 os, version = $1, $3 95 @cpu = 'x86' if @cpu.nil? and os =~ /32$/ 96 [os, version] 97 when /netbsdelf/ then [ 'netbsdelf', nil ] 98 when /openbsd(\d+\.\d+)?/ then [ 'openbsd', $1 ] 99 when /bitrig(\d+\.\d+)?/ then [ 'bitrig', $1 ] 100 when /solaris(\d+\.\d+)?/ then [ 'solaris', $1 ] 101 # test 102 when /^(\w+_platform)(\d+)?/ then [ $1, $2 ] 103 else [ 'unknown', nil ] 104 end 105 when Gem::Platform then 106 @cpu = arch.cpu 107 @os = arch.os 108 @version = arch.version 109 else 110 raise ArgumentError, "invalid argument #{arch.inspect}" 111 end 112 end 113 114 def inspect 115 "%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a] 116 end 117 118 def to_a 119 [@cpu, @os, @version] 120 end 121 122 def to_s 123 to_a.compact.join '-' 124 end 125 126 ## 127 # Is +other+ equal to this platform? Two platforms are equal if they have 128 # the same CPU, OS and version. 129 130 def ==(other) 131 self.class === other and to_a == other.to_a 132 end 133 134 alias :eql? :== 135 136 def hash # :nodoc: 137 to_a.hash 138 end 139 140 ## 141 # Does +other+ match this platform? Two platforms match if they have the 142 # same CPU, or either has a CPU of 'universal', they have the same OS, and 143 # they have the same version, or either has no version. 144 # 145 # Additionally, the platform will match if the local CPU is 'arm' and the 146 # other CPU starts with "arm" (for generic ARM family support). 147 148 def ===(other) 149 return nil unless Gem::Platform === other 150 151 # cpu 152 ([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or 153 (@cpu == 'arm' and other.cpu =~ /\Aarm/)) and 154 155 # os 156 @os == other.os and 157 158 # version 159 (@version.nil? or other.version.nil? or @version == other.version) 160 end 161 162 ## 163 # Does +other+ match this platform? If +other+ is a String it will be 164 # converted to a Gem::Platform first. See #=== for matching rules. 165 166 def =~(other) 167 case other 168 when Gem::Platform then # nop 169 when String then 170 # This data is from http://gems.rubyforge.org/gems/yaml on 19 Aug 2007 171 other = case other 172 when /^i686-darwin(\d)/ then ['x86', 'darwin', $1 ] 173 when /^i\d86-linux/ then ['x86', 'linux', nil ] 174 when 'java', 'jruby' then [nil, 'java', nil ] 175 when /^dalvik(\d+)?$/ then [nil, 'dalvik', $1 ] 176 when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ] 177 when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ] 178 when /mswin64(\_(\d+))?/ then ['x64', 'mswin64', $2 ] 179 when 'powerpc-darwin' then ['powerpc', 'darwin', nil ] 180 when /powerpc-darwin(\d)/ then ['powerpc', 'darwin', $1 ] 181 when /sparc-solaris2.8/ then ['sparc', 'solaris', '2.8' ] 182 when /universal-darwin(\d)/ then ['universal', 'darwin', $1 ] 183 else other 184 end 185 186 other = Gem::Platform.new other 187 else 188 return nil 189 end 190 191 self === other 192 end 193 194 ## 195 # A pure-Ruby gem that may use Gem::Specification#extensions to build 196 # binary files. 197 198 RUBY = 'ruby'.freeze 199 200 ## 201 # A platform-specific gem that is built for the packaging Ruby's platform. 202 # This will be replaced with Gem::Platform::local. 203 204 CURRENT = 'current'.freeze 205end 206