lib/cocoapods-core/platform.rb
module Pod
# A Platform describes an SDK name and deployment target.
#
class Platform
# @return [Symbol, String] the name of the SDK represented by the platform.
#
attr_reader :symbolic_name
alias_method :name, :symbolic_name
# @return [Version] the deployment target of the platform.
#
attr_reader :deployment_target
# Constructs a platform from either another platform or by
# specifying the symbolic name and optionally the deployment target.
#
# @overload initialize(name, deployment_target)
#
# @param [Symbol, String] name
# the name of platform.
#
# @param [String, Version] deployment_target
# the optional deployment.
#
# @note If the deployment target is not provided a default deployment
# target will not be assigned.
#
# @example Initialization with symbol
#
# Platform.new(:ios)
# Platform.new(:ios, '4.3')
#
# @overload initialize(platform)
#
# @param [Platform] platform
# Another {Platform}.
#
# @example Initialization with another platform
#
# platform = Platform.new(:ios)
# Platform.new(platform)
#
def initialize(input, target = nil)
if input.is_a? Platform
@symbolic_name = input.name
@deployment_target = input.deployment_target
else
input = input.to_s.downcase
name = case input
when 'macos'
# Allow `Platform.new('macos')` to be equivalent to `Platform.macos`
'osx'
when 'xros'
# Compatibility with older references to 'xrOS'
'visionos'
else
input
end
@symbolic_name = name.to_sym
target = target[:deployment_target] if target.is_a?(Hash)
@deployment_target = Version.create(target)
end
end
# Convenience method to initialize an iOS platform.
#
# @return [Platform] an iOS platform.
#
def self.ios
new :ios
end
# Convenience method to initialize an OS X platform.
#
# @return [Platform] an OS X platform.
#
def self.osx
new :osx
end
# Convenience method to initialize a macOS platform.
#
# @return [Platform] a macOS platform.
#
def self.macos
osx
end
# Convenience method to initialize a tvOS platform.
#
# @return [Platform] a tvOS platform.
#
def self.tvos
new :tvos
end
# Convenience method to initialize a visionOS platform.
#
# @return [Platform] a visionOS platform.
#
def self.visionos
new :visionos
end
# Convenience method to initialize a watchOS platform.
#
# @return [Platform] a watchOS platform.
#
def self.watchos
new :watchos
end
# Convenience method to get all available platforms.
#
# @return [Array<Platform>] list of platforms.
#
def self.all
[ios, osx, watchos, visionos, tvos]
end
# Checks if a platform is equivalent to another one or to a symbol
# representation.
#
# @param [Platform, Symbol] other
# the other platform to check.
#
# @note If a symbol is passed the comparison does not take into account
# the deployment target.
#
# @return [Boolean] whether two platforms are the equivalent.
#
def ==(other)
if other.is_a?(Symbol)
@symbolic_name == other
else
(name == other.name) && (deployment_target == other.deployment_target)
end
end
# (see #==)
alias_method :eql?, :==
# Hashes the instance by the platform name and deployment target.
#
# This adds support to make instances usable as Hash keys.
#
# @!visibility private
def hash
name.hash ^ deployment_target.hash
end
# Checks whether a platform supports another one.
#
# In the context of operating system SDKs, a platform supports another
# one if they have the same name and the other platform has a minor or
# equal deployment target.
#
# @return [Boolean] whether the platform supports another platform.
#
def supports?(other)
other = Platform.new(other)
if other.deployment_target && deployment_target
(other.name == name) && (other.deployment_target <= deployment_target)
else
other.name == name
end
end
# @return [String] a string representation that includes the deployment
# target.
#
def to_s
s = self.class.string_name(@symbolic_name)
s << " #{deployment_target}" if deployment_target
s
end
# @return [String] the debug representation.
#
def inspect
"#<#{self.class.name} name=#{name.inspect} " \
"deployment_target=#{deployment_target.inspect}>"
end
# @return [Symbol] a symbol representing the name of the platform.
#
def to_sym
name
end
# Compares the platform first by name and the by deployment_target for
# sorting.
#
# @param [Platform] other
# The other platform to compare.
#
# @return [Fixnum] -1, 0, or +1 depending on whether the receiver is less
# than, equal to, or greater than other.
#
def <=>(other)
name_sort = name.to_s <=> other.name.to_s
if name_sort.zero?
deployment_target <=> other.deployment_target
else
name_sort
end
end
# @return [Boolean] whether the platform requires legacy architectures for
# iOS.
#
def requires_legacy_ios_archs?
if name == :ios
deployment_target && (deployment_target < Version.new('4.3'))
else
false
end
end
# @return [Boolean] whether the platform supports dynamic frameworks.
#
def supports_dynamic_frameworks?
if name == :ios
deployment_target && (deployment_target >= Version.new(8.0))
else
true
end
end
# @return [String] The string that describes the #symbolic_name.
#
def string_name
self.class.string_name(symbolic_name)
end
# @return [String] The string that describes the #symbolic_name,
# which doesn't contain spaces and is so safe to use in
# paths which might not be quoted or escaped consequently.
def safe_string_name
string_name.tr(' ', '')
end
# Converts the symbolic name of a platform to a string name suitable to be
# presented to the user.
#
# @param [Symbol] symbolic_name
# the symbolic name of a platform.
#
# @return [String] The string that describes the name of the given symbol.
#
def self.string_name(symbolic_name)
case symbolic_name
when :ios then 'iOS'
when :osx then 'macOS'
when :watchos then 'watchOS'
when :tvos then 'tvOS'
when :visionos then 'visionOS'
else symbolic_name.to_s
end
end
end
end