Commit db65b82c authored by Luke Redpath's avatar Luke Redpath

Refactor functionality out of the target installer and into the LocalPod and Sandbox classes,

especially around linking of header files and tracking header search paths.
parent 1ca552a6
......@@ -59,13 +59,14 @@ module Pod
def install_dependencies!
build_specifications.map do |spec|
Pod.new(sandbox, spec).tap do |pod|
if spec.pod_destroot.exist? || spec.local?
message = "Using #{spec}"
message += " [LOCAL]" if spec.local?
puts message unless config.silent?
if pod.exists? || spec.local?
puts "Using #{pod}" unless config.silent?
else
puts "Installing #{spec}" unless config.silent?
spec = spec.part_of_specification if spec.part_of_other_pod?
# TODO: get this working again
# spec = spec.part_of_specification if spec.part_of_other_pod?
downloader = Downloader.for_pod(pod)
downloader.download
......@@ -89,9 +90,9 @@ module Pod
puts "Generating support files" unless config.silent?
target_installers.each do |target_installer|
target_installer.install!
target_installer.create_files_in(root)
target_installer.install!(pods, sandbox)
end
generate_lock_file!
puts "* Running post install hooks" if config.verbose?
......
......@@ -26,9 +26,9 @@ module Pod
"#{@definition.lib_name}.xcconfig"
end
def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new(build_specifications.map do |spec|
spec.expanded_resources
def copy_resources_script_for(pods)
@copy_resources_script ||= Generator::CopyResourcesScript.new(pods.map do |pod|
pod.expanded_resources
end.flatten)
end
......@@ -62,33 +62,21 @@ module Pod
end
# TODO move xcconfig related code into the xcconfig method, like copy_resources_script and generate_bridge_support.
def install!
def install!(pods, sandbox)
# First add the target to the project
@target = @project.targets.new_static_library(@definition.lib_name)
header_search_paths = []
build_specifications.each do |spec|
xcconfig.merge!(spec.xcconfig)
# Only add implementation files to the compile phase
spec.implementation_files.each do |file|
pods.each do |pod|
xcconfig.merge!(pod.specification.xcconfig)
pod.implementation_files.each do |file|
@target.add_source_file(file, nil, spec.compiler_flags)
end
# Symlink header files to Pods/Headers
spec.copy_header_mappings.each do |header_dir, files|
target_dir = "#{config.headers_symlink_root}/#{header_dir}"
FileUtils.mkdir_p(target_dir)
target_dir_real_path = Pathname.new(target_dir).realpath
files.each do |file|
source = Pathname.new("#{config.project_pods_root}/#{file}").realpath.relative_path_from(target_dir_real_path)
Dir.chdir(target_dir) do
FileUtils.ln_sf(source, File.basename(file))
end
end
end
# Collect all header search paths
header_search_paths.concat(spec.header_search_paths)
pod.link_headers
end
xcconfig.merge!('HEADER_SEARCH_PATHS' => header_search_paths.sort.uniq.join(" "))
xcconfig.merge!('HEADER_SEARCH_PATHS' => sandbox.header_search_paths.join(" "))
# Add all the target related support files to the group, even the copy
# resources script although the project doesn't actually use them.
......@@ -98,6 +86,7 @@ module Pod
support_files_group.files.new('path' => copy_resources_filename)
prefix_file = support_files_group.files.new('path' => prefix_header_filename)
xcconfig_file = support_files_group.files.new("path" => xcconfig_filename)
# Assign the xcconfig as the base config of each config.
@target.buildConfigurations.each do |config|
config.baseConfiguration = xcconfig_file
......@@ -105,20 +94,23 @@ module Pod
config.buildSettings['GCC_PREFIX_HEADER'] = prefix_header_filename
config.buildSettings['PODS_ROOT'] = '$(SRCROOT)'
end
create_files(pods, sandbox)
end
def create_files_in(root)
def create_files(pods, sandbox)
if @podfile.generate_bridge_support?
puts "* Generating BridgeSupport metadata file at `#{root + bridge_support_filename}'" if config.verbose?
bridge_support_generator.save_as(root + bridge_support_filename)
copy_resources_script.resources << bridge_support_filename
bridge_support_metadata_path = sandbox.root + bridge_support_filename
puts "* Generating BridgeSupport metadata file at `#{bridge_support_metadata_path}'" if config.verbose?
bridge_support_generator.save_as(bridge_support_metadata_path)
copy_resources_script_for(pods).resources << bridge_support_filename
end
puts "* Generating xcconfig file at `#{root + xcconfig_filename}'" if config.verbose?
xcconfig.save_as(root + xcconfig_filename)
puts "* Generating prefix header at `#{root + prefix_header_filename}'" if config.verbose?
save_prefix_header_as(root + prefix_header_filename)
puts "* Generating copy resources script at `#{root + copy_resources_filename}'" if config.verbose?
copy_resources_script.save_as(root + copy_resources_filename)
puts "* Generating xcconfig file at `#{sandbox.root + xcconfig_filename}'" if config.verbose?
xcconfig.save_as(sandbox.root + xcconfig_filename)
puts "* Generating prefix header at `#{sandbox.root + prefix_header_filename}'" if config.verbose?
save_prefix_header_as(sandbox.root + prefix_header_filename)
puts "* Generating copy resources script at `#{sandbox.root + copy_resources_filename}'" if config.verbose?
copy_resources_script.save_as(sandbox.root + copy_resources_filename)
end
end
end
......
......@@ -10,8 +10,20 @@ module Pod
@sandbox.root + specification.name
end
def to_s
if specification.local?
"#{specification} [LOCAL]"
else
specification.to_s
end
end
def create
root.mkpath unless root.exist?
root.mkpath unless exists?
end
def exists?
root.exist?
end
def chdir(&block)
......@@ -20,7 +32,7 @@ module Pod
end
def implode
root.rmtree if root.exist?
root.rmtree if exists?
end
def clean
......@@ -39,8 +51,35 @@ module Pod
expanded_paths(specification.resources, :relative_to_sandbox => true)
end
def implementation_files
source_files.select { |f| f.extname != '.h' }
end
def header_files
source_files.select { |f| f.extname == '.h' }
end
def link_headers
copy_header_mappings.each do |namespaced_path, files|
@sandbox.add_header_files(namespaced_path, files)
end
end
private
def relative_root
root.relative_path_from(@sandbox.root)
end
def copy_header_mappings
header_files.inject({}) do |mappings, from|
from_without_prefix = from.relative_path_from(relative_root)
to = specification.header_dir + specification.copy_header_mapping(from_without_prefix)
(mappings[to.dirname] ||= []) << from
mappings
end
end
def expanded_paths(patterns, options={})
patterns.map do |pattern|
pattern = root + pattern
......
......@@ -4,11 +4,34 @@ module Pod
def initialize(path)
@root = path
@header_search_paths = []
FileUtils.mkdir_p(@root)
end
def implode
@root.rmtree
root.rmtree
end
def headers_path
root + "Headers"
end
def add_header_file(namespace_path, relative_header_path)
namespaced_header_path = headers_path + namespace_path
namespaced_header_path.mkpath unless File.exist?(namespaced_header_path)
source = (root + relative_header_path).relative_path_from(namespaced_header_path)
Dir.chdir(namespaced_header_path) { FileUtils.ln_sf(source, relative_header_path.basename)}
@header_search_paths << namespaced_header_path.relative_path_from(root)
namespaced_header_path + relative_header_path.basename
end
def add_header_files(namespace_path, relative_header_paths)
relative_header_paths.map { |path| add_header_file(namespace_path, path) }
end
def header_search_paths
@header_search_paths.uniq.map { |path| "$(PODS_ROOT)/#{path}" }
end
end
end
......@@ -45,6 +45,14 @@ describe Pod::LocalPod do
@pod.resources.should == [Pathname.new("BananaLib/Resources/logo-sidebar.png")]
end
it 'returns a list of implementation files' do
@pod.implementation_files.should == [Pathname.new("BananaLib/Classes/Banana.m")]
end
it 'returns a list of header files' do
@pod.header_files.should == [Pathname.new("BananaLib/Classes/Banana.h")]
end
it 'can clean up after itself' do
@pod.clean_paths.tap do |paths|
@pod.clean
......@@ -55,4 +63,11 @@ describe Pod::LocalPod do
end
end
it "can link it's headers into the sandbox" do
@pod.link_headers
expected_header_path = @sandbox.headers_path + "BananaLib/Banana.h"
expected_header_path.should.be.symlink
File.read(expected_header_path).should == (@sandbox.root + @pod.header_files[0]).read
end
end
......@@ -23,4 +23,49 @@ describe Pod::Sandbox do
FileUtils.mkdir(TMP_POD_ROOT) # put it back again
end
it "returns it's headers path" do
@sandbox.headers_path.should == Pathname.new(File.join(TMP_POD_ROOT, "Headers"))
end
it "can add namespaced headers to it's header path using symlinks and return the relative path" do
FileUtils.mkdir_p(@sandbox.root + "ExampleLib/Headers")
namespace_path = Pathname.new("ExampleLib")
relative_header_path = Pathname.new("ExampleLib/Headers/MyHeader.h")
File.open(@sandbox.root + relative_header_path, "w") { |file| file.write('hello') }
symlink_path = @sandbox.add_header_file(namespace_path, relative_header_path)
symlink_path.should.be.symlink
File.read(symlink_path).should == 'hello'
end
it 'can add multiple headers at once and return the relative symlink paths' do
FileUtils.mkdir_p(@sandbox.root + "ExampleLib/Headers")
namespace_path = Pathname.new("ExampleLib")
relative_header_paths = [
Pathname.new("ExampleLib/Headers/MyHeader.h"),
Pathname.new("ExampleLib/Headers/MyOtherHeader.h")
]
relative_header_paths.each do |path|
File.open(@sandbox.root + path, "w") { |file| file.write('hello') }
end
symlink_paths = @sandbox.add_header_files(namespace_path, relative_header_paths)
symlink_paths.each do |path|
path.should.be.symlink
File.read(path).should == "hello"
end
end
it 'keeps a list of unique header search paths when headers are added' do
FileUtils.mkdir_p(@sandbox.root + "ExampleLib/Headers")
namespace_path = Pathname.new("ExampleLib")
relative_header_paths = [
Pathname.new("ExampleLib/Headers/MyHeader.h"),
Pathname.new("ExampleLib/Headers/MyOtherHeader.h")
]
relative_header_paths.each do |path|
File.open(@sandbox.root + path, "w") { |file| file.write('hello') }
end
@sandbox.add_header_files(namespace_path, relative_header_paths)
@sandbox.header_search_paths.should == ["$(PODS_ROOT)/Headers/ExampleLib"]
end
end
......@@ -134,7 +134,8 @@ describe "A Pod::Specification that's part of another pod's source" do
#end
end
# TODO: This is really what a LocalPod now represents
# Which probably means most of this functionality should move there
describe "A Pod::Specification, with installed source," do
before do
config.project_pods_root = fixture('integration')
......
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