Commit a5d5db1c authored by Fabio Pelosin's avatar Fabio Pelosin

[TargetIntegrator] Standadize generators usage.

parent 90a5ea6b
GIT GIT
remote: git://github.com/CocoaPods/Core.git remote: git://github.com/CocoaPods/Core.git
revision: 463b02c0c1cd6d0b77ee2ef3efab1334f8066fc8 revision: 423f7364a74324db85238d3e8f8587b8191d7372
specs: specs:
cocoapods-core (0.17.0.alpha) cocoapods-core (0.17.0.alpha)
activesupport (~> 3.2.6) activesupport (~> 3.2.6)
......
...@@ -3,10 +3,11 @@ module Pod ...@@ -3,10 +3,11 @@ module Pod
class Markdown < Acknowledgements class Markdown < Acknowledgements
def self.path_from_basepath(path)
Pathname.new(path.dirname + "#{path.basename.to_s}.markdown")
end
def save_as(path) def save_as(path)
if (path.extname != ".markdown")
path = Pathname.new(path.dirname + "#{path.basename.to_s}.markdown")
end
file = File.new(path, "w") file = File.new(path, "w")
file.write(licenses) file.write(licenses)
file.close file.close
......
...@@ -4,10 +4,11 @@ module Pod ...@@ -4,10 +4,11 @@ module Pod
class Plist < Acknowledgements class Plist < Acknowledgements
require "xcodeproj/xcodeproj_ext" require "xcodeproj/xcodeproj_ext"
def self.path_from_basepath(path)
Pathname.new(path.dirname + "#{path.basename.to_s}.plist")
end
def save_as(path) def save_as(path)
if (path.extname != ".plist")
path = Pathname.new(path.dirname + "#{path.basename.to_s}.plist")
end
Xcodeproj.write_plist(plist, path) Xcodeproj.write_plist(plist, path)
end end
......
...@@ -403,8 +403,8 @@ module Pod ...@@ -403,8 +403,8 @@ module Pod
# #
def write_pod_project def write_pod_project
UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do 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.main_group.sort_by_type!
pods_project['Frameworks'].sort_by_type!
pods_project.save_as(sandbox.project_path) pods_project.save_as(sandbox.project_path)
end end
end end
......
...@@ -2,27 +2,27 @@ module Pod ...@@ -2,27 +2,27 @@ module Pod
class Installer class Installer
# Controller class responsible of creating and configuring the static # Controller class responsible of creating and configuring the static
# library target in Pods project. Every target is generated from a target # library target in Pods project. It also creates the support file needed
# definition of the Podfile. # by the target.
# #
class TargetInstaller class TargetInstaller
# @param [Project] project @see project # @param [Project] project @see project
# @param [TargetDefinition] target_definition @see target_definition # @param [Library] library @see library
# #
def initialize(sandbox, library) def initialize(sandbox, library)
@sandbox = sandbox @sandbox = sandbox
@library = library @library = library
end 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] # @return [void]
# #
def install! def install!
add_file_reference_for_support_files
add_target add_target
add_pod_references add_pod_references
create_suport_files_group
create_xcconfig_file create_xcconfig_file
create_prefix_header create_prefix_header
...@@ -34,12 +34,12 @@ module Pod ...@@ -34,12 +34,12 @@ module Pod
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
public
# @!group API # @!group API
# #
# This is the tentative API for the podfile and the specification hooks. # This is the tentative API for the podfile and the specification hooks.
public
# @return [Sandbox] sandbox the sandbox where the support files should # @return [Sandbox] sandbox the sandbox where the support files should
# be generated. # be generated.
# #
...@@ -56,6 +56,24 @@ module Pod ...@@ -56,6 +56,24 @@ module Pod
# #
attr_reader :target 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 # @!group Hooks compatiblity
...@@ -65,49 +83,39 @@ module Pod ...@@ -65,49 +83,39 @@ module Pod
# #
def prefix_header_filename def prefix_header_filename
UI.warn "The usage of the TargetInstaller#prefix_header_filename is deprecated." 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 end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
# @!group Installation steps
private private
# Adds the file references for the support files that are generated by # @!group Installation steps
# 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
# Adds the target for the library to the Pods project with the # Adds the target for the library to the Pods project with the
# appropriate build configurations. # appropriate build configurations.
# #
# @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig. # @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] # @return [void]
# #
def add_target def add_target
name = library.label name = library.label
platform = library.platform.name platform = library.platform.name
settings = build_settings_for_platform(library.platform) deployment_target = library.platform.deployment_target.to_s
settings['GCC_PREFIX_HEADER'] = library.prefix_header_name @target = project.new_target(:static_library, name, platform, deployment_target)
if target_definition.inhibit_all_warnings?
settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES' settings = {}
if library.platform.requires_legacy_ios_archs?
settings['ARCHS'] = "armv6 armv7"
end end
Generator::XCConfig.pods_project_settings.each do |key, value| if target_definition.inhibit_all_warnings?
settings[key] = value settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end end
@target = project.new_target(:static_library, name, platform)
@target.build_settings('Debug').merge!(settings) @target.build_settings('Debug').merge!(settings)
@target.build_settings('Release').merge!(settings) @target.build_settings('Release').merge!(settings)
...@@ -122,10 +130,6 @@ module Pod ...@@ -122,10 +130,6 @@ module Pod
end end
end end
@target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
library.target = @target library.target = @target
end end
...@@ -147,6 +151,18 @@ module Pod ...@@ -147,6 +151,18 @@ module Pod
end end
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. # Generates the contents of the xcconfig file and saves it to disk.
# #
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support # @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
...@@ -155,30 +171,46 @@ module Pod ...@@ -155,30 +171,46 @@ module Pod
# @return [void] # @return [void]
# #
def create_xcconfig_file 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 = Generator::XCConfig.new(sandbox, pods, library.relative_pods_root)
gen.set_arc_compatibility_flag = target_definition.podfile.set_arc_compatibility_flag? 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 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
end end
# Creates a prefix header file which imports `UIKit` or `Cocoa`. This # Creates a prefix header file which imports `UIKit` or `Cocoa` according
# file also include any prefix header content reported by the # to the platform of the target. This file also include any prefix header
# specification of the pods. # content reported by the specification of the pods.
# #
# @return [void] # @return [void]
# #
def create_prefix_header 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 = 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
end end
# Generates the bridge support metadata if requested by the {Podfile}. # 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 # library because it is needed for environments interpreted at
# runtime. # runtime.
# #
...@@ -186,12 +218,14 @@ module Pod ...@@ -186,12 +218,14 @@ module Pod
# #
def create_bridge_support_file def create_bridge_support_file
if target_definition.podfile.generate_bridge_support? if target_definition.podfile.generate_bridge_support?
UI.message "- Generating BridgeSupport metadata at #{UI.path library.bridge_support_path}" do path = library.bridge_support_path
generator = Generator::BridgeSupport.new(pods.map do |pod| UI.message "- Generating BridgeSupport metadata at #{UI.path(path)}" do
pod.relative_header_files.map { |header| sandbox.root + header } relative_headers = pods.map { |pod| pod.relative_header_files }.flatten
end.flatten) headers = relative_headers.map { |header| sandbox.root + header }
generator.save_as(library.bridge_support_path) generator = Generator::BridgeSupport.new(headers)
copy_resources_script.resources << library.bridge_support_name generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end end
end end
end end
...@@ -199,14 +233,19 @@ module Pod ...@@ -199,14 +233,19 @@ module Pod
# Creates a script that copies the resources to the bundle of the client # Creates a script that copies the resources to the bundle of the client
# target. # 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] # @return [void]
# #
def create_copy_resources_script def create_copy_resources_script
UI.message "- Generating copy resources script at #{UI.path(library.copy_resources_script_path)}" do path = library.copy_resources_script_path
copy_resources_script.resources << pods.map { |p| p.relative_resource_files }.flatten UI.message "- Generating copy resources script at #{UI.path(path)}" do
copy_resources_script.save_as(library.copy_resources_script_path) 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
end end
...@@ -215,8 +254,15 @@ module Pod ...@@ -215,8 +254,15 @@ module Pod
# @return [void] # @return [void]
# #
def create_acknowledgements def create_acknowledgements
path = library.acknowledgements_path basepath = library.acknowledgements_basepath
Generator::Acknowledgements.new(target_definition, pods).save_as(path) 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 end
# Generates a dummy source file for each target so libraries that contain # Generates a dummy source file for each target so libraries that contain
...@@ -226,73 +272,43 @@ module Pod ...@@ -226,73 +272,43 @@ module Pod
# #
def create_dummy_source def create_dummy_source
path = library.dummy_source_path path = library.dummy_source_path
Generator::DummySource.new(library.label).save_as(path) UI.message "- Generating acknowledgements at #{UI.path(path)}" do
relative_path = path.relative_path_from(sandbox.root) generator = Generator::DummySource.new(library.label)
file_reference = project.new_file(relative_path, "Targets Support Files") generator.save_as(path)
target.source_build_phase.add_file_reference(file_reference) file_reference = add_file_to_support_group(path)
target.source_build_phase.add_file_reference(file_reference)
end
end end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
# @!group Private helpers.
private private
# @return [PBXFileReference] the file reference to the xcconfig file of # @!group Private helpers.
# 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
# @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 attr_reader :support_files_group
library.target_definition
end
# 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 attr_reader :bridge_support_file
@copy_resources_script ||= Generator::CopyResourcesScript.new
end
# 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 # @param [Pathname] path
# the platform for which the build settings are needed. # 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) def add_file_to_support_group(path)
settings = {} relative_path = path.relative_path_from(sandbox.root)
settings['ARCHS'] = "armv6 armv7" if platform.requires_legacy_ios_archs? support_files_group.new_file(relative_path)
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
end end
end end
end end
end end
......
...@@ -142,30 +142,16 @@ module Pod ...@@ -142,30 +142,16 @@ module Pod
"${SRCROOT}/#{relative_to_srcroot("#{copy_resources_script_name}")}" "${SRCROOT}/#{relative_to_srcroot("#{copy_resources_script_name}")}"
end 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. # @return [Pathname] the absolute path of the prefix header file.
# #
def prefix_header_path def prefix_header_path
support_files_root + prefix_header_name support_files_root + "#{label}-prefix.pch"
end
# @return [String] the name of the bridge support file relative to this
# target.
#
def bridge_support_name
"#{label}.bridgesupport"
end end
# @return [Pathname] the absolute path of the bridge support file. # @return [Pathname] the absolute path of the bridge support file.
# #
def bridge_support_path def bridge_support_path
support_files_root + bridge_support_name support_files_root + "#{label}.bridgesupport"
end end
# @return [Pathname] the absolute path of acknowledgements file. # @return [Pathname] the absolute path of acknowledgements file.
...@@ -173,7 +159,7 @@ module Pod ...@@ -173,7 +159,7 @@ module Pod
# @note The acknowledgements generators add the extension according to # @note The acknowledgements generators add the extension according to
# the file type. # the file type.
# #
def acknowledgements_path def acknowledgements_basepath
support_files_root + "#{label}-Acknowledgements" support_files_root + "#{label}-Acknowledgements"
end end
......
...@@ -407,8 +407,12 @@ module Pod ...@@ -407,8 +407,12 @@ module Pod
config config
end end
# Returns also weak frameworks.
#
def 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 end
# Computes the paths of all the public headers of the pod including every # Computes the paths of all the public headers of the pod including every
......
...@@ -135,7 +135,8 @@ module Pod ...@@ -135,7 +135,8 @@ module Pod
# #
def path(pathname) def path(pathname)
if 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 else
'' ''
end end
......
...@@ -127,7 +127,7 @@ module Pod ...@@ -127,7 +127,7 @@ module Pod
# @note ASIHTTPRequest depends on Reachability in iOS. # @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 podfile = Podfile.new do
platform :ios platform :ios
xcodeproj 'dummy' xcodeproj 'dummy'
...@@ -290,14 +290,16 @@ module Pod ...@@ -290,14 +290,16 @@ module Pod
root = config.project_pods_root root = config.project_pods_root
(root + 'Pods.xcconfig').read.should == installer.libraries.first.xcconfig.to_s (root + 'Pods.xcconfig').read.should == installer.libraries.first.xcconfig.to_s
project_file = (root + 'Pods.xcodeproj/project.pbxproj').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]) should_xcodebuild(podfile.target_definitions[:default])
end end
#--------------------------------------# #--------------------------------------#
it "adds resources to the xcode copy script" do xit "adds resources to the xcode copy script" do
podfile = Podfile.new do podfile = Podfile.new do
platform test_platform platform test_platform
xcodeproj 'dummy' xcodeproj 'dummy'
...@@ -317,8 +319,6 @@ module Pod ...@@ -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 it "overwrites an existing project.pbxproj file" do
podfile = Podfile.new do podfile = Podfile.new do
platform test_platform platform test_platform
......
...@@ -29,7 +29,8 @@ describe Pod::Generator::Markdown do ...@@ -29,7 +29,8 @@ describe Pod::Generator::Markdown do
end end
it "writes a markdown file to disk" do 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" expected_path = @sandbox.root + "Pods-Acknowledgements.markdown"
mockFile = mock mockFile = mock
mockFile.expects(:write).with(equals(@markdown.licenses)) mockFile.expects(:write).with(equals(@markdown.licenses))
......
...@@ -44,7 +44,8 @@ describe Pod::Generator::Plist do ...@@ -44,7 +44,8 @@ describe Pod::Generator::Plist do
end end
it "writes a plist to disk at the given path" do 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" expected_path = @sandbox.root + "Pods-Acknowledgements.plist"
Xcodeproj.expects(:write_plist).with(equals(@plist.plist), equals(expected_path)) Xcodeproj.expects(:write_plist).with(equals(@plist.plist), equals(expected_path))
@plist.save_as(given_path) @plist.save_as(given_path)
......
...@@ -8,11 +8,9 @@ describe Pod::Generator::Acknowledgements do ...@@ -8,11 +8,9 @@ describe Pod::Generator::Acknowledgements do
@acknowledgements = Pod::Generator::Acknowledgements.new(@target_definition, @pods) @acknowledgements = Pod::Generator::Acknowledgements.new(@target_definition, @pods)
end end
it "calls save_as on both a Plist and a Markdown generator" do it "the the generators" do
path = @sandbox.root + "Pods-Acknowledgements.plist" generators = Pod::Generator::Acknowledgements.generators
Pod::Generator::Plist.any_instance.expects(:save_as).with(equals(path)) generators.map { |g| g.name.split('::').last }.should == ['Plist', 'Markdown']
Pod::Generator::Markdown.any_instance.expects(:save_as).with(equals(path))
@acknowledgements.save_as(path)
end end
it "returns a string for each header and footnote text method" do it "returns a string for each header and footnote text method" do
......
...@@ -34,7 +34,12 @@ module Pod ...@@ -34,7 +34,12 @@ module Pod
@installer.install! @installer.install!
group = @project.support_files_group['Pods'] group = @project.support_files_group['Pods']
group.children.map(&:display_name).sort.should == [ 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 end
...@@ -126,6 +131,13 @@ module Pod ...@@ -126,6 +131,13 @@ module Pod
names.should.include("Banana.m") names.should.include("Banana.m")
end 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 it "creates and xcconfig file" do
......
...@@ -58,24 +58,16 @@ module Pod ...@@ -58,24 +58,16 @@ module Pod
@lib.copy_resources_script_relative_path.should == '${SRCROOT}/Pods/Pods-resources.sh' @lib.copy_resources_script_relative_path.should == '${SRCROOT}/Pods/Pods-resources.sh'
end 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 it "returns the absolute path of the prefix header file" do
@lib.prefix_header_path.to_s.should.include?('Pods/Pods-prefix.pch') @lib.prefix_header_path.to_s.should.include?('Pods/Pods-prefix.pch')
end 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 it "returns the absolute path of the bridge support file" do
@lib.bridge_support_path.to_s.should.include?('Pods/Pods.bridgesupport') @lib.bridge_support_path.to_s.should.include?('Pods/Pods.bridgesupport')
end end
it "returns the absolute path of the acknowledgements file" do it "returns the absolute path of the acknowledgements files without extension" do
@lib.acknowledgements_path.to_s.should.include?('Pods/Pods-Acknowledgements') @lib.acknowledgements_basepath.to_s.should.include?('Pods/Pods-Acknowledgements')
end end
end end
end end
......
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
describe Pod::LocalPod do module Pod
describe "in general" do describe LocalPod do
before do describe "in general" do
@sandbox = temporary_sandbox before do
@spec = fixture_spec('banana-lib/BananaLib.podspec') @sandbox = temporary_sandbox
@pod = Pod::LocalPod.new(@spec, @sandbox, Pod::Platform.new(:ios)) @spec = fixture_spec('banana-lib/BananaLib.podspec')
copy_fixture_to_pod('banana-lib', @pod) @pod = LocalPod.new(@spec, @sandbox, Platform.new(:ios))
end copy_fixture_to_pod('banana-lib', @pod)
end
it "returns the Pod root directory path" do it "returns the Pod root directory path" do
@pod.root.should == @sandbox.root + 'BananaLib' @pod.root.should == @sandbox.root + 'BananaLib'
end end
it "creates it's own root directory if it doesn't exist" do it "creates it's own root directory if it doesn't exist" do
@pod.create @pod.create
File.directory?(@pod.root).should.be.true File.directory?(@pod.root).should.be.true
end end
it "can execute a block within the context of it's root" do it "can execute a block within the context of it's root" do
@pod.chdir { FileUtils.touch("foo") } @pod.chdir { FileUtils.touch("foo") }
Pathname(@pod.root + "foo").should.exist Pathname(@pod.root + "foo").should.exist
end end
it "can delete itself" do it "can delete itself" do
@pod.create @pod.create
@pod.implode @pod.implode
@pod.root.should.not.exist @pod.root.should.not.exist
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.relative_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 grouped by specification" do it "returns the source files grouped by specification" do
files = @pod.source_files_by_spec[@pod.specifications.first].sort files = @pod.source_files_by_spec[@pod.specifications.first].sort
files.should == [ files.should == [
@pod.root + "Classes/Banana.m", @pod.root + "Classes/Banana.m",
@pod.root + "Classes/Banana.h" @pod.root + "Classes/Banana.h"
].sort ].sort
end end
it "returns a list of header files" do it "returns a list of header files" do
@pod.relative_header_files.should == [Pathname.new("BananaLib/Classes/Banana.h")] @pod.relative_header_files.should == [Pathname.new("BananaLib/Classes/Banana.h")]
end end
it "returns a list of header files by specification" do it "returns a list of header files by specification" do
files = @pod.header_files_by_spec[@pod.specifications.first].sort files = @pod.header_files_by_spec[@pod.specifications.first].sort
files.should == [ @pod.root + "Classes/Banana.h" ] files.should == [ @pod.root + "Classes/Banana.h" ]
end 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"
# * There are some hidden files on Travis # * There are some hidden files on Travis
# * The submodule of the repo (libPusher) can be ignore, to reduce noise of this test # * The submodule of the repo (libPusher) can be ignore, to reduce noise of this test
clean_files_without_hidden = clean_paths.reject { |p| p.to_s.include?('/.') || p.to_s.include?('libPusher') } clean_files_without_hidden = clean_paths.reject { |p| p.to_s.include?('/.') || p.to_s.include?('libPusher') }
clean_files_without_hidden.should == %W[ /sub-dir /sub-dir/sub-dir-2 /sub-dir/sub-dir-2/somefile.txt ] clean_files_without_hidden.should == %W[ /sub-dir /sub-dir/sub-dir-2 /sub-dir/sub-dir-2/somefile.txt ]
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.relative_resource_files.should == [Pathname.new("BananaLib/Resources/logo-sidebar.png")] @pod.relative_resource_files.should == [Pathname.new("BananaLib/Resources/logo-sidebar.png")]
end end
it "can link it's headers into the sandbox" do it "can link it's headers into the sandbox" do
@pod.link_headers @pod.link_headers
expected_header_path = @sandbox.build_headers.root + "BananaLib/Banana.h" expected_header_path = @sandbox.build_headers.root + "BananaLib/Banana.h"
expected_header_path.should.be.symlink expected_header_path.should.be.symlink
File.read(expected_header_path).should == (@sandbox.root + @pod.header_files[0]).read File.read(expected_header_path).should == (@sandbox.root + @pod.header_files[0]).read
end end
it "can link it's public headers into the sandbox" do it "can link it's public headers into the sandbox" do
@pod.link_headers @pod.link_headers
expected_header_path = @sandbox.public_headers.root + "BananaLib/Banana.h" expected_header_path = @sandbox.public_headers.root + "BananaLib/Banana.h"
expected_header_path.should.be.symlink expected_header_path.should.be.symlink
File.read(expected_header_path).should == (@sandbox.root + @pod.header_files[0]).read File.read(expected_header_path).should == (@sandbox.root + @pod.header_files[0]).read
end end
it "can add it's source files to an Xcode project target" do 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) @pod.add_file_references_to_project(project)
project['Pods/BananaLib/Banana.h'].path.should == "BananaLib/Classes/Banana.h" project['Pods/BananaLib/Banana.h'].path.should == "BananaLib/Classes/Banana.h"
project['Pods/BananaLib/Banana.m'].path.should == "BananaLib/Classes/Banana.m" project['Pods/BananaLib/Banana.m'].path.should == "BananaLib/Classes/Banana.m"
end end
it "can add it's source files to a target with any specially configured compiler flags" do 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) target = project.new_target(:static, 'Pods', :ios)
@pod.top_specification.compiler_flags = '-d some_flag' @pod.top_specification.compiler_flags = '-d some_flag'
@pod.add_file_references_to_project(project) @pod.add_file_references_to_project(project)
@pod.add_build_files_to_target(target) @pod.add_build_files_to_target(target)
h_build_file = target.headers_build_phase.files.first h_build_file = target.headers_build_phase.files.first
h_build_file.file_ref.path.should == "BananaLib/Classes/Banana.h" h_build_file.file_ref.path.should == "BananaLib/Classes/Banana.h"
h_build_file.settings.should == {"ATTRIBUTES"=>["Public"]} h_build_file.settings.should == {"ATTRIBUTES"=>["Public"]}
m_build_file = target.source_build_phase.files.first m_build_file = target.source_build_phase.files.first
m_build_file.file_ref.path.should == "BananaLib/Classes/Banana.m" m_build_file.file_ref.path.should == "BananaLib/Classes/Banana.m"
m_build_file.settings.should == {"COMPILER_FLAGS"=>"-d some_flag"} m_build_file.settings.should == {"COMPILER_FLAGS"=>"-d some_flag"}
end end
it "returns the platform" do it "returns the platform" do
@pod.platform.should == :ios @pod.platform.should == :ios
end end
it "raises if the files are accessed before creating the pod dir" do it "raises if the files are accessed before creating the pod dir" do
@pod.implode @pod.implode
lambda { @pod.source_files }.should.raise Pod::Informative lambda { @pod.source_files }.should.raise Informative
end
end end
end
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
describe "with installed source and multiple subspecs" do describe "with installed source and multiple subspecs" do
def assert_array_equals(expected, computed) def assert_array_equals(expected, computed)
delta1 = computed - expected delta1 = computed - expected
delta1.should == [] delta1.should == []
delta2 = expected - computed delta2 = expected - computed
delta2.should == [] delta2.should == []
end end
before do before do
@sandbox = temporary_sandbox @sandbox = temporary_sandbox
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs 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]) @pod.add_specification(subspecs[1])
copy_fixture_to_pod('chameleon', @pod) copy_fixture_to_pod('chameleon', @pod)
end end
it "identifies the top level specification" do it "identifies the top level specification" do
@pod.top_specification.name.should == 'Chameleon' @pod.top_specification.name.should == 'Chameleon'
end end
it "returns the subspecs" do it "returns the subspecs" do
@pod.specifications.map(&:name).should == %w[ Chameleon/UIKit Chameleon/StoreKit ] @pod.specifications.map(&:name).should == %w[ Chameleon/UIKit Chameleon/StoreKit ]
end end
it "resolve the source files" do it "resolve the source files" do
computed = @pod.relative_source_files.map(&:to_s) computed = @pod.relative_source_files.map(&:to_s)
expected = %w[ expected = %w[
Chameleon/UIKit/Classes/UIKit.h Chameleon/UIKit/Classes/UIKit.h
Chameleon/UIKit/Classes/UIView.h Chameleon/UIKit/Classes/UIView.h
Chameleon/UIKit/Classes/UIWindow.h Chameleon/UIKit/Classes/UIWindow.h
...@@ -152,18 +153,18 @@ describe Pod::LocalPod do ...@@ -152,18 +153,18 @@ describe Pod::LocalPod do
Chameleon/StoreKit/Classes/StoreKit.h Chameleon/StoreKit/Classes/StoreKit.h
Chameleon/StoreKit/Classes/SKPayment.m ] Chameleon/StoreKit/Classes/SKPayment.m ]
assert_array_equals(expected, computed) assert_array_equals(expected, computed)
end end
it "resolve the resources" do it "resolve the resources" do
@pod.relative_resource_files.map(&:to_s).sort.should == [ @pod.relative_resource_files.map(&:to_s).sort.should == [
"Chameleon/UIKit/Resources/<UITabBar> background.png", "Chameleon/UIKit/Resources/<UITabBar> background.png",
"Chameleon/UIKit/Resources/<UITabBar> background@2x.png" ] "Chameleon/UIKit/Resources/<UITabBar> background@2x.png" ]
end end
it "resolve the clean paths" do it "resolve the clean paths" do
# fake_git serves to check that source control files are deleted # fake_git serves to check that source control files are deleted
expected = %w[ expected = %w[
/.fake_git /.fake_git
/.fake_git/branches /.fake_git/branches
/.fake_git/HEAD /.fake_git/HEAD
...@@ -215,14 +216,14 @@ describe Pod::LocalPod do ...@@ -215,14 +216,14 @@ describe Pod::LocalPod do
/MessageUI/MessageUI_Prefix.pch /MessageUI/MessageUI_Prefix.pch
/StoreKit/StoreKit_Prefix.pch /StoreKit/StoreKit_Prefix.pch
/UIKit/UIKit_Prefix.pch /UIKit/UIKit_Prefix.pch
] ]
root = @pod.root.to_s root = @pod.root.to_s
computed = @pod.clean_paths.each{ |p| p.gsub!(root, '') } computed = @pod.clean_paths.each{ |p| p.gsub!(root, '') }
assert_array_equals(expected, computed) assert_array_equals(expected, computed)
end end
it "resolves the used files" do it "resolves the used files" do
expected = %w[ expected = %w[
/UIKit/Classes/UIKit.h /UIKit/Classes/UIKit.h
/UIKit/Classes/UIView.h /UIKit/Classes/UIView.h
/UIKit/Classes/UIWindow.h /UIKit/Classes/UIWindow.h
...@@ -234,37 +235,37 @@ describe Pod::LocalPod do ...@@ -234,37 +235,37 @@ describe Pod::LocalPod do
/Chameleon.podspec /Chameleon.podspec
/README.md /README.md
/LICENSE /LICENSE
] + [ ] + [
"/UIKit/Resources/<UITabBar> background.png", "/UIKit/Resources/<UITabBar> background.png",
"/UIKit/Resources/<UITabBar> background@2x.png" "/UIKit/Resources/<UITabBar> background@2x.png"
] ]
computed = @pod.used_files.map{ |p| p.gsub!(@pod.root.to_s, '').to_s } computed = @pod.used_files.map{ |p| p.gsub!(@pod.root.to_s, '').to_s }
assert_array_equals(expected, computed) assert_array_equals(expected, computed)
end end
it "resolved the header files" do it "resolved the header files" do
expected = %w[ expected = %w[
Chameleon/UIKit/Classes/UIKit.h Chameleon/UIKit/Classes/UIKit.h
Chameleon/UIKit/Classes/UIView.h Chameleon/UIKit/Classes/UIView.h
Chameleon/UIKit/Classes/UIWindow.h Chameleon/UIKit/Classes/UIWindow.h
Chameleon/StoreKit/Classes/SKPayment.h Chameleon/StoreKit/Classes/SKPayment.h
Chameleon/StoreKit/Classes/StoreKit.h ] Chameleon/StoreKit/Classes/StoreKit.h ]
computed = @pod.relative_header_files.map(&:to_s) computed = @pod.relative_header_files.map(&:to_s)
assert_array_equals(expected, computed) assert_array_equals(expected, computed)
end end
it "resolves the documentation header files including not activated subspecs" do it "resolves the documentation header files including not activated subspecs" do
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
spec = subspecs[0] spec = subspecs[0]
spec.stubs(:public_header_files).returns("UIKit/Classes/*Kit.h") 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 # 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 } computed = @pod.documentation_headers.map { |p| p.relative_path_from(@pod.root).to_s }
# The Following headers are private: # The Following headers are private:
# UIKit/Classes/UIView.h # UIKit/Classes/UIView.h
# UIKit/Classes/UIWindow.h # UIKit/Classes/UIWindow.h
expected = %w[ expected = %w[
UIKit/Classes/UIKit.h UIKit/Classes/UIKit.h
StoreKit/Classes/SKPayment.h StoreKit/Classes/SKPayment.h
StoreKit/Classes/StoreKit.h StoreKit/Classes/StoreKit.h
...@@ -284,105 +285,131 @@ describe Pod::LocalPod do ...@@ -284,105 +285,131 @@ describe Pod::LocalPod do
AssetsLibrary/Classes/ALAssetsGroup.h AssetsLibrary/Classes/ALAssetsGroup.h
AssetsLibrary/Classes/ALAssetsLibrary.h AssetsLibrary/Classes/ALAssetsLibrary.h
AssetsLibrary/Classes/AssetsLibrary.h AssetsLibrary/Classes/AssetsLibrary.h
] ]
assert_array_equals(expected, computed) assert_array_equals(expected, computed)
end end
it "merges the xcconfigs without duplicates" do it "merges the xcconfigs without duplicates" do
@pod.xcconfig.should == { @pod.xcconfig.should == {
"OTHER_LDFLAGS"=>"-framework AppKit -framework Foundation -framework IOKit -framework QTKit -framework QuartzCore -framework SystemConfiguration -framework WebKit" } "OTHER_LDFLAGS"=>"-framework AppKit -framework Foundation -framework IOKit -framework QTKit -framework QuartzCore -framework SystemConfiguration -framework WebKit" }
end end
it "returns a hash of mappings with a custom header dir prefix" do it "returns a hash of mappings with a custom header dir prefix" do
mappings = @pod.send(:header_mappings, @pod.header_files_by_spec) mappings = @pod.send(:header_mappings, @pod.header_files_by_spec)
mappings = mappings.map do |folder, headers| mappings = mappings.map do |folder, headers|
"#{folder} > #{headers.sort.map{ |p| p.relative_path_from(@pod.root).to_s }.join(' ')}" "#{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
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
# TODO this is a stub # TODO this is a stub
xit "respects the exclude files attribute of the specifications" do xit "respects the exclude files attribute of the specifications" do
@pod.stubs(:exclude_files).returns([@pod.root + 'UIKit/Classes/UIKit.h']) @pod.stubs(:exclude_files).returns([@pod.root + 'UIKit/Classes/UIKit.h'])
mappings = @pod.send(:header_mappings, @pod.header_files_by_spec) mappings = @pod.send(:header_mappings, @pod.header_files_by_spec)
mappings = mappings.map do |folder, headers| mappings = mappings.map do |folder, headers|
"#{folder} > #{headers.sort.map{ |p| p.relative_path_from(@pod.root).to_s }.join(' ')}" "#{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/UIView.h UIKit/Classes/UIWindow.h" ]
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
xit "includes the sandbox of the pod's headers while linking" do xit "includes the sandbox of the pod's headers while linking" do
@sandbox.build_headers.expects(:add_search_path).with(Pathname.new('Chameleon')) @sandbox.build_headers.expects(:add_search_path).with(Pathname.new('Chameleon'))
@sandbox.public_headers.expects(:add_search_path).with(Pathname.new('Chameleon')) @sandbox.public_headers.expects(:add_search_path).with(Pathname.new('Chameleon'))
@pod.link_headers @pod.link_headers
end end
it "differentiates among public and build headers" do it "differentiates among public and build headers" do
subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs subspecs = fixture_spec('chameleon/Chameleon.podspec').subspecs
spec = subspecs[0] spec = subspecs[0]
spec.stubs(:public_header_files).returns("UIKit/Classes/*Kit.h") 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 } 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 } 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 } build_headers.sort.should == %w{ UIKit.h UIView.h UIWindow.h }
public_headers.should == %w{ UIKit.h } public_headers.should == %w{ UIKit.h }
end
end end
end
describe "concerning a Pod with a local source" do #---------------------------------------------------------------------------#
before do describe "concerning a Pod with a local source" 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))
end
it "is marked as local" do before do
@pod.to_s.should.include? '[LOCAL]' @local_path = temporary_directory + 'localBanana'
end @sandbox = temporary_sandbox
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@spec.source = {:local => @local_path}
@pod = LocalPod::LocalSourcedPod.new(@spec, @sandbox, Platform.new(:ios))
end
it "is marked as downloaded" do it "is marked as local" do
@pod.downloaded?.should.be.true @pod.to_s.should.include? '[LOCAL]'
end end
it "correctly repports the root of the pod" do it "is marked as downloaded" do
@pod.root.should == @local_path @pod.downloaded?.should.be.true
end end
it "doesn't create the root" do it "correctly repports the root of the pod" do
@pod.create @pod.root.should == @local_path
@local_path.exist?.should.be.false end
end
before do it "doesn't create the root" do
FileUtils.cp_r(fixture('banana-lib'), @local_path) @pod.create
end @local_path.exist?.should.be.false
end
it "doesn't cleans the user files" do before do
useless_file = @local_path + 'useless.txt' FileUtils.cp_r(fixture('banana-lib'), @local_path)
FileUtils.touch(useless_file) end
@pod.root.should == @local_path
@pod.clean! it "doesn't cleans the user files" do
useless_file.exist?.should.be.true useless_file = @local_path + 'useless.txt'
end FileUtils.touch(useless_file)
@pod.root.should == @local_path
@pod.clean!
useless_file.exist?.should.be.true
end
it "doesn't implode" do it "doesn't implode" do
@pod.implode @pod.implode
@local_path.exist?.should.be.true @local_path.exist?.should.be.true
end
it "detects the files of the pod" do
@pod.source_files.map {|path| path.to_s.gsub(/.*tmp\//,'') }.sort.should == [
"localBanana/Classes/Banana.m",
"localBanana/Classes/Banana.h"
].sort
end
end end
it "detects the files of the pod" do #---------------------------------------------------------------------------#
@pod.source_files.map {|path| path.to_s.gsub(/.*tmp\//,'') }.sort.should == [
"localBanana/Classes/Banana.m", describe "concerning a Pod with a local source" do
"localBanana/Classes/Banana.h"
].sort 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 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