class Pod::Specification

The Specification provides a DSL to describe a Pod. A pod is defined as a library originating from a source. A specification can support detailed attributes for modules of code through subspecs.

Usually it is stored in files with `podspec` extension.

Attributes

app_specification[RW]

@return [Bool] If this specification is an app specification.

app_specification?[RW]

@return [Bool] If this specification is an app specification.

attributes_hash[RW]

@return [Hash] the hash that stores the information of the attributes of

the specification.
hash_value[R]

@return [Integer] the cached hash value for this spec.

parent[R]

@return [Specification] the parent of the specification unless the

specification is a root.
subspecs[RW]

@return [Array<Specification>] The subspecs of the specification.

test_specification[RW]

@return [Bool] If this specification is a test specification.

test_specification?[RW]

@return [Bool] If this specification is a test specification.

Public Class Methods

convert_keys_to_string(value, recursive: true) click to toggle source

Converts the keys of the given hash to a string.

@param [Object] value

the value that needs to be stripped from the Symbols.

@param [Boolean] recursive

whether to convert keys of nested hashes.

@return [Hash] the hash with the keys as strings instead of symbols.

# File lib/cocoapods-core/specification.rb, line 633
def self.convert_keys_to_string(value, recursive: true)
  return unless value
  result = {}
  value.each do |key, subvalue|
    subvalue = Specification.convert_keys_to_string(subvalue) if recursive && subvalue.is_a?(Hash)
    result[key.to_s] = subvalue
  end
  result
end
convert_keys_to_symbol(value, recursive: true) click to toggle source

Converts the keys of the given hash to a symbol.

@param [Object] value

the value that needs to be stripped from the Strings.

@param [Boolean] recursive

whether to convert keys of nested hashes.

@return [Hash] the hash with the keys as symbols instead of strings.

# File lib/cocoapods-core/specification.rb, line 653
def self.convert_keys_to_symbol(value, recursive: true)
  return unless value
  result = {}
  value.each do |key, subvalue|
    subvalue = Specification.convert_keys_to_symbol(subvalue) if recursive && subvalue.is_a?(Hash)
    result[key.to_sym] = subvalue
  end
  result
end
from_file(path, subspec_name = nil) click to toggle source

Loads a specification form the given path.

@param [Pathname, String] path

the path of the `podspec` file.

@param [String] subspec_name

the name of the specification that should be returned. If it is
nil returns the root specification.

@raise If the file doesn't return a Pods::Specification after

evaluation.

@return [Specification] the specification

# File lib/cocoapods-core/specification.rb, line 710
def self.from_file(path, subspec_name = nil)
  path = Pathname.new(path)
  unless path.exist?
    raise Informative, "No podspec exists at path `#{path}`."
  end

  string = File.open(path, 'r:utf-8', &:read)
  # Work around for Rubinius incomplete encoding in 1.9 mode
  if string.respond_to?(:encoding) && string.encoding.name != 'UTF-8'
    string.encode!('UTF-8')
  end

  from_string(string, path, subspec_name)
end
from_hash(hash, parent = nil, test_specification: false, app_specification: false) click to toggle source

Configures a new specification from the given hash.

@param [Hash] hash the hash which contains the information of the

specification.

@param [Specification] parent the parent of the specification unless the

specification is a root.

@return [Specification] the specification

# File lib/cocoapods-core/specification/json.rb, line 75
def self.from_hash(hash, parent = nil, test_specification: false, app_specification: false)
  attributes_hash = hash.dup
  spec = Spec.new(parent, nil, test_specification, :app_specification => app_specification)
  subspecs = attributes_hash.delete('subspecs')
  testspecs = attributes_hash.delete('testspecs')
  appspecs = attributes_hash.delete('appspecs')

  ## backwards compatibility with 1.3.0
  spec.test_specification = !attributes_hash['test_type'].nil?

  spec.attributes_hash = attributes_hash
  spec.subspecs.concat(subspecs_from_hash(spec, subspecs, false, false))
  spec.subspecs.concat(subspecs_from_hash(spec, testspecs, true, false))
  spec.subspecs.concat(subspecs_from_hash(spec, appspecs, false, true))

  spec
end
from_json(json) click to toggle source

Configures a new specification from the given JSON representation.

@param [String] the JSON encoded hash which contains the information of

the specification.

@return [Specification] the specification

# File lib/cocoapods-core/specification/json.rb, line 59
def self.from_json(json)
  require 'json'
  hash = JSON.parse(json)
  from_hash(hash)
end
from_string(spec_contents, path, subspec_name = nil) click to toggle source

Loads a specification with the given string. The specification is evaluated in the context of `path`.

@param [String] spec_contents

A string describing a specification.

@param [Pathname, String] path @see from_file @param [String] subspec_name @see from_file

@return [Specification] the specification

# File lib/cocoapods-core/specification.rb, line 736
def self.from_string(spec_contents, path, subspec_name = nil)
  path = Pathname.new(path).expand_path
  spec = nil
  case path.extname
  when '.podspec'
    Dir.chdir(path.parent.directory? ? path.parent : Dir.pwd) do
      spec = ::Pod._eval_podspec(spec_contents, path)
      unless spec.is_a?(Specification)
        raise Informative, "Invalid podspec file at path `#{path}`."
      end
    end
  when '.json'
    spec = Specification.from_json(spec_contents)
  else
    raise Informative, "Unsupported specification format `#{path.extname}` for spec at `#{path}`."
  end

  spec.defined_in_file = path
  spec.subspec_by_name(subspec_name, true)
end
name_and_version_from_string(string_representation) click to toggle source

@param [String] string_representation

