Commit 16a324a7 authored by Fabio Pelosin's avatar Fabio Pelosin

Merge pull request #347 from CocoaPods/t-296

Support for `header_dir` attr in subspecs.
parents d4bc7371 f4326c73
...@@ -13,6 +13,7 @@ examples/Pods ...@@ -13,6 +13,7 @@ examples/Pods
examples/**/Pods examples/**/Pods
examples/RelativePathProject/RelativePathProject/RelativePathProject.xcodeproj examples/RelativePathProject/RelativePathProject/RelativePathProject.xcodeproj
spec/fixtures/banana-lib spec/fixtures/banana-lib
spec/fixtures/chameleon
spec/fixtures/integration/Headers/ spec/fixtures/integration/Headers/
/concatenated.* /concatenated.*
spec/fixtures/mercurial-repo/.hg/*cache spec/fixtures/mercurial-repo/.hg/*cache
......
...@@ -145,7 +145,7 @@ namespace :gem do ...@@ -145,7 +145,7 @@ namespace :gem do
# Update the last version in CocoaPods-version.yml # Update the last version in CocoaPods-version.yml
specs_branch = '0.6' specs_branch = '0.6'
Dir.chdir ('../Specs') do Dir.chdir('../Specs') do
puts Dir.pwd puts Dir.pwd
sh "git checkout #{specs_branch}" sh "git checkout #{specs_branch}"
sh "git pull" sh "git pull"
......
...@@ -406,7 +406,7 @@ module Pod ...@@ -406,7 +406,7 @@ module Pod
def file_patterns_errors def file_patterns_errors
messages = [] messages = []
messages << "The sources did not match any file" if !@spec.source_files.empty? && @pod.source_files.empty? messages << "The sources did not match any file" if !@spec.source_files.empty? && @pod.source_files.empty?
messages << "The resources did not match any file" if !@spec.resources.empty? && @pod.resources.empty? messages << "The resources did not match any file" if !@spec.resources.empty? && @pod.resource_files.empty?
messages << "The preserve_paths did not match any file" if !@spec.preserve_paths.empty? && @pod.preserve_paths.empty? messages << "The preserve_paths did not match any file" if !@spec.preserve_paths.empty? && @pod.preserve_paths.empty?
messages << "The exclude_header_search_paths did not match any file" if !@spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty? messages << "The exclude_header_search_paths did not match any file" if !@spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty?
messages messages
......
...@@ -29,7 +29,7 @@ module Pod ...@@ -29,7 +29,7 @@ module Pod
pods.each do |pod| pods.each do |pod|
# Add all source files to the project grouped by pod # Add all source files to the project grouped by pod
group = @project.add_pod_group(pod.name) group = @project.add_pod_group(pod.name)
pod.source_files.each do |path| pod.relative_source_files.each do |path|
group.files.new('path' => path.to_s) group.files.new('path' => path.to_s)
end end
end end
......
...@@ -20,12 +20,12 @@ module Pod ...@@ -20,12 +20,12 @@ module Pod
end end
def copy_resources_script_for(pods) def copy_resources_script_for(pods)
@copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map { |p| p.resources }.flatten) @copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map { |p| p.relative_resource_files }.flatten)
end end
def bridge_support_generator_for(pods, sandbox) def bridge_support_generator_for(pods, sandbox)
Generator::BridgeSupport.new(pods.map do |pod| Generator::BridgeSupport.new(pods.map do |pod|
pod.header_files.map { |header| sandbox.root + header } pod.relative_header_files.map { |header| sandbox.root + header }
end.flatten) end.flatten)
end end
......
...@@ -13,10 +13,13 @@ module Pod ...@@ -13,10 +13,13 @@ module Pod
# safely cleaned by the pod. # safely cleaned by the pod.
# #
# @example # @example
#
# pod = LocalPod.new 'RestKit/Networking' # pod = LocalPod.new 'RestKit/Networking'
# pod.add_specification 'RestKit/UI' # pod.add_specification 'RestKit/UI'
# #
# @note
# Unless otherwise specified in the name of the method the {LocalPod}
# returns absolute paths.
#
class LocalPod class LocalPod
# @return [Specification] The specification that describes the pod. # @return [Specification] The specification that describes the pod.
...@@ -140,6 +143,7 @@ module Pod ...@@ -140,6 +143,7 @@ module Pod
# #
def clean def clean
clean_paths.each { |path| FileUtils.rm_rf(path) } clean_paths.each { |path| FileUtils.rm_rf(path) }
@cleaned = true
end end
# Finds the absolute paths, including hidden ones, of the files # Finds the absolute paths, including hidden ones, of the files
...@@ -148,7 +152,7 @@ module Pod ...@@ -148,7 +152,7 @@ module Pod
# @return [Array<Strings>] The paths that can be deleted. # @return [Array<Strings>] The paths that can be deleted.
# #
def clean_paths def clean_paths
cached_used_paths = used_paths.map{ |path| path.to_s } cached_used_paths = used_files
files = Dir.glob(root + "**/*", File::FNM_DOTMATCH) files = Dir.glob(root + "**/*", File::FNM_DOTMATCH)
files.reject! do |candidate| files.reject! do |candidate|
...@@ -159,51 +163,77 @@ module Pod ...@@ -159,51 +163,77 @@ module Pod
files files
end end
# @return [Array<Pathname>] The relative path of the files used by the pod. # @return [Array<String>] The absolute path of the files used by the pod.
# #
def used_paths def used_files
files = [ source_files(false), files = [ source_files, resource_files, preserve_files, readme_file, license_file, prefix_header_file ]
resources(false),
preserve_paths,
readme_file,
license_file,
prefix_header_file ]
files.compact! files.compact!
files.flatten! files.flatten!
files.map!{ |path| path.to_s }
files files
end end
# @!group Files # @!group Files
# @param (see #source_files_by_spec)
#
# @return [Array<Pathname>] The paths of the source files. # @return [Array<Pathname>] The paths of the source files.
# #
def source_files(relative = true) def source_files
chained_expanded_paths(:source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => relative) source_files_by_spec.values.flatten
end end
# Finds the source files that every activated {Specification} requires. # @return [Array<Pathname>] The *relative* paths of the source files.
# #
# @param [Boolean] relative Whether the paths should be returned relative def relative_source_files
# to the sandbox. source_files.map{ |p| p.relative_path_from(@sandbox.root) }
end
# Finds the source files that every activated {Specification} requires.
# #
# @note If the same file is required by two specifications the one at the # @note If the same file is required by two specifications the one at the
# higher level in the inheritance chain wins. # higher level in the inheritance chain wins.
# #
# @return [Hash{Specification => Array<Pathname>}] The files grouped by
# {Specification}.
#
def source_files_by_spec
options = {:glob => '*.{h,m,mm,c,cpp}'}
paths_by_spec(:source_files, options)
end
# @return [Array<Pathname>] The paths of the header files. # @return [Array<Pathname>] The paths of the header files.
# #
def header_files def header_files
source_files.select { |f| f.extname == '.h' } header_files_by_spec.values.flatten
end
# @return [Array<Pathname>] The *relative* paths of the source files.
#
def relative_header_files
header_files.map{ |p| p.relative_path_from(@sandbox.root) }
end end
# @return [Hash{Specification => Array<Pathname>}] The paths of the header # @return [Hash{Specification => Array<Pathname>}] The paths of the header
# files grouped by {Specification}. # files grouped by {Specification}.
# #
def header_files_by_spec
result = {}
source_files_by_spec.each do |spec, paths|
headers = paths.select { |f| f.extname == '.h' }
result[spec] = headers unless headers.empty?
end
result
end
# @return [Array<Pathname>] The paths of the resources. # @return [Array<Pathname>] The paths of the resources.
# #
def resources(relative = true) def resource_files
chained_expanded_paths(:resources, :relative_to_sandbox => relative) paths_by_spec(:resources).values.flatten
end
# @return [Array<Pathname>] The *relative* paths of the resources.
#
def relative_resource_files
resource_files.map{ |p| p.relative_path_from(@sandbox.root) }
end end
# @return [Pathname] The absolute path of the prefix header file # @return [Pathname] The absolute path of the prefix header file
...@@ -215,11 +245,15 @@ module Pod ...@@ -215,11 +245,15 @@ module Pod
# @return [Array<Pathname>] The absolute paths of the files of the pod # @return [Array<Pathname>] The absolute paths of the files of the pod
# that should be preserved. # that should be preserved.
# #
def preserve_paths def preserve_files
chained_expanded_paths(:preserve_paths) + expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ]) paths = paths_by_spec(:preserve_paths).values
paths += expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
paths.compact!
paths.uniq!
paths
end end
# @return [Pathname] The automatically detected path of the README # @return [Pathname] The automatically detected absolute path of the README
# file. # file.
# #
def readme_file def readme_file
...@@ -266,9 +300,16 @@ module Pod ...@@ -266,9 +300,16 @@ module Pod
# @return [Array<Pathname>] The path of all the public headers of the pod. # @return [Array<Pathname>] The path of all the public headers of the pod.
# #
def all_specs_public_header_files def all_specs_public_header_files
#TODO: merge with #221 if @cleaned
specs = top_specification.recursive_subspecs << top_specification raise Informative, "The pod is cleaned and cannot compute the all the "\
specs.map { |s| expanded_paths(s.source_files, :glob => '*.{h}') }.compact.flatten.select { |f| f.extname == '.h' }.uniq "header files as they might be deleted."
end
all_specs = [ top_specification ] + top_specification.subspecs
options = {:glob => '*.{h}'}
files = paths_by_spec(:source_files, options, all_specs).values.flatten!
headers = files.select { |f| f.extname == '.h' }
headers
end end
# @!group Target integration # @!group Target integration
...@@ -276,7 +317,8 @@ module Pod ...@@ -276,7 +317,8 @@ module Pod
# @return [void] Copies the pods headers to the sandbox. # @return [void] Copies the pods headers to the sandbox.
# #
def link_headers def link_headers
copy_header_mappings.each do |namespaced_path, files| @sandbox.add_header_search_path(headers_sandbox)
header_mappings.each do |namespaced_path, files|
@sandbox.add_header_files(namespaced_path, files) @sandbox.add_header_files(namespaced_path, files)
end end
end end
...@@ -287,8 +329,9 @@ module Pod ...@@ -287,8 +329,9 @@ module Pod
# @return [void] Adds the pods source files to a given target. # @return [void] Adds the pods source files to a given target.
# #
def add_to_target(target) def add_to_target(target)
sources_files_by_specification.each do | spec, files | source_files_by_spec.each do | spec, files |
files.each do |file| files.each do |file|
file = file.relative_path_from(@sandbox.root)
target.add_source_file(file, nil, spec.compiler_flags.strip) target.add_source_file(file, nil, spec.compiler_flags.strip)
end end
end end
...@@ -306,7 +349,7 @@ module Pod ...@@ -306,7 +349,7 @@ module Pod
# (the files the need to compiled) of the pod. # (the files the need to compiled) of the pod.
# #
def implementation_files def implementation_files
source_files.select { |f| f.extname != '.h' } relative_source_files.select { |f| f.extname != '.h' }
end end
# @return [Pathname] The path of the pod relative from the sandbox. # @return [Pathname] The path of the pod relative from the sandbox.
...@@ -315,63 +358,67 @@ module Pod ...@@ -315,63 +358,67 @@ module Pod
root.relative_path_from(@sandbox.root) root.relative_path_from(@sandbox.root)
end end
# @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers
# folders as the keys and the the absolute paths of the header files
# as the values.
#
# @todo this is being overridden in the RestKit 0.9.4 spec, need to do # @todo this is being overridden in the RestKit 0.9.4 spec, need to do
# something with that, and this method also still exists in Specification. # something with that, and this method also still exists in Specification.
# #
# @todo This is not overridden anymore in specification refactor and the # @todo This is not overridden anymore in specification refactor and the
# code Pod::Specification#copy_header_mapping can be moved here. # code Pod::Specification#copy_header_mapping can be moved here.
def copy_header_mappings def header_mappings
search_path_headers = header_files - headers_excluded_from_search_paths mappings = {}
search_path_headers.inject({}) do |mappings, from| header_files_by_spec.each do |spec, paths|
from_without_prefix = from.relative_path_from(relative_root) paths = paths - headers_excluded_from_search_paths
to = top_specification.header_dir + top_specification.copy_header_mapping(from_without_prefix) paths.each do |from|
(mappings[to.dirname] ||= []) << from from_relative = from.relative_path_from(root)
mappings to = headers_sandbox + (spec.header_dir) + spec.copy_header_mapping(from_relative)
(mappings[to.dirname] ||= []) << from
end
end end
mappings
end end
# Finds the source files that every activate {Specification} requires. def headers_sandbox
# @headers_sandbox ||= Pathname.new(top_specification.name)
# @note The paths of the files are relative to the sandbox.
# @note If the same file is required by two specifications the one at the higher level in the inheritance chain wins.
#
# @return [Hash{Specification => Array<Pathname>}] The files grouped by {Specification}.
#
def sources_files_by_specification
files_by_spec = {}
processed_files = []
specifications.sort_by { |s| s.name.length }.each do |spec|
files = []
expanded_paths(spec.source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => true).each do | file |
files << file unless processed_files.include?(file)
end
files_by_spec[spec] = files
processed_files += files
end
files_by_spec
end end
# @todo merge with #221 # @return [<Pathname>] The relative path of the headers that should not be
# included in the linker search paths.
# #
def headers_excluded_from_search_paths def headers_excluded_from_search_paths
chained_expanded_paths(:exclude_header_search_paths, :glob => '*.h', :relative_to_sandbox => true) options = { :glob => '*.h' }
paths = paths_by_spec(:exclude_header_search_paths, options)
paths.values.compact.uniq
end end
# @!group Paths Patterns # @!group Paths Patterns
# Finds all the paths patterns of a each activated specifications and # The paths obtained by resolving the patterns of an attribute
# converts them to the actual paths present in the pod. # groupped by spec.
# #
# @return [Array<Pathname>] A list of the paths. # @param [Symbol] accessor The accessor to use to obtain the paths patterns.
# @param [Hash] options (see #expanded_paths)
# #
def chained_expanded_paths(accessor, options = {}) def paths_by_spec(accessor, options = {}, specs = nil)
specifications.map { |s| expanded_paths(s.send(accessor), options) }.compact.flatten.uniq specs ||= specifications
paths_by_spec = {}
processed_paths = []
specs = specs.sort_by { |s| s.name.length }
specs.each do |spec|
paths = expanded_paths(spec.send(accessor), options)
unless paths.empty?
paths_by_spec[spec] = paths - processed_paths
processed_paths += paths
end
end
paths_by_spec
end end
# The paths obtained by interpolating the patterns of a given attribute # Converts patterns of paths to the {Pathname} of the files present in the
# collected by spec. # pod.
#
# @todo implement case insensitive search
# #
# @param [String, FileList, Array<String, Pathname>] patterns # @param [String, FileList, Array<String, Pathname>] patterns
# The patterns to expand. # The patterns to expand.
...@@ -379,8 +426,6 @@ module Pod ...@@ -379,8 +426,6 @@ module Pod
# The options to used for expanding the paths patterns. # The options to used for expanding the paths patterns.
# @option options [String] :glob # @option options [String] :glob
# The pattern to use for globing directories. # The pattern to use for globing directories.
# @option options [Boolean] :relative_to_sandbox
# Whether the paths should be returned relative to the sandbox.
# #
# @raise [Informative] If the pod does not exists. # @raise [Informative] If the pod does not exists.
# #
...@@ -405,11 +450,7 @@ module Pod ...@@ -405,11 +450,7 @@ module Pod
end end
pattern.glob.map do |file| pattern.glob.map do |file|
if options[:relative_to_sandbox] file
file.relative_path_from(@sandbox.root)
else
file
end
end end
end.flatten end.flatten
end end
......
...@@ -42,6 +42,16 @@ module Pod ...@@ -42,6 +42,16 @@ module Pod
@header_search_paths.uniq.map { |path| "${PODS_ROOT}/#{path}" } @header_search_paths.uniq.map { |path| "${PODS_ROOT}/#{path}" }
end end
# Adds an header search path to the sandbox.
#
# @param path [Pathname] The path tho add.
#
# @return [void]
#
def add_header_search_path(path)
@header_search_paths << Pathname.new(HEADERS_DIR) + path
end
def prepare_for_install def prepare_for_install
headers_root.rmtree if headers_root.exist? headers_root.rmtree if headers_root.exist?
end end
......
...@@ -38,10 +38,18 @@ module Pod ...@@ -38,10 +38,18 @@ module Pod
end end
# multi-platform attributes # multi-platform attributes
%w[ source_files resources preserve_paths exclude_header_search_paths frameworks libraries dependencies compiler_flags].each do |attr| %w[ source_files
resources
preserve_paths
exclude_header_search_paths
frameworks
libraries
dependencies
compiler_flags ].each do |attr|
instance_variable_set( "@#{attr}", { :ios => [], :osx => [] } ) instance_variable_set( "@#{attr}", { :ios => [], :osx => [] } )
end end
@xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new } @xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new }
@header_dir = { :ios => nil, :osx => nil }
yield self if block_given? yield self if block_given?
end end
...@@ -122,6 +130,7 @@ module Pod ...@@ -122,6 +130,7 @@ module Pod
libraries= libraries=
compiler_flags= compiler_flags=
deployment_target= deployment_target=
header_dir=
dependency }.each do |method| dependency }.each do |method|
define_method(method) do |args| define_method(method) do |args|
@specification._on_platform(@platform) do @specification._on_platform(@platform) do
...@@ -183,16 +192,10 @@ module Pod ...@@ -183,16 +192,10 @@ module Pod
top_attr_accessor :license, lambda { |l| ( l.kind_of? String ) ? { :type => l } : l } top_attr_accessor :license, lambda { |l| ( l.kind_of? String ) ? { :type => l } : l }
top_attr_accessor :version, lambda { |v| Version.new(v) } top_attr_accessor :version, lambda { |v| Version.new(v) }
top_attr_accessor :authors, lambda { |a| parse_authors(a) } top_attr_accessor :authors, lambda { |a| parse_authors(a) }
top_attr_accessor :header_mappings_dir, lambda { |file| Pathname.new(file) } # If not provided the headers files are flattened
top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
top_attr_accessor :prefix_header_contents
top_attr_reader :description, lambda {|instance, ivar| ivar || instance.summary } top_attr_reader :description, lambda {|instance, ivar| ivar || instance.summary }
top_attr_writer :description top_attr_writer :description
top_attr_reader :header_dir, lambda {|instance, ivar| ivar || instance.pod_destroot_name }
top_attr_writer :header_dir, lambda {|dir| Pathname.new(dir) }
alias_method :author=, :authors= alias_method :author=, :authors=
def self.parse_authors(*names_and_email_addresses) def self.parse_authors(*names_and_email_addresses)
...@@ -206,6 +209,13 @@ module Pod ...@@ -206,6 +209,13 @@ module Pod
### Attributes **with** multiple platform support ### Attributes **with** multiple platform support
# @todo allow for subspecs
#
top_attr_accessor :header_mappings_dir, lambda { |file| Pathname.new(file) } # If not provided the headers files are flattened
top_attr_accessor :prefix_header_file, lambda { |file| Pathname.new(file) }
top_attr_accessor :prefix_header_contents
pltf_chained_attr_accessor :source_files, lambda {|value, current| pattern_list(value) } pltf_chained_attr_accessor :source_files, lambda {|value, current| pattern_list(value) }
pltf_chained_attr_accessor :resources, lambda {|value, current| pattern_list(value) } pltf_chained_attr_accessor :resources, lambda {|value, current| pattern_list(value) }
pltf_chained_attr_accessor :preserve_paths, lambda {|value, current| pattern_list(value) } # Paths that should not be cleaned pltf_chained_attr_accessor :preserve_paths, lambda {|value, current| pattern_list(value) } # Paths that should not be cleaned
...@@ -218,7 +228,28 @@ module Pod ...@@ -218,7 +228,28 @@ module Pod
alias_method :framework=, :frameworks= alias_method :framework=, :frameworks=
alias_method :library=, :libraries= alias_method :library=, :libraries=
platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } } # @!method header_dir=
#
# @abstract The directory where to name space the headers files of
# the specification.
#
# @param [String] The headers directory.
#
platform_attr_writer :header_dir, lambda { |dir, _| Pathname.new(dir) }
# @abstract (see #header_dir=)
#
# @return [Pathname] The headers directory.
#
# @note If no value is provided it returns an empty {Pathname}.
#
def header_dir
@header_dir[active_platform] || (@parent.header_dir if @parent) || Pathname.new('')
end
# @!method xcconfig=
#
platform_attr_writer :xcconfig, lambda {|value, current| current.tap { |c| c.merge!(value) } }
def xcconfig def xcconfig
raw_xconfig.dup. raw_xconfig.dup.
...@@ -341,12 +372,6 @@ module Pod ...@@ -341,12 +372,6 @@ module Pod
end end
end end
def pod_destroot_name
if root = pod_destroot
root.basename
end
end
def self.pattern_list(patterns) def self.pattern_list(patterns)
if patterns.is_a?(Array) && (!defined?(Rake) || !patterns.is_a?(Rake::FileList)) if patterns.is_a?(Array) && (!defined?(Rake) || !patterns.is_a?(Rake::FileList))
patterns patterns
......
...@@ -6,7 +6,8 @@ describe Pod::LocalPod do ...@@ -6,7 +6,8 @@ describe Pod::LocalPod do
describe "in general" do describe "in general" do
before do before do
@sandbox = temporary_sandbox @sandbox = temporary_sandbox
@pod = Pod::LocalPod.new(fixture_spec('banana-lib/BananaLib.podspec'), @sandbox, Pod::Platform.new(:ios)) @spec = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(@spec, @sandbox, Pod::Platform.new(:ios))
copy_fixture_to_pod('banana-lib', @pod) copy_fixture_to_pod('banana-lib', @pod)
end end
...@@ -31,12 +32,29 @@ describe Pod::LocalPod do ...@@ -31,12 +32,29 @@ describe Pod::LocalPod do
end end
it 'returns an expanded list of source files, relative to the sandbox root' do it 'returns an expanded list of source files, relative to the sandbox root' do
@pod.source_files.sort.should == [ @pod.relative_source_files.sort.should == [
Pathname.new("BananaLib/Classes/Banana.m"), Pathname.new("BananaLib/Classes/Banana.m"),
Pathname.new("BananaLib/Classes/Banana.h") Pathname.new("BananaLib/Classes/Banana.h")
].sort ].sort
end end
it 'returns the source files groupped by specification' do
files = @pod.source_files_by_spec[@pod.specifications.first].sort
files.should == [
@pod.root + "Classes/Banana.m",
@pod.root + "Classes/Banana.h"
].sort
end
it 'returns a list of header files' do
@pod.relative_header_files.should == [Pathname.new("BananaLib/Classes/Banana.h")]
end
it 'returns a list of header files by specification' do
files = @pod.header_files_by_spec[@pod.specifications.first].sort
files.should == [ @pod.root + "Classes/Banana.h" ]
end
it 'returns an expanded list the files to clean' do it 'returns an expanded list the files to clean' do
clean_paths = @pod.clean_paths.map { |p| p.to_s.gsub(/.*Pods\/BananaLib/,'') } clean_paths = @pod.clean_paths.map { |p| p.to_s.gsub(/.*Pods\/BananaLib/,'') }
clean_paths.should.include "/.git/config" clean_paths.should.include "/.git/config"
...@@ -46,11 +64,7 @@ describe Pod::LocalPod do ...@@ -46,11 +64,7 @@ describe Pod::LocalPod do
end end
it 'returns an expanded list of resources, relative to the sandbox root' do it 'returns an expanded list of resources, relative to the sandbox root' do
@pod.resources.should == [Pathname.new("BananaLib/Resources/logo-sidebar.png")] @pod.relative_resource_files.should == [Pathname.new("BananaLib/Resources/logo-sidebar.png")]
end
it 'returns a list of header files' do
@pod.header_files.should == [Pathname.new("BananaLib/Classes/Banana.h")]
end end
it "can link it's headers into the sandbox" do it "can link it's headers into the sandbox" do
...@@ -84,172 +98,201 @@ describe Pod::LocalPod do ...@@ -84,172 +98,201 @@ describe Pod::LocalPod do
end end
end end
describe "with installed source," do describe "with installed source and multiple subspecs" do
#before do
#config.project_pods_root = fixture('integration')
#podspec = fixture('spec-repos/master/SSZipArchive/0.1.0/SSZipArchive.podspec')
#@spec = Pod::Specification.from_file(podspec)
#@destroot = fixture('integration/SSZipArchive')
#end
xit "returns the list of files that the source_files pattern expand to" do
files = @destroot.glob('**/*.{h,c,m}')
files = files.map { |file| file.relative_path_from(config.project_pods_root) }
@spec.expanded_source_files[:ios].sort.should == files.sort
end
xit "returns the list of headers" do
files = @destroot.glob('**/*.h')
files = files.map { |file| file.relative_path_from(config.project_pods_root) }
@spec.header_files[:ios].sort.should == files.sort
end
xit "returns a hash of mappings from the pod's destroot to its header dirs, which by default is just the pod's header dir" do
@spec.copy_header_mappings[:ios].size.should == 1
@spec.copy_header_mappings[:ios][Pathname.new('SSZipArchive')].sort.should == %w{
SSZipArchive.h
minizip/crypt.h
minizip/ioapi.h
minizip/mztools.h
minizip/unzip.h
minizip/zip.h
}.map { |f| Pathname.new("SSZipArchive/#{f}") }.sort
end
xit "allows for customization of header mappings by overriding copy_header_mapping" do
def @spec.copy_header_mapping(from)
Pathname.new('ns') + from.basename
end
@spec.copy_header_mappings[:ios].size.should == 1
@spec.copy_header_mappings[:ios][Pathname.new('SSZipArchive/ns')].sort.should == %w{
SSZipArchive.h
minizip/crypt.h
minizip/ioapi.h
minizip/mztools.h
minizip/unzip.h
minizip/zip.h
}.map { |f| Pathname.new("SSZipArchive/#{f}") }.sort
end
xit "returns a hash of mappings with a custom header dir prefix" do
@spec.header_dir = 'AnotherRoot'
@spec.copy_header_mappings[:ios][Pathname.new('AnotherRoot')].sort.should == %w{
SSZipArchive.h
minizip/crypt.h
minizip/ioapi.h
minizip/mztools.h
minizip/unzip.h
minizip/zip.h
}.map { |f| Pathname.new("SSZipArchive/#{f}") }.sort
end
xit "returns the user header search paths" do
def @spec.copy_header_mapping(from)
Pathname.new('ns') + from.basename
end
@spec.header_search_paths.should == %w{
"$(PODS_ROOT)/Headers/SSZipArchive"
"$(PODS_ROOT)/Headers/SSZipArchive/ns"
}
end
xit "returns the user header search paths with a custom header dir prefix" do def assert_array_equals(expected, computed)
@spec.header_dir = 'AnotherRoot' delta1 = computed - expected
def @spec.copy_header_mapping(from) delta1.should == []
Pathname.new('ns') + from.basename delta2 = expected - computed
end delta2.should == []
@spec.header_search_paths.should == %w{
"$(PODS_ROOT)/Headers/AnotherRoot"
"$(PODS_ROOT)/Headers/AnotherRoot/ns"
}
end end
xit "returns the list of files that the resources pattern expand to" do
@spec.expanded_resources.should == {}
@spec.resource = 'LICEN*'
@spec.expanded_resources[:ios].map(&:to_s).should == %w{ SSZipArchive/LICENSE }
@spec.expanded_resources[:osx].map(&:to_s).should == %w{ SSZipArchive/LICENSE }
@spec.resources = 'LICEN*', 'Readme.*'
@spec.expanded_resources[:ios].map(&:to_s).should == %w{ SSZipArchive/LICENSE SSZipArchive/Readme.markdown }
@spec.expanded_resources[:osx].map(&:to_s).should == %w{ SSZipArchive/LICENSE SSZipArchive/Readme.markdown }
end
end
describe "regarding multiple subspecs" do
before do before do
# specification with only some subspecs activated @sandbox = temporary_sandbox
# to check that only the needed files are being activated subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
# A fixture is needed. @pod = Pod::LocalPod.new(subspecs[0], @sandbox, Pod::Platform.new(:osx))
# @pod.add_specification(subspecs[1])
# specification = Pod::Spec.new do |s| copy_fixture_to_pod('chameleon', @pod)
# ... end
# s.xcconfig = ...
# s.compiler_flags = ... it "identifies the top level specification" do
# s.subspec 's1' do |s1| @pod.top_specification.name.should == 'Chameleon'
# s1.xcconfig = ... end
# s1.compiler_flags = ...
# s1.ns.source_files = 's1.{h,m}' it "returns the subspecs" do
# end @pod.specifications.map(&:name).should == %w[ Chameleon/UIKit Chameleon/StoreKit ]
# end
# s.subspec 's2' do |s2|
# s2.ns.source_files = 's2.{h,m}' it "resolve the source files" do
# end computed = @pod.relative_source_files.map(&:to_s)
# expected = %w[
# Add only s1 to the localPod Chameleon/UIKit/Classes/UIKit.h
# s1 = specification.subspec_by_name(s1) Chameleon/UIKit/Classes/UIView.h
# @pod = Pod::LocalPod.new(s1, @sandbox, Pod::Platform.new(:ios)) Chameleon/UIKit/Classes/UIWindow.h
# @pod.add_specification(specification) Chameleon/UIKit/Classes/UIView.m
end Chameleon/UIKit/Classes/UIWindow.m
Chameleon/StoreKit/Classes/SKPayment.h
xit "returns the subspecs" do Chameleon/StoreKit/Classes/StoreKit.h
@pod.subspecs.map{ |s| name }.should == %w[ s1 ] Chameleon/StoreKit/Classes/SKPayment.m ]
end
assert_array_equals(expected, computed)
xit "resolve the source files" do end
@pod.source_files.should == %w[ s1.h s1.m ]
end it "resolve the resources" do
@pod.relative_resource_files.map(&:to_s).sort.should == [
xit "resolve the resources" do "Chameleon/UIKit/Resources/<UITabBar> background.png",
end "Chameleon/UIKit/Resources/<UITabBar> background@2x.png" ]
end
xit "resolve the clean paths" do
@pod.clean_paths.should == %w[ s2.h s2.m ] it "resolve the clean paths" do
end # fake_git serves to check that source control files are deleted
expected = %w[
xit "resolves the used files" do /.fake_git
@pod.used_files.should == %w[ s1.h s1.m README.md ] /.fake_git/branches
end /.fake_git/HEAD
/.fake_git/index
xit "resolved the header files" do /AddressBookUI
@pod.header_files.should == %w[ s1.h ] /AddressBookUI/AddressBookUI_Prefix.pch
end /AddressBookUI/Classes
/AddressBookUI/Classes/ABUnknownPersonViewController.h
xit "resolves the header files of every subspec" do /AddressBookUI/Classes/ABUnknownPersonViewController.m
@pod.all_specs_public_header_files.should == %w[ s1.h s2.h ] /AddressBookUI/Classes/AddressBookUI.h
end /AssetsLibrary
/AssetsLibrary/AssetsLibrary_Prefix.pch
xit "merges the xcconfigs" do /AssetsLibrary/Classes
end /AssetsLibrary/Classes/ALAsset.h
/AssetsLibrary/Classes/ALAsset.m
xit "adds each file to a target with the compiler flags of its specification" do /AssetsLibrary/Classes/ALAssetRepresentation.h
# @pod.add_to_target(target) /AssetsLibrary/Classes/ALAssetRepresentation.m
end /AssetsLibrary/Classes/ALAssetsFilter.h
/AssetsLibrary/Classes/ALAssetsFilter.m
xit "can provide the source files of all the subspecs" do /AssetsLibrary/Classes/ALAssetsGroup.h
sources = @pod.all_specs_source_files.map { |p| p.relative_path_from(@sandbox.root).to_s } /AssetsLibrary/Classes/ALAssetsGroup.m
sources.should == %w[ s1.h s1.m s2.h s2.m ] /AssetsLibrary/Classes/ALAssetsLibrary.h
/AssetsLibrary/Classes/ALAssetsLibrary.m
/AssetsLibrary/Classes/AssetsLibrary.h
/AVFoundation
/AVFoundation/AVFoundation_Prefix.pch
/AVFoundation/Classes
/AVFoundation/Classes/AVAudioPlayer.h
/AVFoundation/Classes/AVAudioPlayer.m
/AVFoundation/Classes/AVAudioSession.h
/AVFoundation/Classes/AVAudioSession.m
/AVFoundation/Classes/AVFoundation.h
/MediaPlayer
/MediaPlayer/Classes
/MediaPlayer/Classes/MediaPlayer.h
/MediaPlayer/Classes/MPMediaPlayback.h
/MediaPlayer/Classes/MPMoviePlayerController.h
/MediaPlayer/Classes/MPMoviePlayerController.m
/MediaPlayer/Classes/MPMusicPlayerController.h
/MediaPlayer/Classes/MPMusicPlayerController.m
/MediaPlayer/Classes/UIInternalMovieView.h
/MediaPlayer/Classes/UIInternalMovieView.m
/MediaPlayer/MediaPlayer_Prefix.pch
/MessageUI
/MessageUI/Classes
/MessageUI/Classes/MessageUI.h
/MessageUI/Classes/MFMailComposeViewController.h
/MessageUI/Classes/MFMailComposeViewController.m
/MessageUI/MessageUI_Prefix.pch
/StoreKit/StoreKit_Prefix.pch
/UIKit/UIKit_Prefix.pch
]
computed = @pod.clean_paths.each{ |p| p.gsub!(@pod.root.to_s, '') }
assert_array_equals(expected, computed)
end
it "resolves the used files" do
expected = %w[
/UIKit/Classes/UIKit.h
/UIKit/Classes/UIView.h
/UIKit/Classes/UIWindow.h
/UIKit/Classes/UIView.m
/UIKit/Classes/UIWindow.m
/StoreKit/Classes/SKPayment.h
/StoreKit/Classes/StoreKit.h
/StoreKit/Classes/SKPayment.m
/Chameleon.podspec
/README.md
/LICENSE
] + [
"/UIKit/Resources/<UITabBar> background.png",
"/UIKit/Resources/<UITabBar> background@2x.png"
]
computed = @pod.used_files.map{ |p| p.gsub!(@pod.root.to_s, '').to_s }
assert_array_equals(expected, computed)
end
it "resolved the header files" do
expected = %w[
Chameleon/UIKit/Classes/UIKit.h
Chameleon/UIKit/Classes/UIView.h
Chameleon/UIKit/Classes/UIWindow.h
Chameleon/StoreKit/Classes/SKPayment.h
Chameleon/StoreKit/Classes/StoreKit.h ]
computed = @pod.relative_header_files.map(&:to_s)
assert_array_equals(expected, computed)
end
it "resolves the header files of **every** subspec" do
computed = @pod.all_specs_public_header_files.map { |p| p.relative_path_from(@pod.root).to_s }
expected = %w[
UIKit/Classes/UIKit.h
UIKit/Classes/UIView.h
UIKit/Classes/UIWindow.h
StoreKit/Classes/SKPayment.h
StoreKit/Classes/StoreKit.h
MessageUI/Classes/MessageUI.h
MessageUI/Classes/MFMailComposeViewController.h
MediaPlayer/Classes/MediaPlayer.h
MediaPlayer/Classes/MPMediaPlayback.h
MediaPlayer/Classes/MPMoviePlayerController.h
MediaPlayer/Classes/MPMusicPlayerController.h
MediaPlayer/Classes/UIInternalMovieView.h
AVFoundation/Classes/AVAudioPlayer.h
AVFoundation/Classes/AVAudioSession.h
AVFoundation/Classes/AVFoundation.h
AssetsLibrary/Classes/ALAsset.h
AssetsLibrary/Classes/ALAssetRepresentation.h
AssetsLibrary/Classes/ALAssetsFilter.h
AssetsLibrary/Classes/ALAssetsGroup.h
AssetsLibrary/Classes/ALAssetsLibrary.h
AssetsLibrary/Classes/AssetsLibrary.h
]
assert_array_equals(expected, computed)
end
it "merges the xcconfigs without duplicates" do
@pod.xcconfig.should == {
"OTHER_LDFLAGS"=>"-framework AppKit -framework Foundation -framework IOKit -framework QTKit -framework QuartzCore -framework SystemConfiguration -framework WebKit" }
end
it "returns a hash of mappings with a custom header dir prefix" do
mappings = @pod.send(:header_mappings)
mappings = mappings.map do |folder, headers|
"#{folder} > #{headers.sort.map{ |p| p.relative_path_from(@pod.root).to_s }.join(' ')}"
end
mappings.sort.should == [
"Chameleon/StoreKit > StoreKit/Classes/SKPayment.h StoreKit/Classes/StoreKit.h",
"Chameleon/UIKit > UIKit/Classes/UIKit.h UIKit/Classes/UIView.h UIKit/Classes/UIWindow.h" ]
end end
xit 'can clean the unused files' do it "respects the headers excluded from the search paths" do
# copy fixture to another folder @pod.stubs(:headers_excluded_from_search_paths).returns([@pod.root + 'UIKit/Classes/UIKit.h'])
@pod.clean mappings = @pod.send(:header_mappings)
@pod.clean_paths.tap do |paths| mappings = mappings.map do |folder, headers|
paths.each do |path| "#{folder} > #{headers.sort.map{ |p| p.relative_path_from(@pod.root).to_s }.join(' ')}"
path.should.not.exist
end
end end
mappings.sort.should == [
"Chameleon/StoreKit > StoreKit/Classes/SKPayment.h StoreKit/Classes/StoreKit.h",
"Chameleon/UIKit > UIKit/Classes/UIView.h UIKit/Classes/UIWindow.h" ]
end end
it "includes the sandbox of the pod's headers while linking" do
@sandbox.expects(:add_header_search_path).with(Pathname.new('Chameleon'))
@pod.link_headers
end
end end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment