class Pod::Specification::Consumer
Allows to conveniently access a Specification
programmatically.
It takes care of:
-
standardizing the attributes
-
handling multi-platform values
-
handle default values
-
handle automatic container wrapping of values
-
handle inherited values
This class allows to store the values of the attributes in the Specification
as specified in the DSL
. The benefits is reduced reliance on meta programming to access the attributes and the possibility of serializing a specification back exactly as defined in a file.
Attributes
@return [Symbol] The name of the platform for which the specification
needs to be consumed.
@return [Specification] The specification to consume.
Public Class Methods
@param [Specification] spec @see spec @param [Symbol, Platform] platform
The platform for which the specification needs to be consumed.
# File lib/cocoapods-core/specification/consumer.rb, line 34 def initialize(spec, platform) @spec = spec @platform_name = platform.is_a?(Symbol) ? platform : platform.name unless spec.supported_on_platform?(platform) raise StandardError, "#{self} is not compatible with #{platform}." end end
Creates a method to access the contents of the attribute.
@param [Symbol] name
the name of the attribute.
@macro [attach]
@!method $1
# File lib/cocoapods-core/specification/consumer.rb, line 51 def self.spec_attr_accessor(name) define_method(name) do value_for_attribute(name) end end
Public Instance Methods
@return [Array<Dependency>] the dependencies on other Pods.
# File lib/cocoapods-core/specification/consumer.rb, line 230 def dependencies value = value_for_attribute(:dependencies) value.map do |name, requirements| Dependency.new(name, requirements) end end
Merges the values of an attribute, either because the attribute is multi platform or because it is inherited.
@param [Specification::DSL::Attribute] attr
the attribute for which that value is needed.
@param [String, Array, Hash] existing_value
the current value (the value of the parent or non-multiplatform value).
@param [String, Array, Hash] new_value
the value to append (the value of the spec or the multi-platform value).
@return [String, Array, Hash] The merged value.
# File lib/cocoapods-core/specification/consumer.rb, line 319 def merge_values(attr, existing_value, new_value) return existing_value if new_value.nil? return new_value if existing_value.nil? if attr.types.include?(TrueClass) new_value.nil? ? existing_value : new_value elsif attr.container == Array r = [*existing_value] + [*new_value] r.compact elsif attr.container == Hash existing_value.merge(new_value) do |_, old, new| merge_hash_value(attr, old, new) end else new_value end end
@return [Hash{String => String}] the xcconfig flags for the current
specification for the pod target.
# File lib/cocoapods-core/specification/consumer.rb, line 100 def pod_target_xcconfig attr = Specification::DSL.attributes[:pod_target_xcconfig] merge_values(attr, value_for_attribute(:xcconfig), value_for_attribute(:pod_target_xcconfig)) end
Wraps a value in an Array if needed and calls the prepare hook to allow further customization of a value before storing it in the instance variable.
@note Only array containers are wrapped. To automatically wrap
values for attributes with hash containers a prepare hook should be used.
@return [Object] the customized value of the original one if no
prepare hook was defined.
# File lib/cocoapods-core/specification/consumer.rb, line 348 def prepare_value(attr, value) if attr.container == Array value = if value.is_a?(Hash) [value] else [*value].compact end end hook_name = prepare_hook_name(attr) if self.respond_to?(hook_name, true) send(hook_name, value) else value end end
Returns the value of a given attribute taking into account multi platform values.
@param [Specification] the_spec
the specification for which the value is needed.
@param [Specification::DSL::Attribute] attr
the attribute for which that value is needed.
@return [String, Array, Hash] The value for an attribute.
# File lib/cocoapods-core/specification/consumer.rb, line 289 def raw_value_for_attribute(the_spec, attr) value = the_spec.attributes_hash[attr.name.to_s] value = prepare_value(attr, value) if attr.multi_platform? if platform_hash = the_spec.attributes_hash[platform_name.to_s] platform_value = platform_hash[attr.name.to_s] platform_value = prepare_value(attr, platform_value) value = merge_values(attr, value, platform_value) end end value end
@return [Hash{String => String}] the xcconfig flags for the current
specification for the user target.
# File lib/cocoapods-core/specification/consumer.rb, line 108 def user_target_xcconfig attr = Specification::DSL.attributes[:user_target_xcconfig] merge_values(attr, value_for_attribute(:xcconfig), value_for_attribute(:user_target_xcconfig)) end
Returns the value for the attribute with the given name for the specification. It takes into account inheritance, multi-platform attributes and default values.
@param [Symbol] attr_name
The name of the attribute.
@return [String, Array, Hash] the value for the attribute.
# File lib/cocoapods-core/specification/consumer.rb, line 250 def value_for_attribute(attr_name) attr = Specification::DSL.attributes[attr_name] value = value_with_inheritance(spec, attr) value = attr.default(platform_name) if value.nil? value = attr.container.new if value.nil? && attr.container value end
Returns the value of a given attribute taking into account inheritance.
@param [Specification] the_spec
the specification for which the value is needed.
@param [Specification::DSL::Attribute] attr
the attribute for which that value is needed.
@return [String, Array, Hash] the value for the attribute.
# File lib/cocoapods-core/specification/consumer.rb, line 268 def value_with_inheritance(the_spec, attr) value = raw_value_for_attribute(the_spec, attr) if the_spec.root? || !attr.inherited? return value end parent_value = value_with_inheritance(the_spec.parent, attr) merge_values(attr, parent_value, value) end
Private Instance Methods
Ensures that the file patterns of the on demand resources are contained in an array.
@param [String, Array, Hash] value.
The value of the attribute as specified by the user.
@return [Hash] the on demand resources.
# File lib/cocoapods-core/specification/consumer.rb, line 476 def _prepare_on_demand_resources(value) result = {} if value value.each do |key, patterns| case patterns when String, Array result[key] = { :paths => [*patterns].compact, :category => :download_on_demand } when Hash patterns = Specification.convert_keys_to_symbol(patterns, :recursive => false) result[key] = { :paths => [*patterns[:paths]].compact, :category => patterns.fetch(:category, :download_on_demand).to_sym } else raise StandardError, "Unknown on demand resource value type `#{patterns}`." end end end result end
Converts the prefix header to a string if specified as an array.
@param [String, Array] value.
The value of the attribute as specified by the user.
@return [String] the prefix header.
# File lib/cocoapods-core/specification/consumer.rb, line 414 def _prepare_prefix_header_contents(value) if value value = value.join("\n") if value.is_a?(Array) value.strip_heredoc.chomp end end
Ensures that the file patterns of the resource bundles are contained in an array.
@param [String, Array, Hash] value.
The value of the attribute as specified by the user.
@return [Hash] the resources.
# File lib/cocoapods-core/specification/consumer.rb, line 502 def _prepare_resource_bundles(value) result = {} if value value.each do |key, patterns| result[key] = [*patterns].compact end end result end
Converts the a scheme where keys are strings into symbols.
@param [Hash] value.
The value of the attribute as specified by the user.
@return [Hash] the scheme with symbols as keys instead of strings or `nil` if the value is not a hash.
# File lib/cocoapods-core/specification/consumer.rb, line 464 def _prepare_scheme(value) Specification.convert_keys_to_symbol(value, :recursive => false) if value && value.is_a?(Hash) end
Converts the array of hashes (script phases) where keys are strings into symbols.
@param [Array<Hash{String=>String}>] value.
The value of the attribute as specified by the user.
@return [Array<Hash{Symbol=>String}>] the script phases array with symbols for each hash instead of strings.
# File lib/cocoapods-core/specification/consumer.rb, line 441 def _prepare_script_phases(value) if value value.map do |script_phase| if script_phase.is_a?(Hash) 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.compact end end
Converts the test type value from a string to a symbol.
@param [String, Symbol] value.
The value of the test type attributed as specified by the user.
@return [Symbol] the test type as a symbol.
# File lib/cocoapods-core/specification/consumer.rb, line 428 def _prepare_test_type(value) if value value.to_sym end end
Merges two values in a hash together based on the needs of the attribute
@param [Specification::DSL::Attribute] attr
the attribute for which that value is needed.
@param [Object] old the value from the original hash
@param [Object] new the value from the new hash
@return [Object] the merged value
# File lib/cocoapods-core/specification/consumer.rb, line 378 def merge_hash_value(attr, old, new) case attr.name when :info_plist new when ->(name) { spec.non_library_specification? && [:pod_target_xcconfig, :user_target_xcconfig, :xcconfig].include?(name) } new else if new.is_a?(Array) || old.is_a?(Array) r = Array(old) + Array(new) r.compact else old + ' ' + new end end end
@return [String] the name of the prepare hook for this attribute.
@note The hook is called after the value has been wrapped in an
array (if needed according to the container) but before validation.
# File lib/cocoapods-core/specification/consumer.rb, line 403 def prepare_hook_name(attr) "_prepare_#{attr.name}" end