the string that describes a {Specification} generated from
{Specification#to_s}.

@example Input examples

"libPusher (1.0)"
"RestKit/JSON (1.0)"

@return [Array<String, Version>] the name and the version of a

pod.
# File lib/cocoapods-core/specification.rb, line 156
def self.name_and_version_from_string(string_representation)
  match_data = string_representation.match(/\A((?:\s?[^\s(])+)(?: \((.+)\))?\Z/)
  unless match_data
    raise Informative, 'Invalid string representation for a ' \
      "specification: `#{string_representation}`. " \
      'The string representation should include the name and ' \
      'optionally the version of the Pod.'
  end
  name = match_data[1]
  vers = Version.new(match_data[2])
  [name, vers]
end
new(parent = nil, name = nil, test_specification = false, app_specification: false) { |self| ... } click to toggle source

@param [Specification] parent @see parent

@param [String] name

the name of the specification.

@param [Bool] test_specification

Whether the specification is a test specification

@param [Bool] app_specification

Whether the specification is an app specification
# File lib/cocoapods-core/specification.rb, line 43
def initialize(parent = nil, name = nil, test_specification = false, app_specification: false)
  raise StandardError, "#{self} can not be both an app and test specification." if test_specification && app_specification
  @attributes_hash = {}
  @subspecs = []
  @consumers = {}
  @parent = parent
  @hash_value = nil
  @test_specification = test_specification
  @app_specification = app_specification
  attributes_hash['name'] = name
  attributes_hash['test_type'] = :unit if test_specification

  yield self if block_given?
end
root_name(full_name) click to toggle source

Returns the root name of a specification.

@param [String] the name of a specification or of a subspec.

@return [String] the root name

# File lib/cocoapods-core/specification.rb, line 175
def self.root_name(full_name)
  full_name.split('/', 2).first
end
subspecs_from_hash(spec, subspecs, test_specification, app_specification) click to toggle source
# File lib/cocoapods-core/specification/json.rb, line 93
def self.subspecs_from_hash(spec, subspecs, test_specification, app_specification)
  return [] if subspecs.nil?
  subspecs.map do |s_hash|
    Specification.from_hash(s_hash, spec,
                            :test_specification => test_specification,
                            :app_specification => app_specification)
  end
end

Public Instance Methods

==(other) click to toggle source

Checks if a specification is equal to the given one according its name and to its version.

@param [Specification] other

the specification to compare with.

@todo Not sure if comparing only the name and the version is the way to

go. This is used by the installer to group specifications by root
spec.

@return [Bool] Whether the specifications are equal.

# File lib/cocoapods-core/specification.rb, line 99
def ==(other)
  other.is_a?(self.class) &&
    name == other.name &&
    version == other.version
end
Also aliased as: eql?
all_dependencies(platform = nil) click to toggle source

@return [Array<Dependency>] all the dependencies of the specification.

# File lib/cocoapods-core/specification.rb, line 410
def all_dependencies(platform = nil)
  dependencies(platform) + subspec_dependencies(platform)
end
app_specs() click to toggle source

@return [Array<Specification>] the list of all the app subspecs of

a specification.
# File lib/cocoapods-core/specification.rb, line 287
def app_specs
  subspecs.select(&:app_specification?)
end
available_platforms() click to toggle source

@return [Array<Platform>] The platforms that the Pod is supported on.

@note If no platform is specified, this method returns all known

platforms.
# File lib/cocoapods-core/specification.rb, line 520
def available_platforms
  names = supported_platform_names
  names = PLATFORMS if names.empty?
  names.map { |name| Platform.new(name, deployment_target(name)) }
end
checksum() click to toggle source

@return [String] The SHA1 digest of the file in which the specification

is defined.

@return [Nil] If the specification is not defined in a file.

# File lib/cocoapods-core/specification.rb, line 674
def checksum
  @checksum ||= begin
    if root?
      unless defined_in_file.nil?
        require 'digest'
        checksum = Digest::SHA1.hexdigest(File.read(defined_in_file))
        checksum = checksum.encode('UTF-8') if checksum.respond_to?(:encode)
        checksum
      end
    else
      root.checksum
    end
  end
end
consumer(platform) click to toggle source

Returns a consumer to access the multi-platform attributes.

@param [String, Symbol, Platform] platform

the platform of the consumer

@return [Specification::Consumer] the consumer for the given platform

# File lib/cocoapods-core/specification.rb, line 440
def consumer(platform)
  platform = platform.to_sym
  @consumers[platform] ||= Consumer.new(self, platform)
end
default_subspecs() click to toggle source

@return [Array<String>, Symbol] the name(s) of the default subspecs if provided or :none for no default subspecs.

# File lib/cocoapods-core/specification.rb, line 351
def default_subspecs
  # TODO: remove singular form and update the JSON specs.
  value = Array(attributes_hash['default_subspecs'] || attributes_hash['default_subspec'])
  first = value.first
  if first == :none || first == 'none'
    first.to_sym
  else
    value
  end
end
defined_in_file() click to toggle source

@return [String] the path where the specification is defined, if loaded

from a file.
# File lib/cocoapods-core/specification.rb, line 692
def defined_in_file
  root? ? @defined_in_file : root.defined_in_file
end
defined_in_file=(file) click to toggle source

Sets the path of the `podspec` file used to load the specification.

@param [String] file

the `podspec` file.

@return [void]

@visibility private

# File lib/cocoapods-core/specification.rb, line 766
def defined_in_file=(file)
  unless root?
    raise StandardError, 'Defined in file can be set only for root specs.'
  end
  @defined_in_file = file
end
dependencies(platform = nil) click to toggle source

Returns the dependencies on other Pods or subspecs of other Pods.

@param [Platform] platform

return only dependencies supported on the given platform.

@note External dependencies are inherited by subspecs

@return [Array<Dependency>] the dependencies on other Pods.

# File lib/cocoapods-core/specification.rb, line 398
def dependencies(platform = nil)
  if platform
    consumer(platform).dependencies || []
  else
    available_platforms.map do |spec_platform|
      consumer(spec_platform).dependencies
    end.flatten.uniq
  end
end
dependency_whitelisted_for_configuration?(dependency, configuration) click to toggle source

Returns whether a dependency is whitelisted for the given configuration.

@param [Pod::Dependency] dependency

the dependency verify.

@param [Symbol, String] configuration

the configuration to check against.

@return [Bool] whether the dependency is whitelisted or not.

# File lib/cocoapods-core/specification.rb, line 424
def dependency_whitelisted_for_configuration?(dependency, configuration)
  inherited = -> { root? ? true : parent.dependency_whitelisted_for_configuration?(dependency, configuration) }

  return inherited[] unless configuration_whitelist = attributes_hash['configuration_pod_whitelist']
  return inherited[] unless whitelist_for_pod = configuration_whitelist[dependency.name]

  whitelist_for_pod.include?(configuration.to_s.downcase)
end
deployment_target(platform_name) click to toggle source

Returns the deployment target for the specified platform.

@param [String] platform_name

the symbolic name of the platform.

@return [String] the deployment target @return [Nil] if not deployment target was specified for the platform.

# File lib/cocoapods-core/specification.rb, line 534
def deployment_target(platform_name)
  result = platform_hash[platform_name.to_s]
  result ||= parent.deployment_target(platform_name) if parent
  result
end
eql?(other)
Alias for: ==
hash() click to toggle source

Return the hash value for this specification according to its attributes hash.

@note This function must have the property that a.eql?(b) implies

a.hash == b.hash.

@note This method is used by the Hash class.

@return [Fixnum] The hash value.

# File lib/cocoapods-core/specification.rb, line 117
def hash
  if @hash_value.nil?
    @hash_value = (name.hash * 53) ^ version.hash
  end
  @hash_value
end
info_plist() click to toggle source

@return [Hash] The Info.plist value.

# File lib/cocoapods-core/specification.rb, line 481
def info_plist
  attributes_hash['info_plist'] || {}
end
initialize_copy(other) click to toggle source
Calls superclass method
# File lib/cocoapods-core/specification.rb, line 58
def initialize_copy(other)
  super

  @subspecs = @subspecs.map do |subspec|
    subspec = subspec.dup
    subspec.instance_variable_set :@parent, self
    subspec
  end
end
inspect() click to toggle source

@return [String] A string suitable for debugging.

# File lib/cocoapods-core/specification.rb, line 140
def inspect
  "#<#{self.class.name} name=#{name.inspect}>"
end
library_specification?() click to toggle source

@return [Bool] If this specification is a library specification.

@note a library specification is a specification that is not of type app or test.

# File lib/cocoapods-core/specification.rb, line 259
def library_specification?
  !app_specification? && !test_specification?
end
local?() click to toggle source

@return [Bool] whether the specification should use a directory as its

source.
# File lib/cocoapods-core/specification.rb, line 494
def local?
  return true if source[:path]
  false
end
module_name() click to toggle source

Returns the module name of a specification

@return [String] the module name

# File lib/cocoapods-core/specification.rb, line 183
def module_name
  attributes_hash['module_name'] ||
    c99ext_identifier(attributes_hash['header_dir']) ||
    c99ext_identifier(attributes_hash['name'])
end
name=(name) click to toggle source

Sets the name of the `podspec`.

@param [String] name

the `podspec` name.

@return [void]

@visibility private

# File lib/cocoapods-core/specification.rb, line 782
def name=(name)
  @hash_value = nil
  attributes_hash['name'] = name
end
non_library_specification?() click to toggle source

@return [Bool] If this specification is not a library specification.

@note see library_specification?

# File lib/cocoapods-core/specification.rb, line 267
def non_library_specification?
  !library_specification?
end
non_library_specs() click to toggle source

@return [Array<Specification>] the list of all the non libary (app or test) subspecs of

a specification.
# File lib/cocoapods-core/specification.rb, line 294
def non_library_specs
  subspecs.select(&:non_library_specification?)
end
on_demand_resources() click to toggle source

@return [Hash] The on demand resources value.

# File lib/cocoapods-core/specification.rb, line 468
def on_demand_resources
  attributes_hash['on_demand_resources'] || {}
end
prefix_header_file() click to toggle source

@return [Bool, String] The prefix_header_file value.

# File lib/cocoapods-core/specification.rb, line 447
def prefix_header_file
  attributes_hash['prefix_header_file']
end
recursive_subspecs() click to toggle source

@return [Array<Specification>] the recursive list of all the subspecs of

a specification.
# File lib/cocoapods-core/specification.rb, line 301
def recursive_subspecs
  mapper = lambda do |spec|
    spec.subspecs.map do |subspec|
      [subspec, *mapper.call(subspec)]
    end.flatten
  end
  mapper.call(self)
end
root() click to toggle source

@return [Specification] The root specification or itself if it is root.

# File lib/cocoapods-core/specification.rb, line 222
def root
  parent ? parent.root : self
end
root?() click to toggle source

@return [Bool] whether the specification is root.

# File lib/cocoapods-core/specification.rb, line 228
def root?
  parent.nil?
end
scheme() click to toggle source

@return [Hash] The scheme value.

# File lib/cocoapods-core/specification.rb, line 474
def scheme
  value = attributes_hash['scheme'] || {}
  Specification.convert_keys_to_symbol(value, :recursive => false)
end
script_phases() click to toggle source

@return [Array<Hash{Symbol=>String}>] The script_phases value.

# File lib/cocoapods-core/specification.rb, line 453
def script_phases
  script_phases = attributes_hash['script_phases'] || []
  script_phases.map do |script_phase|
    phase = Specification.convert_keys_to_symbol(script_phase)
    phase[:execution_position] = if phase.key?(:execution_position)
                                   phase[:execution_position].to_sym
                                 else
                                   :any
                                 end
    phase
  end
end
spec_type() click to toggle source

@return [Symbol] Spec type of the current spec.

@note see Attribute#SUPPORTED_SPEC_TYPES for the list of available spec_types.

# File lib/cocoapods-core/specification.rb, line 246
def spec_type
  return :app if app_specification?
  return :test if test_specification?

  :library
end
store_attribute(name, value, platform_name = nil) click to toggle source

Sets the value for the attribute with the given name.

@param [Symbol] name

the name of the attribute.

@param [Object] value

the value to store.

@param [Symbol] platform_name

If provided the attribute is stored only for the given platform.

@note If the provides value is Hash the keys are converted to a string.

@return void

# File lib/cocoapods-core/specification.rb, line 597
def store_attribute(name, value, platform_name = nil)
  name = name.to_s
  value = Specification.convert_keys_to_string(value) if value.is_a?(Hash)
  value = value.strip_heredoc.strip if value.respond_to?(:strip_heredoc)
  if platform_name
    platform_name = platform_name.to_s
    attributes_hash[platform_name] ||= {}
    attributes_hash[platform_name][name] = value
  else
    attributes_hash[name] = value
  end
end
subspec?() click to toggle source

@return [Bool] whether the specification is a subspec.

# File lib/cocoapods-core/specification.rb, line 234
def subspec?
  !parent.nil?
end
subspec_by_name(relative_name, raise_if_missing = true, include_non_library_specifications = false) click to toggle source

Returns the subspec with the given name or the receiver if the name is nil or equal to the name of the receiver.

@param [String] relative_name

the relative name of the subspecs starting from the receiver
including the name of the receiver.

@param [Boolean] raise_if_missing

whether an exception should be raised if no specification named
`relative_name` is found.

@example Retrieving a subspec

s.subspec_by_name('Pod/subspec').name #=> 'subspec'

@return [Specification] the subspec with the given name or self.

# File lib/cocoapods-core/specification.rb, line 327
def subspec_by_name(relative_name, raise_if_missing = true, include_non_library_specifications = false)
  if relative_name.nil? || relative_name == base_name
    self
  elsif relative_name.downcase == base_name.downcase
    raise Informative, "Trying to access a `#{relative_name}` " \
      "specification from `#{base_name}`, which has a different case."
  else
    remainder = relative_name[base_name.size + 1..-1]
    subspec_name = remainder.split('/').shift
    subspec = subspecs.find { |s| s.base_name == subspec_name && (include_non_library_specifications || !s.non_library_specification?) }
    unless subspec
      if raise_if_missing
        raise Informative, 'Unable to find a specification named ' \
          "`#{relative_name}` in `#{name} (#{version})`."
      else
        return nil
      end
    end
    subspec.subspec_by_name(remainder, raise_if_missing, include_non_library_specifications)
  end
end
subspec_dependencies(platform = nil) click to toggle source

Returns the dependencies on subspecs.

@note A specification has a dependency on either the

{#default_subspecs} or each of its children subspecs that are
compatible with its platform.

@param [Platform] platform

return only dependencies supported on the given platform.

@return [Array<Dependency>] the dependencies on subspecs.

# File lib/cocoapods-core/specification.rb, line 373
def subspec_dependencies(platform = nil)
  specs = if default_subspecs.empty?
            subspecs.compact.reject(&:non_library_specification?)
          elsif default_subspecs == :none
            []
          else
            default_subspecs.map do |subspec_name|
              root.subspec_by_name("#{name}/#{subspec_name}")
            end
          end
  if platform
    specs = specs.select { |s| s.supported_on_platform?(platform) }
  end
  specs.map { |s| Dependency.new(s.name, version) }
end
supported_on_platform?(*platform) click to toggle source

@return [Bool] whether the specification is supported in the given

platform.

@overload supported_on_platform?(platform)

@param    [Platform] platform
          the platform which is checked for support.

@overload supported_on_platform?(symbolic_name, deployment_target)

# File lib/cocoapods-core/specification.rb, line 510
def supported_on_platform?(*platform)
  platform = Platform.new(*platform)
  available_platforms.any? { |available| platform.supports?(available) }
end
test_specs() click to toggle source

@return [Array<Specification>] the list of all the test subspecs of

a specification.
# File lib/cocoapods-core/specification.rb, line 280
def test_specs
  subspecs.select(&:test_specification?)
end
test_type() click to toggle source

@return [Symbol] the test type supported if this is a test specification.

# File lib/cocoapods-core/specification.rb, line 273
def test_type
  attributes_hash['test_type'].to_sym
end
to_s() click to toggle source

@return [String] A string suitable for representing the specification in

clients.
# File lib/cocoapods-core/specification.rb, line 127
def to_s
  specified_version = raw_version || ''
  if name && !specified_version.empty?
    "#{name} (#{specified_version})"
  elsif name
    name
  else
    'No-name'
  end
end
validate_cocoapods_version() click to toggle source

Validates the cocoapods_version in the specification against the current version of Core. It will raise an Informative error if the version is not satisfied.

# File lib/cocoapods-core/specification.rb, line 807
def validate_cocoapods_version
  unless cocoapods_version.satisfied_by?(Version.create(CORE_VERSION))
    raise Informative, "`#{name}` requires CocoaPods version `#{cocoapods_version}`, " \
                       "which is not satisfied by your current version, `#{CORE_VERSION}`."
  end
end
version=(version) click to toggle source

Sets the version of the `podspec`.

@param [String] version

the `podspec` version.

@return [void]

@visibility private

# File lib/cocoapods-core/specification.rb, line 796
def version=(version)
  @hash_value = nil
  store_attribute(:version, version)
  @version = nil
end

Protected Instance Methods

platform_hash() click to toggle source

@return [Hash] the normalized hash which represents the platform

information.
# File lib/cocoapods-core/specification.rb, line 559
def platform_hash
  case value = attributes_hash['platforms']
  when String
    { value => nil }
  when Array
    result = {}
    value.each do |a_value|
      result[a_value] = nil
    end
    result
  when Hash
    value
  else
    {}
  end
end
supported_platform_names() click to toggle source

@return [Array] the symbolic name of the platform in which the

specification is supported.

@return [Nil] if the specification is supported on all the known

platforms.
# File lib/cocoapods-core/specification.rb, line 548
def supported_platform_names
  result = platform_hash.keys
  if result.empty? && parent
    result = parent.supported_platform_names
  end
  result
end

Private Instance Methods

c99ext_identifier(name) click to toggle source

Transforms the given string into a valid identifier after C99ext standard, so that it can be used in source code where escaping of ambiguous characters is not applicable.

@param [String] name

any name, which may contain leading numbers, spaces or invalid
characters.

@return [String]

# File lib/cocoapods-core/specification.rb, line 201
def c99ext_identifier(name)
  return nil if name.nil?
  I18n.transliterate(name).gsub(/^([0-9])/, '_\1').
    gsub(/[^a-zA-Z0-9_]/, '_').gsub(/_+/, '_')
end
raw_version() click to toggle source

@return [Object, Nil]

the raw value specified for the version attribute, or nil
# File lib/cocoapods-core/specification.rb, line 210
def raw_version
  root.attributes_hash['version']
end