Commit 504bfd33 authored by Fabio Pelosin's avatar Fabio Pelosin

Improved architecture.

- Moved Project::Library to Pod::Library.
- Removed logic from Pod::Library.
- Restored logic for user build configurations.
- CocoaPods now can infer the platform from the user targets.
parent 5cdcf8a8
......@@ -22,6 +22,7 @@
- Adds new subcommand `pod spec cat NAME` to print a spec file to standard output.
- Added Podfile to the Pods project.
- The `--no-clean` option of the `pod spec lint` command now displays the Pods project for inspection.
- CocoaPods now can infer the platform from the integrated targets.
- Major clean up and refactor to the code base.
- Extrace models to [CocoaPods-Core](https://github.com/CocoaPods/Core) gem.
......
......@@ -9,7 +9,7 @@ GIT
GIT
remote: git://github.com/CocoaPods/Xcodeproj.git
revision: df3755dd51a7dce5151b8862d834bf047b5bc60d
revision: e3dc945c7fdbbd9f977f6bc14b3e6023b99dc5e1
specs:
xcodeproj (0.4.0)
activesupport (~> 3.2.6)
......
......@@ -27,6 +27,7 @@ module Pod
autoload :Executable, 'cocoapods/executable'
autoload :ExternalSources, 'cocoapods/external_sources'
autoload :Installer, 'cocoapods/installer'
autoload :Library, 'cocoapods/library'
autoload :LocalPod, 'cocoapods/local_pod'
autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver'
......
......@@ -39,7 +39,7 @@ module Pod
elsif url = options.delete(:http)
Http.new(target_path, url, options)
else
raise "Unsupported download strategy `#{options.inspect}'."
raise "Unsupported download strategy `#{options.inspect}`."
end
end
end
......
......@@ -121,6 +121,7 @@ module Pod
# @return [void]
#
def analyze
create_libraries
generate_pods_by_podfile_state
update_repositories_if_needed
generate_locked_dependencies
......@@ -207,12 +208,141 @@ module Pod
#
attr_reader :target_installers
#---------------------------------------------------------------------------#
#-------------------------------------------------------------------------#
# @!group Pre-installation computations
attr_reader :libraries
private
def create_libraries
@libraries = []
podfile.target_definitions.values.each do |target_definition|
lib = Library.new(target_definition)
lib.support_files_root = config.sandbox.root
if config.integrate_targets?
lib.user_project_path = compute_user_project_path(target_definition)
lib.user_project = Xcodeproj::Project.new(lib.user_project_path)
lib.user_targets = compute_user_project_targets(target_definition, lib.user_project)
lib.user_build_configurations = compute_user_build_configurations(target_definition, lib.user_targets)
lib.platform = compute_platform_for_taget_definition(target_definition, lib.user_targets)
else
lib.user_project_path = config.project_root
lib.user_targets = []
lib.user_build_configurations = {}
lib.platform = target_definition.platform
end
@libraries << lib
end
end
####################################################################################################
# Returns the path of the user project that the {TargetDefinition}
# should integrate.
#
# @raise If the project is implicit and there are multiple projects.
#
# @raise If the path doesn't exits.
#
# @return [Pathname] the path of the user project.
#
def compute_user_project_path(target_definition)
if target_definition.user_project_path
user_project_path = Pathname.new(config.project_root + target_definition.user_project_path)
unless user_project_path.exist?
raise Informative, "Unable to find the Xcode project `#{user_project_path}` for the target `#{target_definition.label}`."
end
else
xcodeprojs = Pathname.glob(config.project_root + '*.xcodeproj')
if xcodeprojs.size == 1
user_project_path = xcodeprojs.first
else
raise Informative, "Could not automatically select an Xcode project. " \
"Specify one in your Podfile like so:\n\n" \
" xcodeproj 'path/to/Project.xcodeproj'\n"
end
end
user_project_path
end
# Returns a list of the targets from the project of {TargetDefinition}
# that needs to be integrated.
#
# @note The method first looks if there is a target specified with
# the `link_with` option of the {TargetDefinition}. Otherwise
# it looks for the target that has the same name of the target
# definition. Finally if no target was found the first
# encountered target is returned (it is assumed to be the one
# to integrate in simple projects).
#
# @note This will only return targets that do **not** already have
# the Pods library in their frameworks build phase.
#
#
def compute_user_project_targets(target_definition, user_project)
return [] unless user_project
if link_with = target_definition.link_with
targets = user_project.targets.select { |t| link_with.include? t.name }
raise Informative, "Unable to find a target named `#{link_with.to_sentence}` to link with target definition `#{target_definition.name}`" if targets.empty?
elsif target_definition.name != :default
target = user_project.targets.find { |t| t.name == target_definition.name.to_s }
targets = [ target ].compact
raise Informative, "Unable to find a target named `#{target_definition.name.to_s}`" if targets.empty?
else
targets = [ user_project.targets.first ].compact
raise Informative, "Unable to find a target" if targets.empty?
end
targets
end
# @todo Robustness for installations without integration.
#
def compute_user_build_configurations(target_definition, user_targets)
if user_targets
user_targets.map { |t| t.build_configurations.map(&:name) }.flatten.inject({}) do |hash, name|
unless name == 'Debug' || name == 'Release'
hash[name] = :release
end
hash
end.merge(target_definition.build_configurations || {})
else
target_definition.build_configurations || {}
end
end
# Returns the platform for the library.
#
# @note This resolves to the lowest deployment target across the user targets.
#
# @todo Finish implementation
#
def compute_platform_for_taget_definition(target_definition, user_targets)
return target_definition.platform if target_definition.platform
if user_targets
name = nil
deployment_target = nil
user_targets.each do |target|
name ||= target.platform_name
raise "Targets with different platforms" unless name == target.platform_name
if !deployment_target || deployment_target > Version.new(target.deployment_target)
deployment_target = Version.new(target.deployment_target)
end
end
platform = Platform.new(name, deployment_target)
# TODO
target_definition.platform = platform
else
raise Informative, "Missing platform for #{target_definition}."\
"If no integrating it is necessary to specify a platform."
end
platform
end
####################################################################################################
# Compares the {Podfile} with the {Lockfile} in order to detect which
# dependencies should be locked.
#
......@@ -542,8 +672,9 @@ module Pod
def prepare_pods_project
UI.message "- Creating Pods project" do
@pods_project = Pod::Project.new(config.sandbox)
if config.project_podfile.exist?
@pods_project.add_podfile(config.project_podfile)
# pods_project.user_build_configurations = podfile.user_build_configurations
end
end
end
......@@ -554,7 +685,8 @@ module Pod
def generate_target_installers
@target_installers = podfile.target_definitions.values.map do |definition|
pods_for_target = local_pods_by_target[definition]
TargetInstaller.new(pods_project, definition, pods_for_target) unless definition.empty?
libray = libraries.find {|l| l.target_definition == definition }
TargetInstaller.new(pods_project, libray, pods_for_target) unless definition.empty?
end.compact
end
......@@ -599,14 +731,14 @@ module Pod
# Runs the post install hooks of the installed specs and of the Podfile.
#
# @todo Run the hooks only for the installed pods.
# @todo Print a messsage with the names of the specs.
# @todo Print a message with the names of the specs.
#
# @return [void]
#
def run_post_install_hooks
UI.message "- Running post install hooks" do
target_installers.each do |target_installer|
specs_by_target[target_installer.target_definition].each do |spec|
specs_by_target[target_installer.library.target_definition].each do |spec|
spec.post_install!(target_installer)
end
end
......@@ -622,10 +754,10 @@ module Pod
def generate_target_support_files
UI.message"- Installing targets" do
target_installers.each do |target_installer|
pods_for_target = local_pods_by_target[target_installer.target_definition]
pods_for_target = local_pods_by_target[target_installer.library.target_definition]
target_installer.install!
acknowledgements_path = target_installer.library.acknowledgements_path
Generator::Acknowledgements.new(target_installer.target_definition,
Generator::Acknowledgements.new(target_installer.library.target_definition,
pods_for_target).save_as(acknowledgements_path)
generate_dummy_source(target_installer)
end
......@@ -633,12 +765,12 @@ module Pod
end
# Generates a dummy source file for each target so libraries that contain
# only cathegories build.
# only categories build.
#
# @todo Move to the target installer?
#
def generate_dummy_source(target_installer)
class_name_identifier = target_installer.target_definition.label
class_name_identifier = target_installer.library.label
dummy_source = Generator::DummySource.new(class_name_identifier)
filename = "#{dummy_source.class_name}.m"
pathname = Pathname.new(sandbox.root + filename)
......@@ -691,7 +823,7 @@ module Pod
#
def integrate_user_project
return unless config.integrate_targets?
UserProjectIntegrator.new(podfile, pods_project, config.project_root).integrate!
UserProjectIntegrator.new(podfile, pods_project, config.project_root, libraries).integrate!
end
end
end
module Pod
class Installer
# This class is responsible of creating and configuring the static library
# target in Pods project. Every target is generated from a target
# 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.
#
class TargetInstaller
......@@ -11,12 +11,11 @@ module Pod
#
attr_reader :project
# @return [TargetDefinition] The target definition whose target needs to
# be generated.
# @return [Library] The library whose target needs to be generated.
#
attr_reader :target_definition
attr_reader :library
# @param [Array<LocalPod>] pods the pods are required by the target
# @return [Array<LocalPod>] The pods are required by the target
# definition of this installer.
#
attr_reader :pods
......@@ -25,9 +24,9 @@ module Pod
# @param [TargetDefinition] target_definition @see target_definition
# @param [Array<LocalPod>] pods @see pods
#
def initialize(project, target_definition, pods)
def initialize(project, library, pods)
@project = project
@target_definition = target_definition
@library = library
@pods = pods
end
......@@ -36,10 +35,9 @@ module Pod
# @return [void]
#
def install!
add_file_reference_for_support_files
add_target
add_build_files_to_target
add_file_reference_for_support_files
configure_target
create_xcconfig_file
create_prefix_header
......@@ -56,27 +54,22 @@ module Pod
#-----------------------------------------------------------------------#
# @!group Installation steps
# @!group Installation products.
private
public
# Adds the library for the {#target_definition} to the Pods
# project.
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
# @return [void]
# @note Generated by the {#add_target} step.
#
def add_target
@library = @project.add_pod_library(target_definition)
@target = @library.target
end
attr_reader :target
# Adds the build files of the pods to the target.
#
# @return [void]
#
def add_build_files_to_target
pods.each { |p| p.add_build_files_to_target(target) }
end
#-----------------------------------------------------------------------#
# @!group Installation steps
private
# Adds the file references for the support files that are generated by
# the installation process to the Pods project.
......@@ -87,31 +80,58 @@ module Pod
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)
g.new_file(library.xcconfig_name).tap { |f| @xcconfig_file_ref = f }
@xcconfig_file_ref = g.new_file(library.xcconfig_name)
end
# Configures the build settings of the target.
# 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?
#
# @return [void]
#
def configure_target
set = {
'GCC_PREFIX_HEADER' => library.prefix_header_name
}
if @target_definition.inhibit_all_warnings?
set['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
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
if target_definition.inhibit_all_warnings?
settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end
Generator::XCConfig.pods_project_settings.each do |key, value|
set[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)
library.user_build_configurations.each do |name, type|
unless @target.build_configurations.map(&:name).include?(name)
build_config = project.new(Xcodeproj::Project::XCBuildConfiguration)
build_config.name = name
settings = @target.build_settings(type.to_s.capitalize)
build_config.build_settings = settings
target.build_configurations << build_config
project.build_configurations << build_config
end
end
@target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
c.build_settings.merge!(set)
end
library.target = @target
end
# Adds the build files of the pods to the target.
#
# @return [void]
#
def add_build_files_to_target
pods.each { |p| p.add_build_files_to_target(target) }
end
# Generates the contents of the xcconfig file and saves it to disk.
......@@ -179,22 +199,9 @@ module Pod
#-----------------------------------------------------------------------#
# @!group Installation products.
public
# @return [Library] the library for the target definition.
#
# @note Generated by the {#add_target} step.
#
attr_reader :library
# @!group Private helpers.
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
# @note Generated by the {#add_target} step.
#
attr_reader :target
private
# @return [PBXFileReference] the file reference to the xcconfig file of
# the target.
......@@ -203,11 +210,6 @@ module Pod
#
attr_reader :xcconfig_file_ref
#-----------------------------------------------------------------------#
# @!group Private helpers.
private
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
......@@ -216,6 +218,12 @@ module Pod
project.sandbox
end
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
library.target_definition
end
# Creates and caches the copy resource script.
#
# @return [CopyResourcesScript]
......@@ -223,6 +231,30 @@ module Pod
def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new
end
# Returns the Xcode build settings for a target with the given platform.
#
# @param [Platform] platform
# the platform for which the build settings are needed.
#
# @return [Hash] the build settings.
#
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
end
end
end
end
......
......@@ -31,12 +31,22 @@ module Pod
#
attr_reader :project_root
# @return [Library] the libraries generated by the installer.
#
attr_reader :libraries
# @param [Podfile] podfile @see #podfile.
# @param [Project] pods_project @see #pods_project.
# @param [Pathname] project_root @see #project_root.
# @param [Library] libraries @see #libraries.
#
def initialize(podfile, pods_project, project_root)
# @todo Too many initialization arguments
#
def initialize(podfile, pods_project, project_root, libraries)
@podfile = podfile
@pods_project = pods_project
@project_root = project_root
@libraries = libraries
end
# Integrates the user projects associated with the {TargetDefinitions}
......@@ -83,7 +93,7 @@ module Pod
# @return [void]
#
def integrate_user_targets
pods_project.libraries.each do |lib|
libraries.each do |lib|
next if lib.target_definition.empty?
TargetIntegrator.new(lib).integrate!
end
......@@ -101,7 +111,7 @@ module Pod
# @return [void]
#
def warn_about_empty_podfile
unless podfile.target_definitions.values.any?{ |td| !td.empty? }
if podfile.target_definitions.values.all?{ |td| td.empty? }
UI.warn "[!] The Podfile does not contain any dependency."
end
end
......@@ -134,9 +144,7 @@ module Pod
# @note Empty target definitions are ignored.
#
def user_project_paths
pods_project.libraries.map do |lib|
# TODO: remove
next if lib.target_definition.empty?
libraries.map do |lib|
lib.user_project_path
end.compact.uniq
end
......@@ -180,8 +188,8 @@ module Pod
# @note A target is considered integrated if it already references
#
def targets
@targets ||= library.user_targets.reject do |t|
t.frameworks_build_phase.files.any? do |build_file|
@targets ||= library.user_targets.reject do |target|
target.frameworks_build_phase.files.any? do |build_file|
file_ref = build_file.file_ref
!file_ref.proxy? && file_ref.display_name == library.name
end
......@@ -293,7 +301,7 @@ module Pod
"Remove the build settings from the target."
]
UI.warn("The target `#{name}' overrides the `#{key}' build " \
"setting defined in `#{xcconfig_relative_path}'.",
"setting defined in `#{library.xcconfig_relative_path}'.",
actions)
end
end
......
module Pod
# Model class which describes a Pods library.
#
# The Library class stores and provides the information necessary for
# working with a library in the Pods project and in the user projects
# through the installation process.
#
class Library
# @return [PBXNativeTarget] the target definition of the Podfile that
# generated this library.
#
attr_reader :target_definition
# @param [TargetDefinition] target_definition @see target_definition
# @param [PBXNativeTarget] target @see target
#
def initialize(target_definition)
@target_definition = target_definition
end
# @return [String] the label for the library.
#
def label
target_definition.label.to_s
end
# @return [String] the name of the library.
#
def name
"lib#{target_definition.label}.a"
end
#-------------------------------------------------------------------------#
# @!group Information storage
# @return [Pathname] the folder where to store the support files of this
# library.
#
attr_accessor :support_files_root
# @return [Pathname] the path of the user project that this library will
# integrate.
#
attr_accessor :user_project_path
# @return [Xcodeproj::Project] The project that will be integrated.
#
attr_accessor :user_project
# @return [Array<PBXNativeTarget>] the list of the user targets that will
# be integrated by this library.
#
attr_accessor :user_targets
# @return [Hash{String=>Symbol}] A hash representing the user build
# configurations where each key corresponds to the name of a
# configuration and its value to its type (`:debug` or `:release`).
#
attr_accessor :user_build_configurations
# @return [Platform] the platform for this library.
#
attr_accessor :platform
# @return [PBXNativeTarget] the target generated in the Pods project for
# this library.
#
attr_accessor :target
# @return [Xcodeproj::Config] the configuration file of the library
#
# @note The configuration is generated by the {TargetInstaller} and
# used by {UserProjectIntegrator} to check for any overridden
# values.
#
attr_accessor :xcconfig
# @todo
#
attr_accessor :specifications
#-------------------------------------------------------------------------#
# @!group Support files
# @return [String] The xcconfig path of the root from the `$(SRCROOT)`
# variable of the user's project.
#
def relative_pods_root
"${SRCROOT}/#{relative_to_srcroot}"
end
# @return [String] the name of the xcconfig file relative to this target.
#
def xcconfig_name
"#{label}.xcconfig"
end
# @return [Pathname] the absolute path of the xcconfig file.
#
def xcconfig_path
support_files_root + xcconfig_name
end
# @return [String] the path of the xcconfig file relative to the root of
# the user project.
#
def xcconfig_relative_path
relative_to_srcroot("#{xcconfig_name}").to_s
end
# @return [String] the name of the copy resources script relative to this
# target.
#
def copy_resources_script_name
"#{label}-resources.sh"
end
# @return [Pathname] the absolute path of the copy resources script.
#
def copy_resources_script_path
support_files_root + copy_resources_script_name
end
# @return [String] the path of the copy resources script relative to the
# root of the user project.
#
def copy_resources_script_relative_path
"${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"
end
# @return [Pathname] the absolute path of the bridge support file.
#
def bridge_support_path
support_files_root + bridge_support_name
end
# @return [Pathname] the absolute path of acknowledgements file.
#
# @note The acknowledgements generators add the extension according to
# the file type.
#
def acknowledgements_path
support_files_root + "#{label}-Acknowledgements"
end
#-------------------------------------------------------------------------#
# @!group Private Helpers
private
# Computes the relative path of a sandboxed file from the `$(SRCROOT)`
# variable of the user's project.
#
# @param [Pathname] path
# A relative path from the root of the sandbox.
#
# @return [String] the computed path.
#
def relative_to_srcroot(path = nil)
base_path = path ? support_files_root + path : support_files_root
base_path.relative_path_from(user_project_path.dirname).to_s
end
end
end
require 'open-uri'
# Allow open-uri to follow http to https redirects.
#
# Inspiration from: https://gist.github.com/1271420
# Relevant issue: http://redmine.ruby-lang.org/issues/3719
# Source here: https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb
#
# Allow open-uri to follow http to https redirects.
# Relevant issue:
# http://redmine.ruby-lang.org/issues/3719
# Source here:
# https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb
module OpenURI
def OpenURI.redirectable?(uri1, uri2) # :nodoc:
# This test is intended to forbid a redirection from http://... to
# file:///etc/passwd, file:///dev/zero, etc. CVE-2011-1521
# https to http redirect is also forbidden intentionally.
# It avoids sending secure cookie or referer by non-secure HTTP protocol.
# (RFC 2109 4.3.1, RFC 2965 3.3, RFC 2616 15.1.3)
# However this is ad hoc. It should be extensible/configurable.
#
def OpenURI.redirectable?(uri1, uri2)
uri1.scheme.downcase == uri2.scheme.downcase ||
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:https?|ftp)\z/i =~ uri2.scheme)
end
......
This diff is collapsed.
......@@ -55,14 +55,14 @@ module Pod
perform_linting
begin
# begin
if spec
check_repo_path if repo_path
perform_extensive_analysis unless quick
end
rescue Exception => e
error "The specification is malformed and crashed the linter."
end
# rescue Exception => e
# error "The specification is malformed and crashed the linter."
# end
unless disable_ui_output
UI.puts " -> ".send(result_color) << (spec ? spec.name : file.basename.to_s)
......
require File.expand_path('../../../spec_helper', __FILE__)
describe TargetInstaller = Pod::Installer::TargetInstaller do
module Pod
describe TargetInstaller = Installer::TargetInstaller do
describe "In general" do
before do
@podfile = Pod::Podfile.new do
platform :ios
end
@target_definition = @podfile.target_definitions[:default]
@project = Pod::Project.new(config.sandbox)
@specification = fixture_spec('banana-lib/BananaLib.podspec')
@pods = [Pod::LocalPod.new(@specification, config.sandbox, Pod::Platform.ios)]
@installer = TargetInstaller.new(@project, @target_definition, @pods,)
end
it "returns the project" do
@installer.project.should == @project
end
it "returns the target_definition" do
@installer.target_definition.should == @target_definition
end
it "returns the pods of the target definition" do
@installer.pods.should == @pods
end
end
describe "Installation" do
describe "In General" do
extend SpecHelper::TemporaryDirectory
before do
@podfile = Pod::Podfile.new do
@podfile = Podfile.new do
platform :ios
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions[:default]
@project = Pod::Project.new(config.sandbox)
@project = Project.new(config.sandbox)
@library = Library.new(@target_definition)
@library.platform = Platform.new(:ios, '6.0')
@library.support_files_root = config.sandbox.root
@library.user_project_path = config.sandbox.root + '../user_project.xcodeproj'
@library.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
specification = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(specification, config.sandbox, @target_definition.platform)
@installer = TargetInstaller.new(@project, @target_definition, [@pod])
@pod = LocalPod.new(specification, config.sandbox, @library.platform)
@installer = TargetInstaller.new(@project, @library, [@pod])
specification.prefix_header_contents = '#import "BlocksKit.h"'
@pod.stubs(:root).returns(Pathname.new(fixture('banana-lib')))
@pod.add_file_references_to_project(@project)
end
def do_install!
# Prevent raise for missing dummy project.
Pathname.any_instance.stubs(:exist?).returns(true)
@pod.add_file_references_to_project(@project)
it "adds file references for the support files of the target" do
@installer.install!
group = @project.support_files_group['Pods']
group.children.map(&:display_name).sort.should == [
"Pods-prefix.pch", "Pods-resources.sh", "Pods.xcconfig"
]
end
it 'adds a new static library target to the project' do
do_install!
#--------------------------------------#
it 'adds the target for the static library to the project' do
@installer.install!
@project.targets.count.should == 1
@project.targets.first.name.should == @target_definition.label
end
it 'adds the source files of each pod to the target of the Pod library' do
do_install!
names = @installer.target.source_build_phase.files.map { |bf| bf.file_ref.name }
names.should == [ "Banana.m" ]
it "adds the user build configurations to the target" do
@installer.install!
target = @project.targets.first
target.build_settings('Test')["VALIDATE_PRODUCT"].should == nil
target.build_settings('AppStore')["VALIDATE_PRODUCT"].should == "YES"
end
it "adds file references for the support files of the target" do
do_install!
group = @project.support_files_group['Pods']
group.children.map(&:display_name).sort.should == [
"Pods-prefix.pch", "Pods-resources.sh", "Pods.xcconfig"
]
it "sets ARCHS to 'armv6 armv7' for both configurations if the deployment target is less than 4.3 for iOS targets" do
@library.platform = Platform.new(:ios, '4.0')
@installer.install!
target = @project.targets.first
target.build_settings('Debug')["ARCHS"].should == "armv6 armv7"
target.build_settings('Release')["ARCHS"].should == "armv6 armv7"
end
#--------------------------------------#
it "uses standard ARCHs if deployment target is 4.3 or above" do
@installer.install!
target = @project.targets.first
target.build_settings('Debug')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
target.build_settings('AppStore')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
end
it "sets VALIDATE_PRODUCT to YES for the Release configuration for iOS targets" do
@installer.install!
target = @project.targets.first
target.build_settings('Release')["VALIDATE_PRODUCT"].should == "YES"
end
it "sets IPHONEOS_DEPLOYMENT_TARGET for iOS targets" do
@installer.install!
target = @project.targets.first
target.build_settings('Debug')["IPHONEOS_DEPLOYMENT_TARGET"].should == "6.0"
target.build_settings('AppStore')["IPHONEOS_DEPLOYMENT_TARGET"].should == "6.0"
end
it "sets MACOSX_DEPLOYMENT_TARGET for OS X targets" do
@library.platform = Platform.new(:osx, '10.8')
@installer.install!
target = @project.targets.first
target.build_settings('Debug')["MACOSX_DEPLOYMENT_TARGET"].should == "10.8"
target.build_settings('AppStore')["MACOSX_DEPLOYMENT_TARGET"].should == "10.8"
end
it "adds the settings of the xcconfig that need to be overridden to the target" do
do_install!
@installer.install!
build_configuration = @project.targets.first.build_configurations
build_settings = build_configuration.first.build_settings
Pod::Generator::XCConfig.pods_project_settings.each do |key, value|
Generator::XCConfig.pods_project_settings.each do |key, value|
build_settings[key].should == value
end
end
it "adds the user's build configurations to the target" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
do_install!
@installer.install!
@project.targets.first.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end
it "does not enable the GCC_WARN_INHIBIT_ALL_WARNINGS flag by default" do
do_install!
@installer.install!
@installer.target.build_configurations.each do |config|
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should.be.nil
end
......@@ -98,14 +112,24 @@ describe TargetInstaller = Pod::Installer::TargetInstaller do
it "enables the GCC_WARN_INHIBIT_ALL_WARNINGS flag" do
@podfile.inhibit_all_warnings!
do_install!
@installer.install!
@installer.target.build_configurations.each do |config|
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should == 'YES'
end
end
#--------------------------------------#
it 'adds the source files of each pod to the target of the Pod library' do
@installer.install!
names = @installer.target.source_build_phase.files.map { |bf| bf.file_ref.name }
names.should == [ "Banana.m" ]
end
#--------------------------------------#
it "creates and xcconfig file" do
do_install!
@installer.install!
file = config.sandbox.root + 'Pods.xcconfig'
xcconfig = Xcodeproj::Config.new(file)
xcconfig.to_hash['PODS_ROOT'].should == '${SRCROOT}/Pods'
......@@ -113,7 +137,7 @@ describe TargetInstaller = Pod::Installer::TargetInstaller do
it "creates a prefix header, including the contents of the specification's prefix header" do
@pod.top_specification.prefix_header_contents = '#import "BlocksKit.h"'
do_install!
@installer.install!
prefix_header = config.sandbox.root + 'Pods-prefix.pch'
prefix_header.read.should == <<-EOS.strip_heredoc
#ifdef __OBJC__
......@@ -125,15 +149,16 @@ describe TargetInstaller = Pod::Installer::TargetInstaller do
end
it "creates a bridge support file" do
Pod::Podfile.any_instance.stubs(:generate_bridge_support? => true)
Pod::Generator::BridgeSupport.any_instance.expects(:save_as).once
do_install!
Podfile.any_instance.stubs(:generate_bridge_support? => true)
Generator::BridgeSupport.any_instance.expects(:save_as).once
@installer.install!
end
it "creates a create copy resources script" do
do_install!
@installer.install!
script = config.sandbox.root + 'Pods-resources.sh'
script.read.should.include?('logo-sidebar.png')
end
end
end
end
require File.expand_path('../../spec_helper', __FILE__)
# @return [Lockfile]
#
def generate_lockfile
hash = {}
hash['PODS'] = []
hash['DEPENDENCIES'] = []
hash['SPEC CHECKSUMS'] = []
hash['COCOAPODS'] = Pod::VERSION
Pod::Lockfile.new(hash)
end
# it 'tells each pod to link its headers' do
# @pods[0].expects(:link_headers)
# do_install!
# end
# @return [Podfile]
#
def generate_podfile(pods = ['JSONKit'])
podfile = Pod::Podfile.new do
platform :ios
xcodeproj 'SampleProject/SampleProject'
pods.each { |name| pod name }
end
end
# it 'tells each pod to link its headers' do
# @pods[0].expects(:link_headers)
# do_install!
# end
module Pod
describe Installer do
before do
@sandbox = temporary_sandbox
config.repos_dir = fixture('spec-repos')
config.project_pods_root = @sandbox.root
FileUtils.cp_r(fixture('integration/JSONKit'), @sandbox.root + 'JSONKit')
end
describe "Concerning pre-installation computations" do
def generate_podfile(pods = ['JSONKit'])
podfile = Podfile.new do
platform :ios
xcodeproj 'MyProject'
pods.each { |name| pod name }
end
# before do
# @sandbox = temporary_sandbox
# config.repos_dir = fixture('spec-repos')
# config.project_pods_root = @sandbox.root
# FileUtils.cp_r(fixture('integration/JSONKit'), @sandbox.root + 'JSONKit')
# end
describe "Concerning pre-installation computations" do
# @sandbox = temporary_sandbox
# config.project_pods_root = temporary_sandbox.root
# FileUtils.cp_r(fixture('integration/JSONKit'), @sandbox.root + 'JSONKit')
......@@ -32,25 +47,14 @@ module Pod
# @installer = Installer.new(resolver)
# target_installer = @installer.target_installers.first
# target_installer.install
end
def generate_lockfile
hash = {}
hash['PODS'] = []
hash['DEPENDENCIES'] = []
hash['SPEC CHECKSUMS'] = []
hash['COCOAPODS'] = Pod::VERSION
Pod::Lockfile.new(hash)
end
before do
podfile = generate_podfile
lockfile = generate_lockfile
@installer = Installer.new(@sandbox, podfile, lockfile)
Project::Library.any_instance.stubs(:user_project_path).returns(config.project_root + 'test.xcodeproj')
# TODO
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile)
SpecHelper.create_sample_app_copy_from_fixture('SampleProject')
@installer.install!
end
......@@ -146,8 +150,8 @@ module Pod
# before do
# sandbox = temporary_sandbox
# Pod::Config.instance.project_pods_root = sandbox.root
# Pod::Config.instance.integrate_targets = false
# Config.instance.project_pods_root = sandbox.root
# Config.instance.integrate_targets = false
# podspec_path = fixture('integration/Reachability/Reachability.podspec')
# podfile = Podfile.new do
# platform :osx
......@@ -194,8 +198,8 @@ module Pod
# before do
# sandbox = temporary_sandbox
# Pod::Config.instance.project_pods_root = sandbox.root
# Pod::Config.instance.integrate_targets = false
# Config.instance.project_pods_root = sandbox.root
# Config.instance.integrate_targets = false
# podspec_path = fixture('chameleon')
# podfile = Podfile.new do
# platform :osx
......
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Pod::Library do
describe "In general" do
before do
@target_definition = Podfile::TargetDefinition.new(:default, nil, nil)
@lib = Library.new(@target_definition)
end
it "returns the target_definition that generated it" do
@lib.target_definition.should == @target_definition
end
it "returns the label of the target definition" do
@lib.label.should == 'Pods'
end
it "returns the name of its product" do
@lib.name.should == 'libPods.a'
end
end
describe "Support files" do
before do
@target_definition = Podfile::TargetDefinition.new(:default, nil, nil)
@lib = Library.new(@target_definition)
@lib.support_files_root = config.sandbox.root
@lib.user_project_path = config.sandbox.root + '../user_project.xcodeproj'
end
it "returns the xcconfig name" do
@lib.xcconfig_name.should == 'Pods.xcconfig'
end
it "returns the absolute path of the xcconfig file" do
@lib.xcconfig_path.to_s.should.include?('Pods/Pods.xcconfig')
end
it "returns the path of the xcconfig file relative to the user project" do
@lib.xcconfig_relative_path.should == 'Pods/Pods.xcconfig'
end
it "returns the resources script name" do
@lib.copy_resources_script_name.should == 'Pods-resources.sh'
end
it "returns the absolute path of the resources script" do
@lib.copy_resources_script_path.to_s.should.include?('Pods/Pods-resources.sh')
end
it "returns the path of the resources script relative to the user project" do
@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')
end
end
end
end
......@@ -50,229 +50,8 @@ describe Pod::Project do
f.xc_language_specification_identifier.should == 'xcode.lang.ruby'
f.path.should == '../Podfile'
end
it "adds build configurations named after every configuration across all of the user's projects" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release }
@project.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end
end
describe "Libraries" do
before do
@project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios, '4.3'
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
end
it "adds build configurations named after every configuration across all of the user's projects to a target" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'Test' => :debug, 'AppStore' => :release }
library = @project.add_pod_library(@target_definition)
target = library.target
target.build_settings('Test')["VALIDATE_PRODUCT"].should == nil
target.build_settings('AppStore')["VALIDATE_PRODUCT"].should == "YES"
end
it "sets ARCHS to 'armv6 armv7' for both configurations if the deployment target is less than 4.3 for iOS targets" do
@target_definition.platform = Pod::Platform.new(:ios, '4.2')
library = @project.add_pod_library(@target_definition)
target = library.target
target.build_settings('Debug')["ARCHS"].should == "armv6 armv7"
target.build_settings('Release')["ARCHS"].should == "armv6 armv7"
end
before do
@lib = @project.add_pod_library(@target_definition)
@target = @lib.target
end
it "uses standard ARCHs if deployment target is 4.3 or above" do
@target.build_settings('Debug')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
@target.build_settings('Release')["ARCHS"].should == "$(ARCHS_STANDARD_32_BIT)"
end
it "sets VALIDATE_PRODUCT to YES for the Release configuration for iOS targets" do
@lib.target.build_settings('Release')["VALIDATE_PRODUCT"].should == "YES"
end
it "sets IPHONEOS_DEPLOYMENT_TARGET for iOS targets" do
@target.build_settings('Debug')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3"
@target.build_settings('Release')["IPHONEOS_DEPLOYMENT_TARGET"].should == "4.3"
end
it "returns the added libraries" do
@project.libraries.should == [ @lib ]
end
end
end
#-----------------------------------------------------------------------------#
describe Pod::Project::Library do
describe "In general" do
before do
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
it "returns the target_definition that generated it" do
@lib.target_definition.should == @target_definition
end
it "returns it target in the Pods project" do
@lib.target.name.should == 'Pods'
end
it "returns the label of the target definition" do
@lib.label.should == 'Pods'
end
end
#---------------------------------------#
describe "User project" do
before do
user_project_path = fixture('SampleProject/SampleProject.xcodeproj')
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
xcodeproj user_project_path
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
it "returns the user project path" do
path = fixture('SampleProject/SampleProject.xcodeproj')
@lib.user_project_path.should == path
end
it "raises if no project could be selected" do
@target_definition.stubs(:user_project_path).returns(nil)
Pathname.any_instance.stubs(:exist?).returns(true)
lambda { @lib.user_project_path }.should.raise Pod::Informative
end
it "raises if the project path doesn't exist" do
Pathname.any_instance.stubs(:exist?).returns(false)
lambda { @lib.user_project_path }.should.raise Pod::Informative
end
it "returns the user project" do
@lib.user_project.class.should == Xcodeproj::Project
end
it "returns the user targets associated with the target definition" do
@lib.user_targets.all? { |t| t.isa == 'PBXNativeTarget' }.should.be.true
@lib.user_targets.map(&:name).should == [ 'SampleProject' ]
end
it "uses the targets specified to link with by the target definition" do
@target_definition.stubs(:link_with).returns(['TestRunner'])
@target_definition.stubs(:name).returns('NON-EXISTING')
@lib.user_targets.first.name.should == 'TestRunner'
end
it "it raises if it can't find any target specified to link with by the target definition" do
@target_definition.stubs(:link_with).returns(['NON-EXISTING'])
lambda { @lib.user_targets }.should.raise Pod::Informative
end
it "uses the target with the same name if the target definition name is different from `:default'" do
@target_definition.stubs(:name).returns('TestRunner')
@lib.user_targets.first.name.should == 'TestRunner'
end
it "it raises if it can't find a target with the same name of the target definition" do
@target_definition.stubs(:name).returns('NON-EXISTING')
lambda { @lib.user_targets }.should.raise Pod::Informative
end
it "uses the first target in the user's project if no explicit target is specified for the default target definition" do
project = Xcodeproj::Project.new(@lib.user_project_path)
@lib.user_targets.should == [ project.targets.first ]
end
end
#---------------------------------------#
describe "TargetInstaller & UserProjectIntegrator" do
before do
user_project_path = fixture('SampleProject/SampleProject.xcodeproj')
project = Pod::Project.new(config.sandbox)
podfile = Pod::Podfile.new do
platform :ios
xcodeproj user_project_path
pod 'JSONKit'
end
@target_definition = podfile.target_definitions.values.first
@lib = project.add_pod_library(@target_definition)
end
#---------------------------------------#
it "returns the name of its product" do
@lib.name.should == 'libPods.a'
end
it "returns it Pods project" do
@lib.project.path.should == config.sandbox.project_path
end
#---------------------------------------#
it "stores the xcconfig" do
@lib.xcconfig = Xcodeproj::Config.new({'PODS_ROOT' => '${SRCROOT}'})
@lib.xcconfig.to_hash['PODS_ROOT'].should == '${SRCROOT}'
end
it "returns the xcconfig name" do
@lib.xcconfig_name.should == 'Pods.xcconfig'
end
it "returns the absolute path of the xcconfig file" do
@lib.xcconfig_path.to_s.should.include?('Pods/Pods.xcconfig')
end
it "returns the path of the xcconfig file relative to the user project" do
@lib.xcconfig_relative_path.should == '../../../tmp/Pods/Pods.xcconfig'
end
it "returns the resources script name" do
@lib.copy_resources_script_name.should == 'Pods-resources.sh'
end
it "returns the absolute path of the resources script" do
@lib.copy_resources_script_path.to_s.should.include?('Pods/Pods-resources.sh')
end
it "returns the path of the resources script relative to the user project" do
@lib.copy_resources_script_relative_path.should == '${SRCROOT}/../../../tmp/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
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