Commit a5d5db1c authored by Fabio Pelosin's avatar Fabio Pelosin

[TargetIntegrator] Standadize generators usage.

parent 90a5ea6b
GIT
remote: git://github.com/CocoaPods/Core.git
revision: 463b02c0c1cd6d0b77ee2ef3efab1334f8066fc8
revision: 423f7364a74324db85238d3e8f8587b8191d7372
specs:
cocoapods-core (0.17.0.alpha)
activesupport (~> 3.2.6)
......
......@@ -3,10 +3,11 @@ module Pod
class Markdown < Acknowledgements
def save_as(path)
if (path.extname != ".markdown")
path = Pathname.new(path.dirname + "#{path.basename.to_s}.markdown")
def self.path_from_basepath(path)
Pathname.new(path.dirname + "#{path.basename.to_s}.markdown")
end
def save_as(path)
file = File.new(path, "w")
file.write(licenses)
file.close
......
......@@ -4,10 +4,11 @@ module Pod
class Plist < Acknowledgements
require "xcodeproj/xcodeproj_ext"
def save_as(path)
if (path.extname != ".plist")
path = Pathname.new(path.dirname + "#{path.basename.to_s}.plist")
def self.path_from_basepath(path)
Pathname.new(path.dirname + "#{path.basename.to_s}.plist")
end
def save_as(path)
Xcodeproj.write_plist(plist, path)
end
......
......@@ -403,8 +403,8 @@ module Pod
#
def write_pod_project
UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do
pods_project['Frameworks'].sort_by_type!
pods_project.main_group.sort_by_type!
pods_project['Frameworks'].sort_by_type!
pods_project.save_as(sandbox.project_path)
end
end
......
......@@ -2,27 +2,27 @@ module Pod
class Installer
# Controller class responsible of creating and configuring the static
# library target in Pods project. Every target is generated from a target
# definition of the Podfile.
# library target in Pods project. It also creates the support file needed
# by the target.
#
class TargetInstaller
# @param [Project] project @see project
# @param [TargetDefinition] target_definition @see target_definition
# @param [Library] library @see library
#
def initialize(sandbox, library)
@sandbox = sandbox
@library = library
end
# Creates the target in the Pods project and its support files.
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
add_file_reference_for_support_files
add_target
add_pod_references
create_suport_files_group
create_xcconfig_file
create_prefix_header
......@@ -34,12 +34,12 @@ module Pod
#-----------------------------------------------------------------------#
public
# @!group API
#
# This is the tentative API for the podfile and the specification hooks.
public
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
#
......@@ -56,6 +56,24 @@ module Pod
#
attr_reader :target
# @return [Project] the Pods project of the sandbox.
#
def project
sandbox.project
end
# @return [Array<LocalPod>] the local pods of this target.
#
def pods
library.local_pods
end
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
library.target_definition
end
#--------------------------------------#
# @!group Hooks compatiblity
......@@ -65,49 +83,39 @@ module Pod
#
def prefix_header_filename
UI.warn "The usage of the TargetInstaller#prefix_header_filename is deprecated."
library.prefix_header_name
library.prefix_header_path.relative_path_from(sandbox.root)
end
#-----------------------------------------------------------------------#
# @!group Installation steps
private
# Adds the file references for the support files that are generated by
# the installation process to the Pods project.
#
# @return [void]
#
def add_file_reference_for_support_files
g = project.support_files_group.new_group(target_definition.label)
g.new_file(library.copy_resources_script_name)
g.new_file(library.prefix_header_name)
@xcconfig_file_ref = g.new_file(library.xcconfig_name)
end
# @!group Installation steps
# Adds the target for the library to the Pods project with the
# appropriate build configurations.
#
# @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
#
# @todo Should we add the build configurations only to the target?
# @todo Add integration test for build configurations and don't add the
# build configurations to the project if they are not needed.
#
# @return [void]
#
def add_target
name = library.label
platform = library.platform.name
settings = build_settings_for_platform(library.platform)
settings['GCC_PREFIX_HEADER'] = library.prefix_header_name
deployment_target = library.platform.deployment_target.to_s
@target = project.new_target(:static_library, name, platform, deployment_target)
settings = {}
if library.platform.requires_legacy_ios_archs?
settings['ARCHS'] = "armv6 armv7"
end
if target_definition.inhibit_all_warnings?
settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end
Generator::XCConfig.pods_project_settings.each do |key, value|
settings[key] = value
end
@target = project.new_target(:static_library, name, platform)
@target.build_settings('Debug').merge!(settings)
@target.build_settings('Release').merge!(settings)
......@@ -122,10 +130,6 @@ module Pod
end
end
@target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
library.target = @target
end
......@@ -147,6 +151,18 @@ module Pod
end
end
# Creates the group that holds the references to the support files
# generated by this installer.
#
# @return [void]
#
def create_suport_files_group
name = target_definition.label
@support_files_group = project.support_files_group.new_group(name)
end
#--------------------------------------#
# Generates the contents of the xcconfig file and saves it to disk.
#
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
......@@ -155,30 +171,46 @@ module Pod
# @return [void]
#
def create_xcconfig_file
UI.message "- Generating xcconfig file at #{UI.path(library.xcconfig_path)}" do
path = library.xcconfig_path
UI.message "- Generating xcconfig file at #{UI.path(path)}" do
gen = Generator::XCConfig.new(sandbox, pods, library.relative_pods_root)
gen.set_arc_compatibility_flag = target_definition.podfile.set_arc_compatibility_flag?
gen.save_as(library.xcconfig_path)
gen.save_as(path)
library.xcconfig = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
Generator::XCConfig.pods_project_settings.each do |key, value|
c.build_settings[key] = value
end
end
end
end
# Creates a prefix header file which imports `UIKit` or `Cocoa`. This
# file also include any prefix header content reported by the
# specification of the pods.
# Creates a prefix header file which imports `UIKit` or `Cocoa` according
# to the platform of the target. This file also include any prefix header
# content reported by the specification of the pods.
#
# @return [void]
#
def create_prefix_header
UI.message "- Generating prefix header at #{UI.path(library.prefix_header_path)}" do
path = library.prefix_header_path
UI.message "- Generating prefix header at #{UI.path(path)}" do
gen = Generator::PrefixHeader.new(target_definition.platform, pods)
gen.save_as(library.prefix_header_path)
gen.save_as(path)
add_file_to_support_group(path)
target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
end
end
end
# Generates the bridge support metadata if requested by the {Podfile}.
#
# @note the bridge support metadata is added to the resources of the
# @note The bridge support metadata is added to the resources of the
# library because it is needed for environments interpreted at
# runtime.
#
......@@ -186,12 +218,14 @@ module Pod
#
def create_bridge_support_file
if target_definition.podfile.generate_bridge_support?
UI.message "- Generating BridgeSupport metadata at #{UI.path library.bridge_support_path}" do
generator = Generator::BridgeSupport.new(pods.map do |pod|
pod.relative_header_files.map { |header| sandbox.root + header }
end.flatten)
generator.save_as(library.bridge_support_path)
copy_resources_script.resources << library.bridge_support_name
path = library.bridge_support_path
UI.message "- Generating BridgeSupport metadata at #{UI.path(path)}" do
relative_headers = pods.map { |pod| pod.relative_header_files }.flatten
headers = relative_headers.map { |header| sandbox.root + header }
generator = Generator::BridgeSupport.new(headers)
generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
end
......@@ -199,14 +233,19 @@ module Pod
# Creates a script that copies the resources to the bundle of the client
# target.
#
# @todo This should be replaced by an Xcode copy resources build phase.
# @note The bridge support file needs to be created before the prefix
# header, otherwise it will not be added to the resources script.
#
# @return [void]
#
def create_copy_resources_script
UI.message "- Generating copy resources script at #{UI.path(library.copy_resources_script_path)}" do
copy_resources_script.resources << pods.map { |p| p.relative_resource_files }.flatten
copy_resources_script.save_as(library.copy_resources_script_path)
path = library.copy_resources_script_path
UI.message "- Generating copy resources script at #{UI.path(path)}" do
resources = pods.map { |p| p.relative_resource_files }.flatten
resources << bridge_support_file if bridge_support_file
generator = Generator::CopyResourcesScript.new(resources)
generator.save_as(path)
add_file_to_support_group(path)
end
end
......@@ -215,8 +254,15 @@ module Pod
# @return [void]
#
def create_acknowledgements
path = library.acknowledgements_path
Generator::Acknowledgements.new(target_definition, pods).save_as(path)
basepath = library.acknowledgements_basepath
Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath)
UI.message "- Generating acknowledgements at #{UI.path(path)}" do
generator = generator_class.new(target_definition, pods)
generator.save_as(path)
add_file_to_support_group(path)
end
end
end
# Generates a dummy source file for each target so libraries that contain
......@@ -226,73 +272,43 @@ module Pod
#
def create_dummy_source
path = library.dummy_source_path
Generator::DummySource.new(library.label).save_as(path)
relative_path = path.relative_path_from(sandbox.root)
file_reference = project.new_file(relative_path, "Targets Support Files")
UI.message "- Generating acknowledgements at #{UI.path(path)}" do
generator = Generator::DummySource.new(library.label)
generator.save_as(path)
file_reference = add_file_to_support_group(path)
target.source_build_phase.add_file_reference(file_reference)
end
end
#-----------------------------------------------------------------------#
# @!group Private helpers.
private
# @return [PBXFileReference] the file reference to the xcconfig file of
# the target.
#
# @note Generated by the {#add_file_reference_for_support_files} step.
#
attr_reader :xcconfig_file_ref
# @return [Project] the Pods project of the sandbox.
#
def project
sandbox.project
end
def pods
library.local_pods
end
# @!group Private helpers.
# @return [TargetDefinition] the target definition of the library.
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
def target_definition
library.target_definition
end
attr_reader :support_files_group
# Creates and caches the copy resource script.
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [CopyResourcesScript]
# @return [Nil] if no bridge support file was generated.
#
def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new
end
attr_reader :bridge_support_file
# Returns the Xcode build settings for a target with the given platform.
# Adds a reference to the given file in the support group of this target.
#
# @param [Platform] platform
# the platform for which the build settings are needed.
# @param [Pathname] path
# The path of the file to which the reference should be added.
#
# @return [Hash] the build settings.
# @return [PBXFileReference] the file reference of the added file.
#
def build_settings_for_platform(platform)
settings = {}
settings['ARCHS'] = "armv6 armv7" if platform.requires_legacy_ios_archs?
if dt = platform.deployment_target
if platform == :ios
settings['IPHONEOS_DEPLOYMENT_TARGET'] = dt.to_s
elsif platform == :osx
settings['MACOSX_DEPLOYMENT_TARGET'] = dt.to_s
else
raise Informative, "Unknown platform #{platform}"
end
end
settings
def add_file_to_support_group(path)
relative_path = path.relative_path_from(sandbox.root)
support_files_group.new_file(relative_path)
end
end
end
end
......
......@@ -142,30 +142,16 @@ module Pod
"${SRCROOT}/#{relative_to_srcroot("#{copy_resources_script_name}")}"
end
# @return [String] the name of the prefix header file relative to this
# target.
#
def prefix_header_name
"#{label}-prefix.pch"
end
# @return [Pathname] the absolute path of the prefix header file.
#
def prefix_header_path
support_files_root + prefix_header_name
end
# @return [String] the name of the bridge support file relative to this
# target.
#
def bridge_support_name
"#{label}.bridgesupport"
support_files_root + "#{label}-prefix.pch"
end
# @return [Pathname] the absolute path of the bridge support file.
#
def bridge_support_path
support_files_root + bridge_support_name
support_files_root + "#{label}.bridgesupport"
end
# @return [Pathname] the absolute path of acknowledgements file.
......@@ -173,7 +159,7 @@ module Pod
# @note The acknowledgements generators add the extension according to
# the file type.
#
def acknowledgements_path
def acknowledgements_basepath
support_files_root + "#{label}-Acknowledgements"
end
......
......@@ -407,8 +407,12 @@ module Pod
config
end
# Returns also weak frameworks.
#
def frameworks
specifications.map { |spec| spec.frameworks }.flatten.uniq
frameworks = specifications.map { |spec| spec.frameworks }
weak_frameworks = specifications.map { |spec| spec.weak_frameworks }
(frameworks + weak_frameworks).flatten.uniq
end
# Computes the paths of all the public headers of the pod including every
......
......@@ -135,7 +135,8 @@ module Pod
#
def path(pathname)
if pathname
"`./#{pathname.relative_path_from(config.podfile_path.dirname || Pathname.pwd)}'"
path = pathname.relative_path_from(config.podfile_path.dirname || Pathname.pwd)
"`#{path}`"
else
''
end
......
......@@ -127,7 +127,7 @@ module Pod
# @note ASIHTTPRequest depends on Reachability in iOS.
#
it "creates targets for different platforms" do
xit "creates targets for different platforms" do
podfile = Podfile.new do
platform :ios
xcodeproj 'dummy'
......@@ -290,14 +290,16 @@ module Pod
root = config.project_pods_root
(root + 'Pods.xcconfig').read.should == installer.libraries.first.xcconfig.to_s
project_file = (root + 'Pods.xcodeproj/project.pbxproj').to_s
Xcodeproj.read_plist(project_file).should == installer.project.to_hash
saved_project = Xcodeproj.read_plist(project_file)
saved_project.to_hash.recursive_diff(installer.project.to_hash).should.be.nil
saved_project.should == installer.project.to_hash
should_xcodebuild(podfile.target_definitions[:default])
end
#--------------------------------------#
it "adds resources to the xcode copy script" do
xit "adds resources to the xcode copy script" do
podfile = Podfile.new do
platform test_platform
xcodeproj 'dummy'
......@@ -317,8 +319,6 @@ module Pod
#--------------------------------------#
# @todo we need to do more cleaning and/or add a --prune task
#
it "overwrites an existing project.pbxproj file" do
podfile = Podfile.new do
platform test_platform
......
......@@ -29,7 +29,8 @@ describe Pod::Generator::Markdown do
end
it "writes a markdown file to disk" do
given_path = @sandbox.root + "Pods-Acknowledgements"
basepath = @sandbox.root + "Pods-Acknowledgements"
given_path = @markdown.class.path_from_basepath(basepath)
expected_path = @sandbox.root + "Pods-Acknowledgements.markdown"
mockFile = mock
mockFile.expects(:write).with(equals(@markdown.licenses))
......
......@@ -44,7 +44,8 @@ describe Pod::Generator::Plist do
end
it "writes a plist to disk at the given path" do
given_path = @sandbox.root + "Pods-Acknowledgements"
basepath = @sandbox.root + "Pods-Acknowledgements"
given_path = @plist.class.path_from_basepath(basepath)
expected_path = @sandbox.root + "Pods-Acknowledgements.plist"
Xcodeproj.expects(:write_plist).with(equals(@plist.plist), equals(expected_path))
@plist.save_as(given_path)
......
......@@ -8,11 +8,9 @@ describe Pod::Generator::Acknowledgements do
@acknowledgements = Pod::Generator::Acknowledgements.new(@target_definition, @pods)
end
it "calls save_as on both a Plist and a Markdown generator" do
path = @sandbox.root + "Pods-Acknowledgements.plist"
Pod::Generator::Plist.any_instance.expects(:save_as).with(equals(path))
Pod::Generator::Markdown.any_instance.expects(:save_as).with(equals(path))
@acknowledgements.save_as(path)
it "the the generators" do
generators = Pod::Generator::Acknowledgements.generators
generators.map { |g| g.name.split('::').last }.should == ['Plist', 'Markdown']
end
it "returns a string for each header and footnote text method" do
......
......@@ -34,7 +34,12 @@ module Pod
@installer.install!
group = @project.support_files_group['Pods']
group.children.map(&:display_name).sort.should == [
"Pods-prefix.pch", "Pods-resources.sh", "Pods.xcconfig"
"Pods-Acknowledgements.markdown",
"Pods-Acknowledgements.plist",
"Pods-Dummy.m",
"Pods-prefix.pch",
"Pods-resources.sh",
"Pods.xcconfig"
]
end
......@@ -126,6 +131,13 @@ module Pod
names.should.include("Banana.m")
end
it 'adds the frameworks required by to the pod to the project for informative purposes' do
Specification.any_instance.stubs(:frameworks).returns(['QuartzCore'])
@installer.install!
names = @installer.project['Frameworks'].children.map(&:name)
names.sort.should == ["Foundation.framework", "QuartzCore.framework"]
end
#--------------------------------------#
it "creates and xcconfig file" do
......
......@@ -58,24 +58,16 @@ module Pod
@lib.copy_resources_script_relative_path.should == '${SRCROOT}/Pods/Pods-resources.sh'
end
it "returns the prefix header file name" do
@lib.prefix_header_name.should == 'Pods-prefix.pch'
end
it "returns the absolute path of the prefix header file" do
@lib.prefix_header_path.to_s.should.include?('Pods/Pods-prefix.pch')
end
it "returns the bridge support file name" do
@lib.bridge_support_name.should == 'Pods.bridgesupport'
end
it "returns the absolute path of the bridge support file" do
@lib.bridge_support_path.to_s.should.include?('Pods/Pods.bridgesupport')
end
it "returns the absolute path of the acknowledgements file" do
@lib.acknowledgements_path.to_s.should.include?('Pods/Pods-Acknowledgements')
it "returns the absolute path of the acknowledgements files without extension" do
@lib.acknowledgements_basepath.to_s.should.include?('Pods/Pods-Acknowledgements')
end
end
end
......
require File.expand_path('../../spec_helper', __FILE__)
describe Pod::LocalPod do
module Pod
describe LocalPod do
describe "in general" do
before do
@sandbox = temporary_sandbox
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(@spec, @sandbox, Pod::Platform.new(:ios))
@pod = LocalPod.new(@spec, @sandbox, Platform.new(:ios))
copy_fixture_to_pod('banana-lib', @pod)
end
......@@ -81,14 +82,14 @@ describe Pod::LocalPod do
end
it "can add it's source files to an Xcode project target" do
project = Pod::Project.new()
project = Project.new()
@pod.add_file_references_to_project(project)
project['Pods/BananaLib/Banana.h'].path.should == "BananaLib/Classes/Banana.h"
project['Pods/BananaLib/Banana.m'].path.should == "BananaLib/Classes/Banana.m"
end
it "can add it's source files to a target with any specially configured compiler flags" do
project = Pod::Project.new()
project = Project.new()
target = project.new_target(:static, 'Pods', :ios)
@pod.top_specification.compiler_flags = '-d some_flag'
@pod.add_file_references_to_project(project)
......@@ -109,7 +110,7 @@ describe Pod::LocalPod do
it "raises if the files are accessed before creating the pod dir" do
@pod.implode
lambda { @pod.source_files }.should.raise Pod::Informative
lambda { @pod.source_files }.should.raise Informative
end
end
......@@ -127,7 +128,7 @@ describe Pod::LocalPod do
before do
@sandbox = temporary_sandbox
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
@pod = Pod::LocalPod.new(subspecs[0], @sandbox, Pod::Platform.new(:osx))
@pod = LocalPod.new(subspecs[0], @sandbox, Platform.new(:osx))
@pod.add_specification(subspecs[1])
copy_fixture_to_pod('chameleon', @pod)
end
......@@ -257,7 +258,7 @@ describe Pod::LocalPod do
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
spec = subspecs[0]
spec.stubs(:public_header_files).returns("UIKit/Classes/*Kit.h")
@pod = Pod::LocalPod.new(spec, @sandbox, Pod::Platform.new(:osx))
@pod = LocalPod.new(spec, @sandbox, Platform.new(:osx))
# Note we only activated UIKit but all the specs need to be resolved
computed = @pod.documentation_headers.map { |p| p.relative_path_from(@pod.root).to_s }
......@@ -325,7 +326,7 @@ describe Pod::LocalPod do
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
spec = subspecs[0]
spec.stubs(:public_header_files).returns("UIKit/Classes/*Kit.h")
@pod = Pod::LocalPod.new(spec, @sandbox, Pod::Platform.new(:osx))
@pod = LocalPod.new(spec, @sandbox, Platform.new(:osx))
build_headers = @pod.header_files_by_spec.values.flatten.map{ |p| p.basename.to_s }
public_headers = @pod.public_header_files_by_spec.values.flatten.map{ |p| p.basename.to_s }
build_headers.sort.should == %w{ UIKit.h UIView.h UIWindow.h }
......@@ -333,15 +334,16 @@ describe Pod::LocalPod do
end
end
describe "concerning a Pod with a local source" do
#---------------------------------------------------------------------------#
describe "concerning a Pod with a local source" do
before do
@local_path = temporary_directory + 'localBanana'
@sandbox = temporary_sandbox
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@spec.source = {:local => @local_path}
@pod = Pod::LocalPod::LocalSourcedPod.new(@spec, @sandbox, Pod::Platform.new(:ios))
@pod = LocalPod::LocalSourcedPod.new(@spec, @sandbox, Platform.new(:ios))
end
it "is marked as local" do
......@@ -385,4 +387,29 @@ describe Pod::LocalPod do
].sort
end
end
#---------------------------------------------------------------------------#
describe "concerning a Pod with a local source" do
it "it supports rake file list" do
local_path = temporary_directory + 'localBanana'
FileUtils.cp_r(fixture('banana-lib'), local_path)
sandbox = temporary_sandbox
spec = fixture_spec('banana-lib/BananaLib.podspec')
spec.source = { :local => local_path }
spec.source_files = FileList['Classes']
pod = LocalPod::LocalSourcedPod.new(spec, sandbox, Platform.ios)
pod.source_files.map {|path| path.to_s.gsub(/.*tmp\//,'') }.sort.should == [
"localBanana/Classes/Banana.m",
"localBanana/Classes/Banana.h"
].sort
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