diff --git a/CHANGELOG.md b/CHANGELOG.md index bf51d6232..4ac94e47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,31 @@ ## Master +##### Breaking + +* The `link_with` Podfile DSL method has been removed in favor of target + inheritance. + [Samuel Giddins](https://github.com/segiddins) + +* The `:exclusive => true` Podfile DSL target option has been removed in favor + of the `inherit! :search_paths` directive. + [Samuel Giddins](https://github.com/segiddins) + +* The specification of `:head` dependencies has been removed. + [Samuel Giddins](https://github.com/segiddins) + +* The deprecated `:local` dependency option has been removed in favor of the + equivalent `:path` option. + [Samuel Giddins](https://github.com/segiddins) + +* The deprecated `dependency` method in the Podfile DSL has been removed in + favor of the equivalent `pod` method. + [Samuel Giddins](https://github.com/segiddins) + +* The deprecated `preferred_dependency` method in the Specification DSL has been + removed in favor of the equivalent `default_subspecs` method. + [Samuel Giddins](https://github.com/segiddins) + ##### Enhancements * Add support for specifying :source with a pod dependency. @@ -24,6 +49,15 @@ [Samuel Giddins](https://github.com/segiddins) [#267](https://github.com/CocoaPods/Core/issues/267) +* The Podfile now allows specifying installation options via the `install!` + directive. + [Samuel Giddins](https://github.com/segiddins) + [#151](https://github.com/CocoaPods/Core/issues/151) + +* The Podfile now allows marking targets as `abstract` and specifying the pod + inheritance mode via the `inherit!` directive. + [Samuel Giddins](https://github.com/segiddins) + ##### Bug Fixes * Allow non-exact version matches to be equal while maintaining a sort order. diff --git a/lib/cocoapods-core/dependency.rb b/lib/cocoapods-core/dependency.rb index 1619dc631..589b4b3a2 100644 --- a/lib/cocoapods-core/dependency.rb +++ b/lib/cocoapods-core/dependency.rb @@ -24,13 +24,6 @@ class Dependency # should be used to resolve the dependency. attr_accessor :podspec_repo - # @return [Bool] whether the dependency should use the podspec with the - # highest know version but force the downloader to checkout the - # `head` of the source repository. - # - attr_accessor :head - alias_method :head?, :head - # @overload initialize(name, requirements) # # @param [String] name @@ -84,6 +77,8 @@ class Dependency # @param [Symbol] is_head # a symbol that can be `:head` or nil. # + # @todo Remove `:head` code once everyone has migrated past CocoaPods 1.0. + # # @example Initialization with the head option # # Dependency.new('RestKit', :head) @@ -109,12 +104,9 @@ def initialize(name = nil, *requirements) end elsif requirements.last == :head - @head = true - requirements.pop - unless requirements.empty? - raise Informative, 'A `:head` dependency may not specify version ' \ - "requirements (#{name})." - end + raise Informative, '`:head` dependencies have been removed. Please use ' \ + "normal external source dependencies (`:git => 'GIT_REPO_URL'`) " \ + "instead of `:head` for `#{name}`." end if requirements.length == 1 && requirements.first.is_a?(Requirement) @@ -159,7 +151,7 @@ def external? # def local? if external_source - external_source[:path] || external_source[:local] + external_source[:path] end end @@ -209,7 +201,6 @@ def root_name # def compatible?(other) return false unless name == other.name - return false unless head? == other.head? return false unless external_source == other.external_source other.requirement.requirements.all? do |_operator, version| @@ -225,7 +216,6 @@ def ==(other) self.class == other.class && name == other.name && requirement == other.requirement && - head? == other.head? && external_source == other.external_source end alias_method :eql?, :== @@ -271,7 +261,6 @@ def merge(other) dep = self.class.new(name, self_req.as_list.concat(other_req.as_list)) end - dep.head = head? || other.head? if external_source || other.external_source self_external_source = external_source || {} other_external_source = other.external_source || {} @@ -322,7 +311,6 @@ def match?(name, version) # "libPusher (= 1.0)" # "libPusher (~> 1.0.1)" # "libPusher (> 1.0, < 2.0)" - # "libPusher (HEAD)" # "libPusher (from `www.example.com')" # "libPusher (defined in Podfile)" # "RestKit/JSON" @@ -333,8 +321,6 @@ def to_s version = '' if external? version << external_source_description(external_source) - elsif head? - version << 'HEAD' elsif requirement != Requirement.default version << requirement.to_s end @@ -364,8 +350,6 @@ def self.from_string(string) case version when nil, /from `(.*)(`|')/ Dependency.new(name) - when /HEAD/ - Dependency.new(name, :head) else version_requirements = version.split(',') if version Dependency.new(name, version_requirements) @@ -409,8 +393,6 @@ def external_source_description(source) desc = "`#{source[:podspec]}`" elsif source.key?(:path) desc = "`#{source[:path]}`" - elsif source.key?(:local) - desc = "`#{source[:local]}`" else desc = "`#{source}`" end diff --git a/lib/cocoapods-core/lockfile.rb b/lib/cocoapods-core/lockfile.rb index 58e31e1d2..349f8b9f2 100644 --- a/lib/cocoapods-core/lockfile.rb +++ b/lib/cocoapods-core/lockfile.rb @@ -239,7 +239,7 @@ def checksum_data # - added: Pods that weren't present in the Podfile. # - changed: Pods that were present in the Podfile but changed: # - Pods whose version is not compatible anymore with Podfile, - # - Pods that changed their head or external options. + # - Pods that changed their external options. # - removed: Pods that were removed form the Podfile. # - unchanged: Pods that are still compatible with Podfile. # @@ -443,10 +443,6 @@ def generate_dependencies_data(podfile) # the values store the external source hashes of each # dependency. # - # @todo The downloader should generate an external source hash that - # should be store for dependencies in head mode and for those - # with external source. - # def generate_external_sources_data(podfile) deps = podfile.dependencies.select(&:external?) deps = deps.sort { |d, other| d.name <=> other.name } diff --git a/lib/cocoapods-core/podfile.rb b/lib/cocoapods-core/podfile.rb index 17d6c32fd..76e888fb7 100644 --- a/lib/cocoapods-core/podfile.rb +++ b/lib/cocoapods-core/podfile.rb @@ -45,7 +45,7 @@ def initialize(defined_in_file = nil, internal_hash = {}, &block) @internal_hash = internal_hash if block default_target_def = TargetDefinition.new('Pods', self) - default_target_def.link_with_first_target = true + default_target_def.abstract = true @root_target_definitions = [default_target_def] @current_target_definition = default_target_def instance_eval(&block) @@ -74,6 +74,8 @@ def target_definitions Hash[target_definition_list.map { |td| [td.name, td] }] end + # @return [Array] all target definitions in the podfile. + # def target_definition_list root_target_definitions.map { |td| [td, td.recursive_children] }.flatten end @@ -134,6 +136,14 @@ def set_arc_compatibility_flag? get_hash_value('set_arc_compatibility_flag') end + # @return [(String,Hash)] the installation strategy and installation options + # to be used during installation. + # + def installation_method + get_hash_value('installation_method', 'name' => 'cocoapods', 'options' => {}). + values_at('name', 'options') + end + #-------------------------------------------------------------------------# public @@ -183,6 +193,7 @@ def post_install!(installer) # @return [Array] The keys used by the hash representation of the Podfile. # HASH_KEYS = %w( + installation_method workspace sources plugins @@ -348,7 +359,7 @@ def self.from_hash(hash, path = nil) # @param [Object] value # The value to store. # - # @raise If the key is not recognized. + # @raise [StandardError] If the key is not recognized. # # @return [void] # @@ -364,15 +375,19 @@ def set_hash_value(key, value) # @param [String] key # The key for which the value is needed. # - # @raise If the key is not recognized. + # @param default + # The default value to return if the internal hash has no entry for + # the given `key`. + # + # @raise [StandardError] If the key is not recognized. # # @return [Object] The value for the key. # - def get_hash_value(key) + def get_hash_value(key, default = nil) unless HASH_KEYS.include?(key) raise StandardError, "Unsupported hash key `#{key}`" end - internal_hash[key] + internal_hash.fetch(key, default) end # @return [TargetDefinition] The current target definition to which the DSL @@ -380,19 +395,6 @@ def get_hash_value(key) # attr_accessor :current_target_definition - public - - # @!group Deprecations - #-------------------------------------------------------------------------# - - # @deprecated Deprecated in favour of the more succinct {#pod}. Remove for - # CocoaPods 1.0. - # - def dependency(name = nil, *requirements, &block) - CoreUI.warn "[DEPRECATED] `dependency' is deprecated (use `pod')" - pod(name, *requirements, &block) - end - #-------------------------------------------------------------------------# end end diff --git a/lib/cocoapods-core/podfile/dsl.rb b/lib/cocoapods-core/podfile/dsl.rb index 2b0000bd5..e5a9505ad 100644 --- a/lib/cocoapods-core/podfile/dsl.rb +++ b/lib/cocoapods-core/podfile/dsl.rb @@ -5,9 +5,7 @@ class Podfile # CocoaPods/cocoapods.github.com. # The Podfile is a specification that describes the dependencies of the - # targets of one or more Xcode projects. The Podfile always creates an - # implicit target, named `default`, which links to the first target of the - # user project. + # targets of one or more Xcode projects. # # A Podfile can be very simple: # @@ -15,19 +13,19 @@ class Podfile # # An example of a more complex Podfile can be: # - # source 'https://github.com/CocoaPods/Specs.git' - # - # platform :ios, '6.0' + # platform :ios, '9.0' # inhibit_all_warnings! # - # xcodeproj 'MyProject' - # - # pod 'ObjectiveSugar', '~> 0.5' + # target "MyApp" do + # pod 'ObjectiveSugar', '~> 0.5' # - # target :test do - # pod 'OCMock', '~> 2.0.1' + # target "MyAppTests" do + # inherit! :search_paths + # pod 'OCMock', '~> 2.0.1' + # end # end # + # # post_install do |installer| # installer.pods_project.targets.each do |target| # puts "#{target.name}" @@ -40,7 +38,7 @@ module DSL # # * `pod` is the way to declare a specific dependency. # * `podspec` provides an easy API for the creation of podspecs. - # * `target` allows you to scope your dependencies to specific + # * `target` is how you scope your dependencies to specific # targets in your Xcode projects. #-----------------------------------------------------------------------# @@ -82,13 +80,6 @@ module DSL # * [Semantic Versioning](http://semver.org) # * [RubyGems Versioning Policies](http://docs.rubygems.org/read/chapter/7) # - # Finally, instead of a version, you can specify the `:head` flag. This - # will use the spec of the newest available version in your spec repo(s), - # but force the download of the ‘bleeding edge’ version (HEAD). Use this - # with caution, as the spec _might_ not be compatible anymore. - # - # pod 'Objection', :head - # # ------ # # ### Build configurations @@ -193,16 +184,9 @@ module DSL # @note This method allow a nil name and the raises to be more # informative. # - # @note Support for inline podspecs has been deprecated. - # # @return [void] # - def pod(name = nil, *requirements, &block) - if block - raise StandardError, 'Inline specifications are deprecated. ' \ - 'Please store the specification in a `podspec` file.' - end - + def pod(name = nil, *requirements) unless name raise StandardError, 'A dependency requires a name.' end @@ -210,9 +194,9 @@ def pod(name = nil, *requirements, &block) current_target_definition.store_pod(name, *requirements) end - # Use the dependencies of a Pod defined in the given podspec file. If no - # arguments are passed the first podspec in the root of the Podfile is - # used. It is intended to be used by the project of a library. Note: + # Use just the dependencies of a Pod defined in the given podspec file. + # If no arguments are passed the first podspec in the root of the Podfile + # is used. It is intended to be used by the project of a library. Note: # this does not include the sources derived from the podspec just the # CocoaPods infrastructure. # @@ -235,7 +219,7 @@ def pod(name = nil, *requirements, &block) # @option options [String] :name # the name of the podspec # - # @note This method uses the dependencies declared by the for the + # @note This method uses the dependencies declared for the # platform of the target definition. # # @@ -248,57 +232,173 @@ def podspec(options = nil) current_target_definition.store_podspec(options) end - # Defines a new static library target and scopes dependencies defined - # from the given block. The target will by default include the - # dependencies defined outside of the block, unless the `:exclusive => - # true` option is - # given. - # - # --- - # - # The Podfile creates a global target named `:default` which produces the - # `libPods.a` file. This target is linked with the first target of user - # project if not value is specified for the `link_with` attribute. + # Defines a CocoaPods target and scopes dependencies defined + # within the given block. A target should correspond to an Xcode target. + # By default the target includes the dependencies defined outside of + # the block, unless instructed not to `inherit!` them. # # @param [Symbol, String] name - # the name of the target definition. - # - # @option options [Bool] :exclusive - # whether the target should inherit the dependencies of its - # parent. by default targets are inclusive. + # the name of the target. # # @example Defining a target # - # target :ZipApp do + # target "ZipApp" do # pod 'SSZipArchive' # end # - # @example Defining an exclusive target + # @example Defining a test target which can access SSZipArchive via Pods + # for it's parent target. # - # target :ZipApp do + # target "ZipApp" do # pod 'SSZipArchive' - # target :test, :exclusive => true do - # pod 'JSONKit' + # + # target "ZipAppTests" do + # inherit! :search_paths + # pod 'Nimble' + # end + # end + # + # @example Defining a target applies Pods to multiple targets via its + # parent target + # + # target "ShowsApp" do + # pod 'ShowsKit' + # + # # Has it's own copy of ShowsKit + ShowTVAuth + # target "ShowsTV" do + # pod "ShowTVAuth" + # end + # + # # Has it's own copy of Specta + Expecta + # # and has access to ShowsKit via the app + # # that the test target is bundled into + # + # target "ShowsTests" do + # inherit! :search_paths + # pod 'Specta' + # pod 'Expecta' # end # end # # @return [void] # - def target(name, options = {}) - if options && !options.keys.all? { |key| [:exclusive].include?(key) } + def target(name, options = nil) + if options raise Informative, "Unsupported options `#{options}` for " \ - "target `#{name}`" + "target `#{name}`." end parent = current_target_definition definition = TargetDefinition.new(name, parent) - definition.exclusive = true if options[:exclusive] self.current_target_definition = definition - yield + yield if block_given? ensure self.current_target_definition = parent end + # Defines a new abstract target that can be used for convenient + # target dependency inheritance. + # + # @param [Symbol, String] name + # the name of the target. + # + # @example Defining an abstract target + # + # abstract_target 'Networking' do + # pod 'AlamoFire' + # + # target 'Networking App 1' + # target 'Networking App 2' + # end + # + # @example Defining an abstract_target wrapping Pods to multiple targets + # + # # There are no targets called "Shows" in any Xcode projects + # abstract_target "Shows" do + # pod 'ShowsKit' + # + # # Has it's own copy of ShowsKit + ShowWebAuth + # target "ShowsiOS" do + # pod "ShowWebAuth" + # end + # + # # Has it's own copy of ShowsKit + ShowTVAuth + # target "ShowsTV" do + # pod "ShowTVAuth" + # end + # + # # Has it's own copy of Specta + Expecta + # # and has access to ShowsKit via the app + # # that the test target is bundled into + # + # target "ShowsTests" do + # inherit! :search_paths + # pod 'Specta' + # pod 'Expecta' + # end + # end + # + # @return [void] + # + def abstract_target(name) + target(name) do + abstract! + yield if block_given? + end + end + + # Denotes that the current target is abstract, and thus will not directly + # link against an Xcode target. + # + # @return [void] + # + def abstract!(abstract = true) + current_target_definition.abstract = abstract + end + + # Sets the inheritance mode for the current target. + # + # @param [:complete, :none, :search_paths] the inheritance mode to set. + # + # @example Inheriting only search paths + # + # target 'App' do + # target 'AppTests' do + # inherit! :search_paths + # end + # end + # + # @return [void] + # + def inherit!(inheritance) + current_target_definition.inheritance = inheritance + end + + # Specifies the installation method to be used when CocoaPods installs + # this Podfile. + # + # @param [String] installation_method + # the name of the installation strategy. + # + # @param [Hash] options + # the installation options. + # + # @example Specifying custom CocoaPods installation options + # + # install! 'cocoapods', + # :deterministic_uuids => false, + # :integrate_targets => false + # + # @return [void] + # + def install!(installation_method, options = {}) + unless current_target_definition.root? + raise Informative, 'The installation method can only be set at the root level of the Podfile.' + end + + set_hash_value('installation_method', 'name' => installation_method, 'options' => options) + end + #-----------------------------------------------------------------------# # @!group Target configuration @@ -345,10 +445,9 @@ def platform(name, target = nil) # # ----- # - # If no explicit project is specified, it will use the Xcode project of - # the parent target. If none of the target definitions specify an - # explicit project and there is only **one** project in the same - # directory as the Podfile then that project will be used. + # If none of the target definitions specify an explicit project + # and there is only **one** project in the same directory as the Podfile + # then that project will be used. # # It is possible also to specify whether the build settings of your # custom build configurations should be modelled after the release or @@ -369,20 +468,22 @@ def platform(name, target = nil) # # @example Specifying the user project # - # # Look for target to link with in an Xcode project called - # # `MyProject.xcodeproj`. - # xcodeproj 'MyProject' + # # This Target can be found in a Xcode project called `FastGPS` + # target "MyGPSApp" do + # xcodeproj 'FastGPS' + # ... + # end # - # target :test do - # # This Pods library links with a target in another project. - # xcodeproj 'TestProject' + # # Same Podfile, multiple Xcodeprojects + # target "MyNotesApp" do + # xcodeproj 'FastNotes' + # ... # end # # @example Using custom build configurations # # xcodeproj 'TestProject', 'Mac App Store' => :release, 'Test' => :debug # - # # @return [void] # def xcodeproj(path, build_configurations = {}) @@ -390,30 +491,18 @@ def xcodeproj(path, build_configurations = {}) current_target_definition.build_configurations = build_configurations end - # Specifies the target(s) in the user’s project that this Pods library - # should be linked in. - # - # ----- - # - # If no explicit target is specified, then the Pods target will be linked - # with the first target in your project. So if you only have one target - # you do not need to specify the target to link with. - # - # @param [String, Array] targets - # the target or the targets to link with. + # @!visibility private # - # @example Link with a user project target + # @deprecated linking a single target with multiple Xcode targets is no + # longer supported. Use an {#abstract_target} and target + # inheritance instead. # - # link_with 'MyApp' - # - # @example Link with multiple user project targets - # - # link_with 'MyApp', 'MyOtherApp' - # - # @return [void] + # TODO: This method can be deleted once people have migrated to this 1.0 + # DSL. # - def link_with(*targets) - current_target_definition.link_with = targets.flatten + def link_with(*) + raise Informative, 'The specification of `link_with` in the Podfile ' \ + 'is now unsupported, please use target blocks instead.' end # Inhibits **all** the warnings from the CocoaPods libraries. @@ -589,7 +678,7 @@ def plugin(name, options = {}) # [`Pod::Installer`](http://rubydoc.info/gems/cocoapods/Pod/Installer/) # as its only argument. # - # @example Defining a pre install hook in a Podfile. + # @example Defining a pre-install hook in a Podfile. # # pre_install do |installer| # # Do something fancy! diff --git a/lib/cocoapods-core/podfile/target_definition.rb b/lib/cocoapods-core/podfile/target_definition.rb index 0b68b8e18..d1c6df63d 100644 --- a/lib/cocoapods-core/podfile/target_definition.rb +++ b/lib/cocoapods-core/podfile/target_definition.rb @@ -19,17 +19,11 @@ class TargetDefinition # @param [TargetDefinition] parent # @see parent # - # @option options [Bool] :exclusive - # @see exclusive? - # def initialize(name, parent, internal_hash = nil) @internal_hash = internal_hash || {} @parent = parent @children = [] - - unless internal_hash - self.name = name - end + self.name ||= name if parent.is_a?(TargetDefinition) parent.children << self end @@ -73,13 +67,25 @@ def podfile # definition including the inherited ones. # def dependencies - if exclusive? || parent.nil? + if exclusive? non_inherited_dependencies else non_inherited_dependencies + parent.dependencies end end + # @return [Array] the targets from which this target + # definition should inherit only search paths. + # + def targets_to_inherit_search_paths + return [] unless inheritance == 'search_paths' + if root? || !matches_platform?(parent) + raise StandardError, "Non-sensical to have search_paths inheritance for #{name} when there is no parent." + else + parent.targets_to_inherit_search_paths << parent + end + end + # @return [Array] The list of the dependencies of the target definition, # excluding inherited ones. # @@ -142,83 +148,81 @@ def name=(name) #--------------------------------------# - # Returns whether the target definition should inherit the dependencies - # of the parent. - # - # @note A target is always `exclusive` if it is root. + # @return [Boolean] whether this target definition is abstract. # - # @note A target is always `exclusive` if the `platform` does - # not match the parent's `platform`. - # - # @return [Bool] whether is exclusive. - # - def exclusive? - if root? - true - elsif get_hash_value('exclusive') - true - else - platform && parent && parent.platform != platform - end + def abstract? + get_hash_value('abstract', false) end - # Sets whether the target definition is exclusive. + # Sets whether this target definition is abstract. # - # @param [Bool] flag - # Whether the definition is exclusive. + # @param [Boolean] abstract + # whether this target definition is abstract. # # @return [void] # - def exclusive=(flag) - set_hash_value('exclusive', flag) + def abstract=(abstract) + set_hash_value('abstract', abstract) end #--------------------------------------# - # @return [Array] The list of the names of the Xcode targets with - # which this target definition should be linked with. + # @return [String] the inheritance mode for this target definition. # - def link_with - value = get_hash_value('link_with') - value unless value.nil? || value.empty? + def inheritance + get_hash_value('inheritance', 'complete') end - # Sets the client targets that should be integrated by this definition. + # Sets the inheritance mode for this target definition. # - # @param [Array] targets - # The list of the targets names. + # @param [#to_s] inheritance + # the inheritance mode for this target definition. + # + # @raise [Informative] if this target definition is a root target + # definition or if the `inheritance` value is unknown. # # @return [void] # - def link_with=(targets) - set_hash_value('link_with', Array(targets).map(&:to_s)) + def inheritance=(inheritance) + inheritance = inheritance.to_s + unless %w(none search_paths complete).include?(inheritance) + raise Informative, "Unrecognized inheritance option `#{inheritance}` specified for target `#{name}`." + end + if root? + raise Informative, 'Cannot set inheritance for the root target definition.' + end + set_hash_value('inheritance', inheritance) end #--------------------------------------# - # Returns whether the target definition should link with the first target - # of the project. + # Returns whether the target definition should inherit the dependencies + # of the parent. # - # @note This option is ignored if {link_with} is set. + # @note A target is always `exclusive` if it is root. + # + # @note A target is always `exclusive` if the `platform` does + # not match the parent's `platform`. # # @return [Bool] whether is exclusive. # - def link_with_first_target? - get_hash_value('link_with_first_target') unless link_with + def exclusive? + if root? + true + else + !matches_platform?(parent) || (inheritance != 'complete') + end end - # Sets whether the target definition should link with the first target of - # the project. - # - # @note This option is ignored if {link_with} is set. - # - # @param [Bool] flag - # Whether the definition should link with the first target. + # @param [TargetDefinition, Nil] target_definition + # the target definition to check for platform compatibility. # - # @return [void] + # @return [Boolean] + # whether this target definition matches the platform of + # `target_definition`. # - def link_with_first_target=(flag) - set_hash_value('link_with_first_target', flag) + def matches_platform?(target_definition) + target_definition && target_definition.platform == platform end #--------------------------------------# @@ -229,7 +233,7 @@ def link_with_first_target=(flag) def user_project_path path = get_hash_value('user_project_path') if path - File.extname(path) == '.xcodeproj' ? path : "#{path}.xcodeproj" + Pathname(path).sub_ext('.xcodeproj').to_path else parent.user_project_path unless root? end @@ -368,7 +372,7 @@ def pod_whitelisted_for_configuration?(pod_name, configuration_name) end end end - !found && (exclusive? || parent.pod_whitelisted_for_configuration?(pod_name, configuration_name)) + !found && (root? || (inheritance != 'none' && parent.pod_whitelisted_for_configuration?(pod_name, configuration_name))) end # Whitelists a pod for a specific configuration. If a pod is whitelisted @@ -396,7 +400,7 @@ def whitelist_pod_for_configuration(pod_name, configuration_name) # pods have been whitelisted. # def all_whitelisted_configurations - parent_configurations = exclusive? ? [] : parent.all_whitelisted_configurations + parent_configurations = (root? || inheritance == 'none') ? [] : parent.all_whitelisted_configurations (configuration_pod_whitelist.keys + parent_configurations).uniq end @@ -536,6 +540,8 @@ def store_podspec(options = nil) children configuration_pod_whitelist uses_frameworks + inheritance + abstract ).freeze # @return [Hash] The hash representation of the target definition. @@ -589,7 +595,7 @@ def self.from_hash(hash, parent) # @param [Object] value # The value to store. # - # @raise If the key is not recognized. + # @raise [StandardError] If the key is not recognized. # # @return [void] # @@ -609,7 +615,7 @@ def set_hash_value(key, value) # @param [Object] base_value # The value to set if they key is nil. Useful for collections. # - # @raise If the key is not recognized. + # @raise [StandardError] If the key is not recognized. # # @return [Object] The value for the key. # @@ -626,7 +632,12 @@ def get_hash_value(key, base_value = nil) # warnings, and :for_pods key for inhibiting warnings per Pod. # def inhibit_warnings_hash - get_hash_value('inhibit_warnings', {}) + inhibit_hash = get_hash_value('inhibit_warnings', {}) + if exclusive? + inhibit_hash + else + parent.send(:inhibit_warnings_hash).merge(inhibit_hash) { |l, r| (l + r).uniq } + end end # Returns the configuration_pod_whitelist hash @@ -636,7 +647,12 @@ def inhibit_warnings_hash # as value. # def configuration_pod_whitelist - get_hash_value('configuration_pod_whitelist', {}) + whitelist_hash = get_hash_value('configuration_pod_whitelist', {}) + if exclusive? + whitelist_hash + else + parent.send(:configuration_pod_whitelist).merge(whitelist_hash) { |l, r| (l + r).uniq } + end end # @return [Array] The dependencies specified by the user for @@ -745,10 +761,8 @@ def parse_configuration_whitelist(name, requirements) configurations = options.delete(:configurations) configurations ||= options.delete(:configuration) - if configurations - Array(configurations).each do |configuration| - whitelist_pod_for_configuration(name, configuration) - end + Array(configurations).each do |configuration| + whitelist_pod_for_configuration(name, configuration) end requirements.pop if options.empty? end diff --git a/lib/cocoapods-core/specification.rb b/lib/cocoapods-core/specification.rb index 8a8249177..1a5378422 100644 --- a/lib/cocoapods-core/specification.rb +++ b/lib/cocoapods-core/specification.rb @@ -62,18 +62,12 @@ def initialize(parent = nil, name = nil) # @return [Bool] Whether the specifications are equal. # def ==(other) - # TODO - # self.class === other && - # attributes_hash == other.attributes_hash && - # subspecs == other.subspecs && - to_s == other.to_s + other.is_a?(self.class) && + name == other.name && + version == other.version end - # @see == - # - def eql?(other) - self == other - end + alias_method :eql?, :== # Return the hash value for this specification according to its attributes # hash. @@ -86,7 +80,7 @@ def eql?(other) # @return [Fixnum] The hash value. # def hash - to_s.hash + (name.hash * 53) ^ version.hash end # @return [String] A string suitable for representing the specification in @@ -115,7 +109,6 @@ def inspect # @example Input examples # # "libPusher (1.0)" - # "libPusher (HEAD based on 1.0)" # "RestKit/JSON (1.0)" # # @return [Array] the name and the version of a @@ -331,7 +324,6 @@ def consumer(platform) # def local? return true if source[:path] - return true if source[:local] false end diff --git a/lib/cocoapods-core/specification/dsl.rb b/lib/cocoapods-core/specification/dsl.rb index 8febd482c..743e10d24 100644 --- a/lib/cocoapods-core/specification/dsl.rb +++ b/lib/cocoapods-core/specification/dsl.rb @@ -104,7 +104,7 @@ module DSL # @!method cocoapods_version=(cocoapods_version) # - # The version of CocoaPods that the sepcification supports. + # The version of CocoaPods that the specification supports. # # @example # @@ -1157,7 +1157,7 @@ def dependency(*args) # We strongly **recommend** library developers to adopt [resource # bundles](http://guides.cocoapods.org/syntax/podspec.html#resource_bundles) # as there can be name collisions using the resources attribute. - # Moreover resources specified with this attribute are copied + # Moreover, resources specified with this attribute are copied # directly to the client target and therefore they are not # optimised by Xcode. # diff --git a/lib/cocoapods-core/specification/dsl/deprecations.rb b/lib/cocoapods-core/specification/dsl/deprecations.rb index 864d058d4..3d4473469 100644 --- a/lib/cocoapods-core/specification/dsl/deprecations.rb +++ b/lib/cocoapods-core/specification/dsl/deprecations.rb @@ -4,12 +4,6 @@ module DSL # Provides warning and errors for the deprecated attributes of the DSL. # module Deprecations - def preferred_dependency=(name) - self.default_subspecs = [name] - CoreUI.warn "[#{self}] `preferred_dependency` has been renamed "\ - 'to `default_subspecs`.' - end - DSL.attribute :xcconfig, :container => Hash, :inherited => true diff --git a/lib/cocoapods-core/specification/json.rb b/lib/cocoapods-core/specification/json.rb index 2ccbf24f7..85b91cb61 100644 --- a/lib/cocoapods-core/specification/json.rb +++ b/lib/cocoapods-core/specification/json.rb @@ -31,15 +31,6 @@ def to_hash end hash end - - # @return [Bool] Whether the specification can be converted to a hash - # without loss of information. - # - # TODO: remove - # - def safe_to_hash? - true - end end # Configures a new specification from the given JSON representation. diff --git a/lib/cocoapods-core/version.rb b/lib/cocoapods-core/version.rb index a766be9de..9f6e96eb5 100644 --- a/lib/cocoapods-core/version.rb +++ b/lib/cocoapods-core/version.rb @@ -38,24 +38,15 @@ class Version < Pod::Vendor::Gem::Version VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z\-]+)*' ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ - # @return [Bool] whether the version represents the `head` of repository. - # - attr_accessor :head - alias_method :head?, :head - # @param [String,Version] version # A string representing a version, or another version. # - # @todo The `from` part of the regular expression should be remove in - # CocoaPods 1.0.0. + # @todo Remove the `HEAD` code once everyone has migrated past 1.0. # def initialize(version) - if version.is_a?(Version) && version.head? - version = version.version - @head = true - elsif version.is_a?(String) && version =~ /HEAD (based on|from) (.*)/ - version = Regexp.last_match[2] - @head = true + if version.is_a?(String) && version =~ /HEAD based on (.*)/ + CoreUI.warn "Ignoring obsolete HEAD specifier in `#{version}`" + version = Regexp.last_match[1] end raise ArgumentError, "Malformed version number string #{version}" unless @@ -68,19 +59,6 @@ def initialize(version) # ZERO = new('0') - # @return [String] a string representation that indicates if the version is - # head. - # - # @note The raw version string is still accessible with the {#version} - # method. - # - # @todo Adding the head information to the string representation creates - # issues (see Dependency#requirement). - # - def to_s - head? ? "HEAD based on #{super}" : super - end - # @return [String] a string representation suitable for debugging. # def inspect diff --git a/spec/dependency_spec.rb b/spec/dependency_spec.rb index 2950d2b8f..2a2652fa7 100644 --- a/spec/dependency_spec.rb +++ b/spec/dependency_spec.rb @@ -51,29 +51,17 @@ module Pod dep.should.not.be.local end - it 'keeps the backward compatibility with :local' do - dep = Dependency.new('cocoapods', :local => '/tmp/cocoapods') - dep.should.be.local - end - it 'raises if initialized with an external source and requirements are provided' do should.raise Informative do Dependency.new('cocoapods', '1.0', :git => 'git://github.com/cocoapods/cocoapods') end end - it 'can be initialized in head mode' do - dependency = Dependency.new('cocoapods', :head) - dependency.should.be.head - dependency.to_s.should == 'cocoapods (HEAD)' - end - describe '#from_string' do it 'creates a dependency from a string' do d = Dependency.from_string('BananaLib (1.0)') d.name.should == 'BananaLib' d.requirement.should =~ Version.new('1.0') - d.head.should.be.nil d.external_source.should.be.nil end @@ -122,24 +110,10 @@ module Pod it 'raises if version requirements are specified for an external source' do should.raise Pod::Informative do - Dependency.new('cocoapods', '1.2.3', :head) - end - end - - it 'only supports the `:head` option on the last version of a pod' do - should.raise Pod::Informative do - Dependency.new('cocoapods', '1.2.3', :head) + Dependency.new('cocoapods', '1.2.3', :git => 'example.com') end end - it 'preserves head information when initialized form a string' do - d = Dependency.from_string('BananaLib (HEAD)') - d.name.should == 'BananaLib' - d.requirement.should.be.none? - d.head.should.be.true - d.external_source.should.be.nil - end - it 'raises if an invalid initialization flag is given' do should.raise ArgumentError do Dependency.new('cocoapods', :foot) @@ -152,10 +126,11 @@ module Pod dependency.requirement.as_list.should == ['= 1.23'] end - it 'can handle specific version with head information' do + it 'warns with head information' do dependency = Dependency.new('cocoapods', '> 1.0') dependency.specific_version = Version.new('HEAD based on 1.23') dependency.requirement.as_list.should == ['= 1.23'] + CoreUI.warnings.should == 'Ignoring obsolete HEAD specifier in `HEAD based on 1.23`' end #--------------------------------------# @@ -165,11 +140,6 @@ module Pod dep.dup.external_source.should == { :podspec => 'bananas' } end - it 'preserves the head information on duplication' do - dep = Dependency.new('bananas', :head) - dep.dup.head.should.be.true - end - #--------------------------------------# it 'returns the name of the dependency, or the name of the pod of which this is a subspec' do @@ -200,12 +170,6 @@ module Pod dep1.compatible?(dep2).should.be.false end - it 'is not compatible with another if the head informations differ' do - dep1 = Dependency.new('bananas', :head) - dep2 = Dependency.new('bananas', '1.9') - dep1.compatible?(dep2).should.be.false - end - it 'is not compatible with another if the external sources differ' do dep1 = Dependency.new('bananas', :podspec => 'bananas') dep2 = Dependency.new('bananas', '1.9') @@ -222,14 +186,6 @@ module Pod dep1.should == dep3 end - it 'takes into account the `head` option to check for equality' do - dep1 = Dependency.new('bananas', :head) - dep2 = Dependency.new('bananas', :head) - dep3 = Dependency.new('bananas') - dep1.should == dep2 - dep1.should.not == dep3 - end - it 'supports Array#uniq' do d_1 = Dependency.new('bananas') d_2 = Dependency.new('bananas') @@ -253,14 +209,6 @@ module Pod dep1.merge(dep2).should == Dependency.new('bananas', '>= 1.8', '1.9') end - it 'it preserves head state while merging with another dependency' do - dep1 = Dependency.new('bananas', '1.9') - dep2 = Dependency.new('bananas', :head) - result = dep1.merge(dep2) - result.should.be.head - result.requirement.as_list.should == ['= 1.9'] - end - it 'it preserves the external source while merging with another dependency' do dep1 = Dependency.new('bananas', '1.9') dep2 = Dependency.new('bananas', :podspec => 'bananas') @@ -341,7 +289,6 @@ module Pod @dep.send(:external_source_description, :svn => 'example.com').should == 'from `example.com`' @dep.send(:external_source_description, :podspec => 'example.com').should == 'from `example.com`' @dep.send(:external_source_description, :path => 'example.com').should == 'from `example.com`' - @dep.send(:external_source_description, :local => 'example.com').should == 'from `example.com`' @dep.send(:external_source_description, :other => 'example.com').should.match /from.*example.com/ end end diff --git a/spec/fixtures/Podfile.yaml b/spec/fixtures/Podfile.yaml index 38f8ec492..85d4f1684 100644 --- a/spec/fixtures/Podfile.yaml +++ b/spec/fixtures/Podfile.yaml @@ -4,7 +4,7 @@ sources: - 'myrepo2' target_definitions: - name: Pods - link_with_first_target: true + abstract: true platform: ios dependencies: @@ -15,4 +15,3 @@ target_definitions: - Reachability - ASIWebPageRequest: - < 1.8.2 - diff --git a/spec/lockfile_spec.rb b/spec/lockfile_spec.rb index 6e4a69632..a835d45d9 100644 --- a/spec/lockfile_spec.rb +++ b/spec/lockfile_spec.rb @@ -277,43 +277,6 @@ def self.checkout_options :added => [], } end - - it 'detects Pods whose head state changed' do - podfile = Podfile.new do - platform :ios - pod 'BlocksKit' - pod 'JSONKit', :head - end - @lockfile.detect_changes_with_podfile(podfile).should == { - :changed => ['JSONKit'], - :removed => [], - :unchanged => ['BlocksKit'], - :added => [], - } - @specs = [ - Specification.new do |s| - s.name = 'BlocksKit' - s.version = '1.0.0' - end, - Specification.new do |s| - s.name = 'JSONKit' - s.version = '1.4' - s.version.head = true - end] - @lockfile = Lockfile.generate(podfile, @specs, @checkout_options) - podfile = Podfile.new do - platform :ios - pod 'BlocksKit' - pod 'JSONKit' - end - - @lockfile.detect_changes_with_podfile(podfile).should == { - :changed => ['JSONKit'], - :removed => [], - :unchanged => ['BlocksKit'], - :added => [], - } - end end #-------------------------------------------------------------------------# @@ -383,28 +346,6 @@ def self.checkout_options YAMLHelper.load_string(Sample.yaml) end - it "serializes correctly `:head' dependencies" do - podfile = Podfile.new do - platform :ios - pod 'BananaLib', :head - end - specs = [ - Specification.new do |s| - s.name = 'BananaLib' - s.version = '1.0' - end, - Specification.new do |s| - s.name = 'monkey' - s.version = '1.0.8' - end, - ] - checkout_options = { - 'BananaLib' => { :git => 'www.example.com', :commit => 'dad4645' }, - } - lockfile = Lockfile.generate(podfile, specs, checkout_options) - lockfile.internal_data['DEPENDENCIES'][0].should == 'BananaLib (HEAD)' - end - it 'serializes correctly external dependencies' do podfile = Podfile.new do platform :ios diff --git a/spec/podfile/dsl_spec.rb b/spec/podfile/dsl_spec.rb index ca4c59546..8f390b4fb 100644 --- a/spec/podfile/dsl_spec.rb +++ b/spec/podfile/dsl_spec.rb @@ -96,7 +96,7 @@ module Pod podfile.dependencies.map(&:name).should == %w(monkey) end - it 'allows to specify a child target definition' do + it 'allows specifying a child target definition' do podfile = Podfile.new do target :tests do pod 'OCMock' @@ -109,7 +109,7 @@ module Pod #-------------------------------------------------------------------------# describe 'Target configuration' do - it 'allows to specify a platform' do + it 'allows specifying a platform' do podfile = Podfile.new do platform :ios, '6.0' target :osx_target do @@ -120,9 +120,10 @@ module Pod podfile.target_definitions[:osx_target].platform.should == Platform.new(:osx, '10.8') end - it 'allows to specify whether the target is exclusive' do + it 'allows specifying whether the target is exclusive' do podfile = Podfile.new do - target 'Pods', :exclusive => true do + target 'Pods' do + inherit!(:none) end end podfile.target_definitions['Pods'].should.be.exclusive @@ -136,6 +137,55 @@ module Pod podfile.target_definitions['Pods'].should.not.be.exclusive end + it 'allows specifying whether the target is abstract' do + podfile = Podfile.new do + target 'App' do + abstract! + end + end + podfile.target_definitions['App'].should.be.abstract + end + + it 'is not abstract by default' do + podfile = Podfile.new do + target 'App' do + end + end + podfile.target_definitions['App'].should.not.be.abstract + end + + it 'allows specifying an abstract target' do + podfile = Podfile.new do + abstract_target 'App' do + end + end + podfile.target_definitions['App'].should.be.abstract + end + + describe 'inheritance' do + it 'allows specifying the inheritance mode for a target' do + modes = %w(search_paths complete none) + modes.each do |mode| + podfile = Podfile.new do + target 'App' do + inherit! mode + end + end + podfile.target_definitions['App'].inheritance.should == mode + end + end + + it 'raises when specifying an unknown mode' do + should.raise(Informative) do + Podfile.new do + target 'App' do + inherit! 'foo' + end + end + end.message.should == 'Unrecognized inheritance option `foo` specified for target `App`.' + end + end + it 'raises if unrecognized keys are passed during the initialization of a target' do should.raise Informative do Podfile.new do @@ -145,12 +195,12 @@ module Pod end end - it 'allows to specify the user Xcode project for a Target definition' do + it 'allows specifying the user Xcode project for a Target definition' do podfile = Podfile.new { xcodeproj 'App.xcodeproj' } podfile.target_definitions['Pods'].user_project_path.should == 'App.xcodeproj' end - it 'allows to specify the build configurations of a user project' do + it 'allows specifying the build configurations of a user project' do podfile = Podfile.new do xcodeproj 'App.xcodeproj', 'Mac App Store' => :release, 'Test' => :debug end @@ -159,21 +209,6 @@ module Pod } end - it 'allows to specify the user targets a Target definition should link with' do - podfile = Podfile.new { link_with 'app_target' } - podfile.target_definitions['Pods'].link_with.should == ['app_target'] - end - - it 'allows to specify multiple user targets a Target definition should link with' do - podfile = Podfile.new { link_with 'app_target', 'test_target' } - podfile.target_definitions['Pods'].link_with.should == %w(app_target test_target) - end - - it 'allows to specify an array of user targets a Target definition should link with' do - podfile = Podfile.new { link_with ['app_target'] } - podfile.target_definitions['Pods'].link_with.should == ['app_target'] - end - it 'allows to inhibit all the warnings of a Target definition' do podfile = Podfile.new do pod 'ObjectiveRecord' @@ -241,5 +276,33 @@ module Pod end #-------------------------------------------------------------------------# + + describe 'Installation Method' do + it 'allows specifying a custom installation method' do + podfile = Podfile.new do + install! 'method' + end + podfile.installation_method.should == ['method', {}] + end + + it 'allows specifying a custom installation method with options' do + podfile = Podfile.new do + install! 'method', 'option' => 'value' + end + podfile.installation_method.should == ['method', { 'option' => 'value' }] + end + + it 'raises when specifying an installation method outside of root' do + should.raise(Informative) do + Podfile.new do + target 'App' do + install! 'method' + end + end + end.message.should == 'The installation method can only be set at the root level of the Podfile.' + end + end + + #-------------------------------------------------------------------------# end end diff --git a/spec/podfile/target_definition_spec.rb b/spec/podfile/target_definition_spec.rb index 8819d6e33..099402ff8 100644 --- a/spec/podfile/target_definition_spec.rb +++ b/spec/podfile/target_definition_spec.rb @@ -4,81 +4,100 @@ module Pod describe Podfile::TargetDefinition do before do @podfile = Podfile.new - @root = Podfile::TargetDefinition.new('MyApp', @podfile) - @child = Podfile::TargetDefinition.new('MyAppTests', @root) - @root.set_platform(:ios, '6.0') + @root = Podfile::TargetDefinition.new('Pods', @podfile) + @parent = Podfile::TargetDefinition.new('MyApp', @root) + @child = Podfile::TargetDefinition.new('MyAppTests', @parent) + @child.inheritance = :search_paths + @parent.set_platform(:ios, '6.0') end #-------------------------------------------------------------------------# describe 'In general' do it 'returns its name' do - @root.name.should == 'MyApp' + @parent.name.should == 'MyApp' end it 'returns the parent' do @root.parent.should == @podfile - @child.parent.should == @root + @parent.parent.should == @root + @child.parent.should == @parent end #--------------------------------------# it 'returns the children' do - @root.children.should == [@child] + @parent.children.should == [@child] @child.children.should == [] end it 'returns the recursive children' do @grand_child = Podfile::TargetDefinition.new('MyAppTests', @child) - @root.recursive_children.should == [@child, @grand_child] + @parent.recursive_children.should == [@child, @grand_child] @child.recursive_children.should == [@grand_child] @grand_child.recursive_children.should == [] end it 'returns whether it is root' do @root.should.be.root + @parent.should.not.be.root @child.should.not.be.root end it 'returns the root target definition' do @root.root.should == @root + @parent.root.should == @root @child.root.should == @root end it 'returns the podfile that specifies it' do - @root.podfile.class.should == Podfile + @parent.podfile.class.should == Podfile @child.podfile.class.should == Podfile end it 'returns dependencies' do - @root.store_pod('BlocksKit') + @parent.store_pod('BlocksKit') @child.store_pod('OCMockito') - @root.dependencies.map(&:name).should == %w(BlocksKit) + @child.inheritance = :complete + @parent.dependencies.map(&:name).should == %w(BlocksKit) @child.dependencies.map(&:name).should == %w(OCMockito BlocksKit) end it "doesn't inherit dependencies if it is exclusive" do - @root.store_pod('BlocksKit') + @parent.store_pod('BlocksKit') @child.store_pod('OCMockito') - @child.exclusive = true + @child.inheritance = :none @child.dependencies.map(&:name).should == %w(OCMockito) end + it 'returns the targets to inherit search paths from' do + @child.inheritance = :search_paths + @child.targets_to_inherit_search_paths.should == [@parent] + + grandchild = Podfile::TargetDefinition.new('Grandchild', @child) + grandchild.inheritance = :search_paths + grandchild.targets_to_inherit_search_paths.should == [@parent, @child] + @child.inheritance = :complete + grandchild.targets_to_inherit_search_paths.should == [@child] + @child.inheritance = :none + grandchild.targets_to_inherit_search_paths.should == [@child] + end + it 'returns the non inherited dependencies' do - @root.store_pod('BlocksKit') + @parent.store_pod('BlocksKit') @child.store_pod('OCMockito') - @root.non_inherited_dependencies.map(&:name).should == %w(BlocksKit) + @parent.non_inherited_dependencies.map(&:name).should == %w(BlocksKit) @child.non_inherited_dependencies.map(&:name).should == %w(OCMockito) end it 'returns whether it is empty' do - @root.store_pod('BlocksKit') - @root.should.not.be.empty + @parent.store_pod('BlocksKit') + @parent.should.not.be.empty @child.should.be.empty end it 'returns its label' do - @root.label.should == 'Pods-MyApp' + @parent.label.should == 'Pods-MyApp' end it 'returns `Pods` as the label if its name is default' do @@ -87,11 +106,12 @@ module Pod end it 'includes the name of the parent in the label if any' do + @child.inheritance = :complete @child.label.should == 'Pods-MyApp-MyAppTests' end it "doesn't include the name of the parent in the label if it is exclusive" do - @child.exclusive = true + @child.inheritance = :none @child.label.should == 'Pods-MyAppTests' end end @@ -99,161 +119,161 @@ module Pod #-------------------------------------------------------------------------# describe 'Attributes accessors' do - it 'is not exclusive by default by the default if the platform of the parent match' do - @child.should.not.be.exclusive + it 'is not abstract by default' do + @child.should.not.be.abstract end - it "is exclusive by the default if the platform of the parent doesn't match" do - @root.set_platform(:osx, '10.6') - @child.set_platform(:ios, '6.0') - @child.should.be.exclusive - end - - it 'allows to set whether it is exclusive' do - @child.should.not.be.exclusive - @child.exclusive = true - @child.should.be.exclusive + it 'allows to set whether it is abstract' do + @child.abstract = true + @child.should.be.abstract end #--------------------------------------# - it "doesn't specify any target to link with by default" do - @root.link_with.should.be.nil + it 'has complete inheritance by default' do + Podfile::TargetDefinition.new('App', nil).inheritance.should == 'complete' end - it 'allows to set the names of the client targets that it should link with' do - @root.link_with = ['appTarget1, appTarget2'] - @root.link_with.should.be == ['appTarget1, appTarget2'] + it 'allows setting the inheritance' do + @child.inheritance = :complete + @child.inheritance.should == 'complete' + @child.inheritance = :none + @child.inheritance.should == 'none' + @child.inheritance = :search_paths + @child.inheritance.should == 'search_paths' end - it 'wraps the targets specified by the user in an array' do - @root.link_with = 'appTarget1' - @root.link_with.should.be == ['appTarget1'] + it 'raises when setting an unknown inheritance mode' do + exception = should.raise(Informative) { @child.inheritance = :unknown } + exception.message.should == 'Unrecognized inheritance option `unknown` specified for target `MyAppTests`.' end - it 'allows targets to be passed in the argument list instead of as an array' do - @root.link_with = 'appTarget1', 'appTarget2' - @root.link_with.should.be == %w(appTarget1 appTarget2) - end - - it 'returns nil if the link_with array is empty' do - @root.link_with = [] - @root.link_with.should.be.nil + it 'raises when setting an inheritance mode on a root target definition' do + exception = should.raise(Informative) { @root.inheritance = :none } + exception.message.should == 'Cannot set inheritance for the root target definition.' end #--------------------------------------# - it 'allows to specify whether it should link with the first target of project' do - @root.link_with_first_target = true - @root.should.link_with_first_target + it 'is exclusive by default by the default if the platform of the parent match' do + @child.should.be.exclusive + end + + it "is exclusive by the default if the platform of the parent doesn't match" do + @parent.set_platform(:osx, '10.6') + @child.set_platform(:ios, '6.0') + @child.should.be.exclusive end - it "returns that it shouldn't link with the first target if any target has been specified" do - @root.link_with = 'appTarget1' - @root.link_with_first_target = true - @root.should.not.link_with_first_target + it 'allows to set whether it is exclusive' do + @child.inheritance = :complete + @child.should.not.be.exclusive + @child.inheritance = :none + @child.should.be.exclusive + @child.inheritance = :search_paths + @child.should.be.exclusive end #--------------------------------------# it "doesn't specifies any user project by default" do - @root.user_project_path.should.be.nil + @parent.user_project_path.should.be.nil end it 'allows to set the path of the user project' do - @root.user_project_path = 'some/path/project.xcodeproj' - @root.user_project_path.should == 'some/path/project.xcodeproj' + @parent.user_project_path = 'some/path/project.xcodeproj' + @parent.user_project_path.should == 'some/path/project.xcodeproj' end it 'appends the extension to a specified user project if needed' do - @root.user_project_path = 'some/path/project' - @root.user_project_path.should == 'some/path/project.xcodeproj' + @parent.user_project_path = 'some/path/project' + @parent.user_project_path.should == 'some/path/project.xcodeproj' end it 'inherits the path of the user project from the parent' do - @root.user_project_path = 'some/path/project.xcodeproj' + @parent.user_project_path = 'some/path/project.xcodeproj' @child.user_project_path.should == 'some/path/project.xcodeproj' end #--------------------------------------# it "doesn't specifies any project build configurations default" do - @root.build_configurations.should.be.nil + @parent.build_configurations.should.be.nil end it 'allows to set the project build configurations' do - @root.build_configurations = { 'Debug' => :debug, 'Release' => :release } - @root.build_configurations.should == { 'Debug' => :debug, 'Release' => :release } + @parent.build_configurations = { 'Debug' => :debug, 'Release' => :release } + @parent.build_configurations.should == { 'Debug' => :debug, 'Release' => :release } end it 'inherits the project build configurations from the parent' do - @root.build_configurations = { 'Debug' => :debug, 'Release' => :release } + @parent.build_configurations = { 'Debug' => :debug, 'Release' => :release } @child.build_configurations.should == { 'Debug' => :debug, 'Release' => :release } end #--------------------------------------# it "doesn't add extra subspec dependencies by default" do - @root.store_pod('RestKit') - @root.dependencies.map(&:name).should == %w(RestKit) + @parent.store_pod('RestKit') + @parent.dependencies.map(&:name).should == %w(RestKit) end it 'allows depending on subspecs' do - @root.store_pod('RestKit', :subspecs => %w(Networking)) - @root.dependencies.map(&:name).sort.should == %w(RestKit/Networking) + @parent.store_pod('RestKit', :subspecs => %w(Networking)) + @parent.dependencies.map(&:name).sort.should == %w(RestKit/Networking) end #--------------------------------------# it "doesn't inhibit warnings per pod by default" do - @root.store_pod('ObjectiveSugar') - @root.should.not.inhibits_warnings_for_pod?('ObjectiveSugar') + @parent.store_pod('ObjectiveSugar') + @parent.should.not.inhibits_warnings_for_pod?('ObjectiveSugar') end it 'inhibits warnings per pod if passed to store_pod' do - @root.store_pod('Objective-Record', :head, :inhibit_warnings => true) - @root.should.inhibits_warnings_for_pod?('Objective-Record') + @parent.store_pod('Objective-Record', :head, :inhibit_warnings => true) + @parent.should.inhibits_warnings_for_pod?('Objective-Record') - @root.store_pod('RestKit/Networking', :head, :inhibit_warnings => true) - @root.should.inhibits_warnings_for_pod?('RestKit') + @parent.store_pod('RestKit/Networking', :head, :inhibit_warnings => true) + @parent.should.inhibits_warnings_for_pod?('RestKit') end it 'must delete the hash if it was empty. otherwise breaks Dependency' do reqs = [{ :inhibit_warnings => true }] - @root.send(:parse_inhibit_warnings, 'Objective-Record', reqs) + @parent.send(:parse_inhibit_warnings, 'Objective-Record', reqs) reqs.should.be.empty end it 'returns if it should inhibit all warnings' do - @root.inhibit_all_warnings = true - @root.should.inhibits_warnings_for_pod?('ObjectiveSugar') + @parent.inhibit_all_warnings = true + @parent.should.inhibits_warnings_for_pod?('ObjectiveSugar') end it 'inherits the option to inhibit all warnings' do - @root.inhibit_all_warnings = true + @parent.inhibit_all_warnings = true @child.store_pod('ASIHTTPRequest') @child.should.inhibits_warnings_for_pod?('ASIHTTPRequest') end it 'inherits the option to inhibit warnings per pod' do - @root.store_pod('Objective-Record', :inhibit_warnings => true) + @parent.store_pod('Objective-Record', :inhibit_warnings => true) @child.should.inhibits_warnings_for_pod?('Objective-Record') end #--------------------------------------# it 'returns if it should use frameworks' do - @root.use_frameworks! - @root.should.uses_frameworks? + @parent.use_frameworks! + @parent.should.uses_frameworks? end it 'inherits the option to use frameworks' do - @root.use_frameworks! + @parent.use_frameworks! @child.should.uses_frameworks? end it 'allows children to opt-out of using frameworks' do - @root.use_frameworks! + @parent.use_frameworks! @child.use_frameworks!(false) @child.should.not.uses_frameworks? end @@ -261,41 +281,41 @@ module Pod #--------------------------------------# it 'whitelists pods by default' do - @root.store_pod('ObjectiveSugar') - @root.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') + @parent.store_pod('ObjectiveSugar') + @parent.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') @child.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') end it 'does not enable pods for un-whitelisted configurations if it is whitelisted for another' do - @root.store_pod('ObjectiveSugar') - @root.whitelist_pod_for_configuration('ObjectiveSugar', 'Release') - @root.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') + @parent.store_pod('ObjectiveSugar') + @parent.whitelist_pod_for_configuration('ObjectiveSugar', 'Release') + @parent.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') @child.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') end it 'enables pods for configurations they are whitelisted for' do - @root.store_pod('ObjectiveSugar', :configuration => 'Release') - @root.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') - @root.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') + @parent.store_pod('ObjectiveSugar', :configuration => 'Release') + @parent.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') + @parent.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') @child.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') @child.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') - @root.store_pod('AFNetworking', :configurations => ['Debug']) - @root.should.pod_whitelisted_for_configuration?('AFNetworking', 'Debug') - @root.should.not.pod_whitelisted_for_configuration?('AFNetworking', 'Release') + @parent.store_pod('AFNetworking', :configurations => ['Debug']) + @parent.should.pod_whitelisted_for_configuration?('AFNetworking', 'Debug') + @parent.should.not.pod_whitelisted_for_configuration?('AFNetworking', 'Release') @child.should.pod_whitelisted_for_configuration?('AFNetworking', 'Debug') @child.should.not.pod_whitelisted_for_configuration?('AFNetworking', 'Release') end it 'coerces configuration names to strings' do - @root.store_pod('ObjectiveSugar', :configuration => :Release) - @root.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') - @root.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') + @parent.store_pod('ObjectiveSugar', :configuration => :Release) + @parent.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') + @parent.should.not.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Debug') end it 'compares build configurations case-insensitively' do - @root.store_pod('ObjectiveSugar', :configuration => :Release) - @root.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') - @root.should.pod_whitelisted_for_configuration?('objectivesugar', 'Release') + @parent.store_pod('ObjectiveSugar', :configuration => :Release) + @parent.should.pod_whitelisted_for_configuration?('ObjectiveSugar', 'Release') + @parent.should.pod_whitelisted_for_configuration?('objectivesugar', 'Release') end it 'returns a unique list of all whitelisted configurations' do @@ -312,38 +332,38 @@ module Pod #--------------------------------------# it 'returns its platform' do - @root.platform.should == Pod::Platform.new(:ios, '6.0') + @parent.platform.should == Pod::Platform.new(:ios, '6.0') end it 'inherits the platform form the parent' do - @root.platform.should == Pod::Platform.new(:ios, '6.0') + @parent.platform.should == Pod::Platform.new(:ios, '6.0') end it 'provides a default deployment target if not specified' do - @root.set_platform(:ios) - @root.platform.should == Pod::Platform.new(:ios, '4.3') + @parent.set_platform(:ios) + @parent.platform.should == Pod::Platform.new(:ios, '4.3') - @root.set_platform(:osx) - @root.platform.should == Pod::Platform.new(:osx, '10.6') + @parent.set_platform(:osx) + @parent.platform.should == Pod::Platform.new(:osx, '10.6') end it 'raises if the specified platform is unsupported' do - e = lambda { @root.set_platform(:win) }.should.raise Podfile::StandardError + e = lambda { @parent.set_platform(:win) }.should.raise Podfile::StandardError e.message.should.match /Unsupported platform/ end #--------------------------------------# it 'stores a dependency on a pod as a sting if no requirements are provided' do - @root.store_pod('BlocksKit') - @root.send(:get_hash_value, 'dependencies').should == [ + @parent.store_pod('BlocksKit') + @parent.send(:get_hash_value, 'dependencies').should == [ 'BlocksKit', ] end it 'stores a dependency on a pod as a hash if requirements provided' do - @root.store_pod('Reachability', '1.0') - @root.send(:get_hash_value, 'dependencies').should == [ + @parent.store_pod('Reachability', '1.0') + @parent.send(:get_hash_value, 'dependencies').should == [ { 'Reachability' => ['1.0'] }, ] end @@ -351,21 +371,21 @@ module Pod #--------------------------------------# it 'stores a dependency on a podspec' do - @root.store_podspec(:name => 'BlocksKit') - @root.send(:get_hash_value, 'podspecs').should == [ + @parent.store_podspec(:name => 'BlocksKit') + @parent.send(:get_hash_value, 'podspecs').should == [ { :name => 'BlocksKit' }, ] end it 'stores a dependency on a podspec and sets is as auto-detect if no options are provided' do - @root.store_podspec - @root.send(:get_hash_value, 'podspecs').should == [ + @parent.store_podspec + @parent.send(:get_hash_value, 'podspecs').should == [ { :autodetect => true }, ] end it 'raises if the provided podspec options are unsupported' do - e = lambda { @root.store_podspec(:invent => 'BlocksKit') }.should.raise Podfile::StandardError + e = lambda { @parent.store_podspec(:invent => 'BlocksKit') }.should.raise Podfile::StandardError e.message.should.match /Unrecognized options/ end end @@ -378,22 +398,24 @@ module Pod @child.set_platform(:ios) @child.to_hash.should == { 'name' => 'MyAppTests', + 'inheritance' => 'search_paths', 'dependencies' => ['BlocksKit'], 'platform' => 'ios', } end it 'stores the children in the hash representation' do - Podfile::TargetDefinition.new('MoarTests', @root) - @root.store_pod('BlocksKit') + Podfile::TargetDefinition.new('MoarTests', @parent) + @parent.store_pod('BlocksKit') @child.store_pod('RestKit') - @root.to_hash.should == { + @parent.to_hash.should == { 'name' => 'MyApp', 'platform' => { 'ios' => '6.0' }, 'dependencies' => ['BlocksKit'], 'children' => [ { 'name' => 'MyAppTests', + 'inheritance' => 'search_paths', 'dependencies' => ['RestKit'], }, { @@ -404,10 +426,10 @@ module Pod end it 'can be initialized from a hash' do - @root.store_pod('BlocksKit') + @parent.store_pod('BlocksKit') @child.store_pod('RestKit') - converted = Podfile::TargetDefinition.from_hash(@root.to_hash, @podfile) - converted.to_hash.should == @root.to_hash + converted = Podfile::TargetDefinition.from_hash(@parent.to_hash, @podfile) + converted.to_hash.should == @parent.to_hash end end @@ -415,25 +437,25 @@ module Pod describe 'Private helpers' do before do - @root.podfile.defined_in_file = SpecHelper::Fixture.fixture('Podfile') + @parent.podfile.defined_in_file = SpecHelper::Fixture.fixture('Podfile') end #--------------------------------------# it 'sets and retrieves a value in the internal hash' do - @root.send(:set_hash_value, 'name', 'Fabio') - @root.send(:get_hash_value, 'name').should.equal 'Fabio' + @parent.send(:set_hash_value, 'name', 'Fabio') + @parent.send(:get_hash_value, 'name').should.equal 'Fabio' end it 'raises if there is an attempt to access or set an unknown key in the internal hash' do - lambda { @root.send(:set_hash_value, 'unknown', true) }.should.raise Pod::Podfile::StandardError - lambda { @root.send(:get_hash_value, 'unknown') }.should.raise Pod::Podfile::StandardError + lambda { @parent.send(:set_hash_value, 'unknown', true) }.should.raise Pod::Podfile::StandardError + lambda { @parent.send(:get_hash_value, 'unknown') }.should.raise Pod::Podfile::StandardError end it 'returns the dependencies specified by the user' do - @root.store_pod('BlocksKit') - @root.store_pod('AFNetworking', '1.0') - dependencies = @root.send(:pod_dependencies) + @parent.store_pod('BlocksKit') + @parent.store_pod('AFNetworking', '1.0') + dependencies = @parent.send(:pod_dependencies) dependencies.map(&:to_s).should == ['BlocksKit', 'AFNetworking (= 1.0)'] end @@ -441,29 +463,29 @@ module Pod describe '#pod_dependencies' do it 'handles dependencies which only indicate the name of the Pod' do - @root.store_pod('BlocksKit') - @root.send(:pod_dependencies).should == [ + @parent.store_pod('BlocksKit') + @parent.send(:pod_dependencies).should == [ Dependency.new('BlocksKit'), ] end it 'handles requirements' do - @root.store_pod('BlocksKit', '> 1.0', '< 2.5') - @root.send(:pod_dependencies).should == [ + @parent.store_pod('BlocksKit', '> 1.0', '< 2.5') + @parent.send(:pod_dependencies).should == [ Dependency.new('BlocksKit', ['> 1.0', '< 2.5']), ] end it 'handles subspecs' do - @root.store_pod('Spec/Subspec') - @root.send(:pod_dependencies).should == [ + @parent.store_pod('Spec/Subspec') + @parent.send(:pod_dependencies).should == [ Dependency.new('Spec/Subspec'), ] end it 'handles dependencies options' do - @root.store_pod('BlocksKit', :git => 'GIT-URL', :commit => '1234') - @root.send(:pod_dependencies).should == [ + @parent.store_pod('BlocksKit', :git => 'GIT-URL', :commit => '1234') + @parent.send(:pod_dependencies).should == [ Dependency.new('BlocksKit', :git => 'GIT-URL', :commit => '1234'), ] end @@ -474,20 +496,20 @@ module Pod describe '#podspec_dependencies' do it 'returns the dependencies of podspecs' do path = SpecHelper::Fixture.fixture('BananaLib.podspec').to_s - @root.store_podspec(:path => path) - @root.send(:podspec_dependencies).should == [ + @parent.store_podspec(:path => path) + @parent.send(:podspec_dependencies).should == [ Dependency.new('monkey', '< 1.0.9', '~> 1.0.1'), ] end it 'reject the dependencies on subspecs' do path = SpecHelper::Fixture.fixture('BananaLib.podspec').to_s - @root.store_podspec(:path => path) + @parent.store_podspec(:path => path) external_dep = Dependency.new('monkey', '< 1.0.9', '~> 1.0.1') internal_dep = Dependency.new('BananaLib/subspec') deps = [external_dep, internal_dep] Specification.any_instance.stubs(:dependencies).returns([deps]) - @root.send(:podspec_dependencies).should == [ + @parent.send(:podspec_dependencies).should == [ Dependency.new('monkey', '< 1.0.9', '~> 1.0.1'), ] end @@ -498,57 +520,57 @@ module Pod describe '#podspec_path_from_options' do it 'resolves a podspec given the absolute path' do options = { :path => SpecHelper::Fixture.fixture('BananaLib') } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec') end it 'resolves a podspec given the relative path' do options = { :path => 'BananaLib.podspec' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec') end it 'add the extension if needed' do options = { :path => 'BananaLib' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec') end it "doesn't add an extension for json podspecs" do options = { :path => 'BananaLib.podspec.json' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec.json') end it 'it expands the tilde in the provided path' do home_dir = File.expand_path('~') options = { :path => '~/BananaLib.podspec' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == Pathname.new("#{home_dir}/BananaLib.podspec") end it 'resolves a podspec given its name' do options = { :name => 'BananaLib' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec') end it "doesn't add an extension for json podspecs" do options = { :name => 'BananaLib.podspec.json' } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec.json') end it 'auto-detects the podspec' do options = { :autodetect => true } - file = @root.send(:podspec_path_from_options, options) + file = @parent.send(:podspec_path_from_options, options) file.should == SpecHelper::Fixture.fixture('BananaLib.podspec') end it 'raise an Informative error if the podspec cannot be auto-detected' do - @root.podfile.defined_in_file = SpecHelper::Fixture.fixture('podfile_without_root_podspec/Podfile') + @parent.podfile.defined_in_file = SpecHelper::Fixture.fixture('podfile_without_root_podspec/Podfile') options = { :autodetect => true } - e = lambda { @root.send(:podspec_path_from_options, options) }.should.raise Pod::Informative + e = lambda { @parent.send(:podspec_path_from_options, options) }.should.raise Pod::Informative e.message.should.match /Could not locate a podspec in the/ end end diff --git a/spec/podfile_spec.rb b/spec/podfile_spec.rb index 74acf8a84..4e22bcd00 100644 --- a/spec/podfile_spec.rb +++ b/spec/podfile_spec.rb @@ -23,11 +23,6 @@ module Pod podfile.root_target_definitions.first.name.should == 'Pods' end - it 'specifies that the default target definition should link with the first target of the project' do - podfile = Podfile.new {} - podfile.root_target_definitions.first.should.link_with_first_target - end - extend SpecHelper::TemporaryDirectory it 'includes the line of the podfile that generated an exception' do @@ -114,6 +109,16 @@ module Pod Podfile.new { set_arc_compatibility_flag! }.should.set_arc_compatibility_flag end + it 'returns the installation method' do + name, options = Podfile.new {}.installation_method + name.should == 'cocoapods' + options.should == {} + + name, options = Podfile.new { install! 'install-method', :option1 => 'value1', 'option2' => false }.installation_method + name.should == 'install-method' + options.should == { :option1 => 'value1', 'option2' => false } + end + describe 'source' do it 'can have multiple sources' do Podfile.new do @@ -150,12 +155,19 @@ module Pod it 'returns the hash representation' do podfile = Podfile.new do pod 'ASIHTTPRequest' + target 'App' do + end end podfile.to_hash.should == { 'target_definitions' => [ 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => ['ASIHTTPRequest'], + 'children' => [ + { + 'name' => 'App', + }, + ], ], } end @@ -165,12 +177,20 @@ module Pod workspace('MyApp.xcworkspace') generate_bridge_support! set_arc_compatibility_flag! + install! 'install-method', :option1 => 'value1', 'option2' => false end podfile.to_hash.should == { - 'target_definitions' => [{ 'name' => 'Pods', 'link_with_first_target' => true }], + 'target_definitions' => [{ 'name' => 'Pods', 'abstract' => true }], 'workspace' => 'MyApp.xcworkspace', 'generate_bridge_support' => true, 'set_arc_compatibility_flag' => true, + 'installation_method' => { + 'name' => 'install-method', + 'options' => { + :option1 => 'value1', + 'option2' => false, + }, + }, } end @@ -179,18 +199,27 @@ module Pod pod 'ASIHTTPRequest' target 'sub-target' do pod 'JSONKit' + target 'test_target' do + inherit!(:search_paths) + end end end podfile.to_hash.should == { 'target_definitions' => [ { 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => ['ASIHTTPRequest'], 'children' => [ { 'name' => 'sub-target', 'dependencies' => ['JSONKit'], + 'children' => [ + { + 'name' => 'test_target', + 'inheritance' => 'search_paths', + }, + ], }, ], }, @@ -204,12 +233,18 @@ module Pod pod 'JSONKit', '> 1.0', :inhibit_warnings => true generate_bridge_support! set_arc_compatibility_flag! + install! 'install-method', :option1 => 'value1', 'option2' => false end expected = <<-EOF.strip_heredoc --- + installation_method: + name: install-method + options: + :option1: value1 + option2: false target_definitions: - name: Pods - link_with_first_target: true + abstract: true dependencies: - ASIHTTPRequest - JSONKit: @@ -244,7 +279,7 @@ module Pod podfile.to_hash.should == { 'target_definitions' => [ 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'inhibit_warnings' => { 'for_pods' => ['ASIHTTPRequest'], }, @@ -261,7 +296,7 @@ module Pod podfile.to_hash.should == { 'target_definitions' => [ 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => ['ObjectiveSugar'], 'inhibit_warnings' => { 'all' => true, @@ -278,7 +313,7 @@ module Pod podfile.to_hash.should == { 'target_definitions' => [ 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => ['ObjectiveSugar'], 'uses_frameworks' => true, ], @@ -295,7 +330,7 @@ module Pod 'target_definitions' => [ { 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => %w(ASIHTTPRequest), }, ], @@ -318,7 +353,7 @@ module Pod 'target_definitions' => [ { 'name' => 'Pods', - 'link_with_first_target' => true, + 'abstract' => true, 'dependencies' => %w(ASIHTTPRequest), }, ], @@ -388,21 +423,19 @@ module Pod podfile.send(:get_hash_value, 'generate_bridge_support').should.be.true end - it 'raises if there is an attempt to access or set an unknown key in the internal hash' do + it 'allows specifying a default value when fetching from the hash' do podfile = Podfile.new - lambda { podfile.send(:set_hash_value, 'unknown', true) }.should.raise Pod::Podfile::StandardError - lambda { podfile.send(:get_hash_value, 'unknown') }.should.raise Pod::Podfile::StandardError - end - end - #-------------------------------------------------------------------------# + podfile.send(:get_hash_value, 'generate_bridge_support', 'default').should == 'default' - describe 'Deprecations' do - it 'Warns about the deprecated dependency DSL directive' do + podfile.send(:set_hash_value, 'generate_bridge_support', true) + podfile.send(:get_hash_value, 'generate_bridge_support', 'default').should.be.true + end + + it 'raises if there is an attempt to access or set an unknown key in the internal hash' do podfile = Podfile.new - podfile.expects(:pod).with('My-Pod') - podfile.dependency 'My-Pod' - CoreUI.warnings.should.match /DEPRECATED/ + lambda { podfile.send(:set_hash_value, 'unknown', true) }.should.raise Pod::Podfile::StandardError + lambda { podfile.send(:get_hash_value, 'unknown') }.should.raise Pod::Podfile::StandardError end end @@ -418,8 +451,8 @@ module Pod pod 'SSZipArchive' end - target :test, :exclusive => true do - link_with 'TestRunner' + target :test do + inherit! :search_paths inhibit_all_warnings! use_frameworks! pod 'JSONKit' @@ -431,7 +464,6 @@ module Pod target :osx_target do platform :osx xcodeproj 'OSX Project.xcodeproj', 'Mac App Store' => :release, 'Test' => :debug - link_with 'OSXTarget' pod 'ASIHTTPRequest' target :nested_osx_target do end @@ -468,16 +500,6 @@ module Pod target.dependencies.should == [Dependency.new('Reachability'), Dependency.new('JSONKit')] end - it 'leaves the name of the target, to link with, to be automatically resolved' do - target = @podfile.target_definitions['Pods'] - target.link_with.should.nil? - end - - it 'returns the names of the explicit targets to link with' do - target = @podfile.target_definitions[:test] - target.link_with.should == ['TestRunner'] - end - it 'returns the platform of the target' do @podfile.target_definitions['Pods'].platform.should == :ios @podfile.target_definitions[:test].platform.should == :ios diff --git a/spec/specification/dsl/deprecations_spec.rb b/spec/specification/dsl/deprecations_spec.rb index 8ae87a148..adbd367ec 100644 --- a/spec/specification/dsl/deprecations_spec.rb +++ b/spec/specification/dsl/deprecations_spec.rb @@ -5,11 +5,5 @@ module Pod before do @spec = Spec.new end - - it 'warns about the renamed `preferred_dependency`' do - @spec.preferred_dependency = 'args' - @spec.attributes_hash['default_subspecs'].should == %w(args) - CoreUI.warnings.should.match /preferred_dependency.*default_subspec/ - end end end diff --git a/spec/specification/json_spec.rb b/spec/specification/json_spec.rb index 6bc550c5b..06fc1798b 100644 --- a/spec/specification/json_spec.rb +++ b/spec/specification/json_spec.rb @@ -130,10 +130,6 @@ module Pod result = Specification.from_hash(@spec.to_hash) result.should == @spec end - - it 'returns whether it safe to convert a specification to hash' do - @spec.safe_to_hash?.should.be.true - end end end end diff --git a/spec/specification_spec.rb b/spec/specification_spec.rb index 9f8ac67f9..070245e2a 100644 --- a/spec/specification_spec.rb +++ b/spec/specification_spec.rb @@ -347,11 +347,6 @@ module Pod @spec.local?.should.be.true end - it '[0.18 backwards compatibility] reports if it is locally sourced' do - @spec.source = { 'local' => '/tmp/local/path' } - @spec.local?.should.be.true - end - it 'returns whether it is supported on a given platform' do @spec.platform = :ios, '4.0' @spec.supported_on_platform?(:ios).should.be.true diff --git a/spec/version_spec.rb b/spec/version_spec.rb index 0bfd5afca..69ee093ee 100644 --- a/spec/version_spec.rb +++ b/spec/version_spec.rb @@ -3,32 +3,20 @@ module Pod describe Version do describe 'In general' do - it 'returns whether it is a `head` version' do - version = Version.new('1.2.3') - version.should.not.be.head - version.head = true - version.should.be.head - end - it 'initializes from a string' do version = Version.new('1.2.3') - version.should.not.be.head + version.version.should == '1.2.3' end it 'initializes from a frozen string' do version = Version.new('1.2.3'.freeze) - version.should.not.be.head + version.version.should == '1.2.3' end it 'initializes from a string containing head information' do version = Version.new('HEAD based on 1.2.3') - version.should.be.head - end - - it 'initializes from another version containing head information' do - head_version = Version.new('HEAD based on 1.2.3') - version = Version.new(head_version) - version.should.be.head + version.version.should == '1.2.3' + CoreUI.warnings.should == 'Ignoring obsolete HEAD specifier in `HEAD based on 1.2.3`' end it 'serializes to a string' do @@ -36,18 +24,6 @@ module Pod version.to_s.should == '1.2.3' end - it 'preserves head information when serializing to a string' do - version = Version.new('1.2.3') - version.head = true - version.to_s.should == 'HEAD based on 1.2.3' - end - - it 'supports the previous way that a HEAD version was described' do - version = Version.new('HEAD from 1.2.3') - version.should.be.head - version.to_s.should == 'HEAD based on 1.2.3' - end - it 'identifies release versions' do version = Version.new('1.0.0') version.should.not.be.prerelease