Commit 4c1f4a86 authored by Marius Rackwitz's avatar Marius Rackwitz

Merge pull request #3550 from CocoaPods/mr-deduplicate-frameworks

Deduplicate pod targets
parents ef5f9a4f a52d6b3b
......@@ -6,6 +6,25 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
## Master
##### Highlighted Enhancement That Needs Testing
* De-duplicate Pod Targets: CocoaPods now recognizes when a dependency is used
multiple times across different user targets, but needs to be built only once.
The targets in `Pods.xcodeproj` need to be duplicated when one of the following
applies:
* They are used on different platforms.
* They are used with differents sets of subspecs.
* They have any dependency which needs to be duplicated.
You can opt-out of this behavior installation-wise, by setting the following
option in your ``~/.cocoapods/config.yaml`:
```yaml
deduplicate_targets: false
```
[Marius Rackwitz](https://github.com/mrackwitz)
[#3550](https://github.com/CocoaPods/CocoaPods/issues/3550)
##### Breaking
* The CocoaPods environment header has been removed.
......
......@@ -19,6 +19,7 @@ module Pod
:clean => true,
:integrate_targets => true,
:deduplicate_targets => true,
:lock_pod_source => true,
:new_version_message => ENV['COCOAPODS_SKIP_UPDATE_MESSAGE'].nil?,
......@@ -89,6 +90,11 @@ module Pod
attr_accessor :integrate_targets
alias_method :integrate_targets?, :integrate_targets
# @return [Bool] Whether CocoaPods should deduplicate pod targets.
#
attr_accessor :deduplicate_targets
alias_method :deduplicate_targets?, :deduplicate_targets
# @return [Bool] Whether the installer should skip the repos update.
#
attr_accessor :skip_repo_update
......
module Pod
module Generator
class EmbedFrameworksScript
# @return [TargetDefinition] The target definition, whose label will be
# used to locate the target-specific build products.
#
attr_reader :target_definition
# @return [Hash{String, Array{String}] Multiple lists of frameworks per
# @return [Hash{String => Array<String>}] Multiple lists of frameworks per
# configuration.
#
attr_reader :frameworks_by_config
# @param [TargetDefinition] target_definition
# @see #target_definition
#
# @param [Hash{String, Array{String}] frameworks_by_config
# @param [Hash{String => Array<String>] frameworks_by_config
# @see #frameworks_by_config
#
def initialize(target_definition, frameworks_by_config)
@target_definition = target_definition
def initialize(frameworks_by_config)
@frameworks_by_config = frameworks_by_config
end
......@@ -54,7 +45,7 @@ module Pod
install_framework()
{
local source="${BUILT_PRODUCTS_DIR}/#{target_definition.label}/$1"
local source="${BUILT_PRODUCTS_DIR}/$1"
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
......@@ -72,9 +63,9 @@ module Pod
# Embed linked Swift runtime libraries
local basename
basename=$(echo $1 | sed -E s/\\\\..+// && exit ${PIPESTATUS[0]})
basename=$(basename $1 | sed -E s/\\\\..+// && exit ${PIPESTATUS[0]})
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\\\/\\(.+dylib\\).*/\\\\1/g | uniq -u && exit ${PIPESTATUS[0]})
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/${basename}.framework/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\\\/\\(.+dylib\\).*/\\\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -auv \\"${SWIFT_STDLIB_PATH}/${lib}\\" \\"${destination}\\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
......
......@@ -18,7 +18,7 @@ module Pod
# @see target
#
def initialize(target)
super(target.target_definition.platform)
super(target.platform)
@target = target
end
......
......@@ -54,19 +54,57 @@ module Pod
'PODS_ROOT' => target.relative_pods_root,
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
}
@xcconfig = Xcodeproj::Config.new(config)
@xcconfig.merge!(merged_user_target_xcconfigs)
generate_settings_to_import_pod_targets
XCConfigHelper.add_target_specific_settings(target, @xcconfig)
generate_vendored_build_settings
generate_other_ld_flags
# TODO: Need to decide how we are going to ensure settings like these
# are always excluded from the user's project.
#
# See https://github.com/CocoaPods/CocoaPods/issues/1216
@xcconfig.attributes.delete('USE_HEADERMAP')
generate_ld_runpath_search_paths if target.requires_frameworks?
@xcconfig
end
#---------------------------------------------------------------------#
private
# Add build settings, which ensure that the pod targets can be imported
# from the integrating target by all sort of imports, which are:
# - `#import <…>`
# - `#import "…"`
# - `@import …;` / `import …`
#
def generate_settings_to_import_pod_targets
if target.requires_frameworks?
# Framework headers are automatically discoverable by `#import <…>`.
header_search_paths = pod_targets.map { |target| "$PODS_FRAMEWORK_BUILD_PATH/#{target.product_name}/Headers" }
header_search_paths = target.pod_targets.map do |target|
if target.scoped?
"$PODS_FRAMEWORK_BUILD_PATH/#{target.product_name}/Headers"
else
"$CONFIGURATION_BUILD_DIR/#{target.product_name}/Headers"
end
end
build_settings = {
'PODS_FRAMEWORK_BUILD_PATH' => target.configuration_build_dir,
'PODS_FRAMEWORK_BUILD_PATH' => target.scoped_configuration_build_dir,
# Make headers discoverable by `import "…"`
'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-iquote'),
}
if target.pod_targets.any?(&:should_build?)
if target.pod_targets.any? { |t| t.should_build? && t.scoped? }
build_settings['FRAMEWORK_SEARCH_PATHS'] = '$(inherited) "$PODS_FRAMEWORK_BUILD_PATH"'
end
config.merge!(build_settings)
@xcconfig.merge!(build_settings)
else
# Make headers discoverable from $PODS_ROOT/Headers directory
header_search_paths = target.sandbox.public_headers.search_paths(target.platform)
......@@ -76,46 +114,50 @@ module Pod
# by `#import <…>`
'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-isystem'),
}
config.merge!(build_settings)
@xcconfig.merge!(build_settings)
end
end
@xcconfig = Xcodeproj::Config.new(config)
XCConfigHelper.add_target_specific_settings(target, @xcconfig)
pod_targets.each do |pod_target|
# Add custom build settings and required build settings to link to
# vendored libraries and frameworks.
#
# @note
# In case of generated pod targets, which require frameworks, the
# vendored frameworks and libraries are already linked statically
# into the framework binary and must not be linked again to the
# user target.
#
def generate_vendored_build_settings
target.pod_targets.each do |pod_target|
unless pod_target.should_build? && pod_target.requires_frameworks?
# In case of generated pod targets, which require frameworks, the
# vendored frameworks and libraries are already linked statically
# into the framework binary and must not be linked again to the
# user target.
XCConfigHelper.add_settings_for_file_accessors_of_target(pod_target, @xcconfig)
end
end
end
# Add pod target to list of frameworks / libraries that are
# linked with the user’s project.
if pod_target.should_build?
if pod_target.requires_frameworks?
@xcconfig.merge!('OTHER_LDFLAGS' => %(-framework "#{pod_target.product_basename}"))
else
@xcconfig.merge!('OTHER_LDFLAGS' => %(-l "#{pod_target.product_basename}"))
end
# Add pod target to list of frameworks / libraries that are linked
# with the user’s project.
#
def generate_other_ld_flags
other_ld_flags = target.pod_targets.select(&:should_build?).map do |pod_target|
if pod_target.requires_frameworks?
%(-framework "#{pod_target.product_basename}")
else
%(-l "#{pod_target.product_basename}")
end
end
@xcconfig.merge!(merged_user_target_xcconfigs)
# TODO: Need to decide how we are going to ensure settings like these
# are always excluded from the user's project.
#
# See https://github.com/CocoaPods/CocoaPods/issues/1216
@xcconfig.attributes.delete('USE_HEADERMAP')
generate_ld_runpath_search_paths if target.requires_frameworks?
@xcconfig
@xcconfig.merge!('OTHER_LDFLAGS' => other_ld_flags.join(' '))
end
# Ensure to add the default linker run path search paths as they could
# be not present due to being historically absent in the project or
# target template or just being removed by being superficial when
# linking third-party dependencies exclusively statically. This is not
# something a project needs specifically for the integration with
# CocoaPods, but makes sure that it is self-contained for the given
# constraints.
#
def generate_ld_runpath_search_paths
ld_runpath_search_paths = ['$(inherited)']
if target.platform.symbolic_name == :osx
......
......@@ -60,13 +60,13 @@ module Pod
# 'USE_HEADERMAP' => 'NO'
}
if target.requires_frameworks?
if target.requires_frameworks? && target.scoped?
# Only quote the FRAMEWORK_SEARCH_PATHS entry, because it’s a setting that takes multiple values.
# In addition, quoting CONFIGURATION_BUILD_DIR would make it be interpreted as a relative path.
build_settings = {
'PODS_FRAMEWORK_BUILD_PATH' => target.configuration_build_dir,
'CONFIGURATION_BUILD_DIR' => '$PODS_FRAMEWORK_BUILD_PATH',
'FRAMEWORK_SEARCH_PATHS' => '"$PODS_FRAMEWORK_BUILD_PATH"',
'CONFIGURATION_BUILD_DIR' => '$PODS_FRAMEWORK_BUILD_PATH',
}
config.merge!(build_settings)
end
......
......@@ -33,7 +33,7 @@ module Pod
#
def self.default_ld_flags(target)
ld_flags = '-ObjC'
if target.target_definition.podfile.set_arc_compatibility_flag? &&
if target.podfile.set_arc_compatibility_flag? &&
target.spec_consumers.any?(&:requires_arc?)
ld_flags << ' -fobjc-arc'
end
......
......@@ -179,7 +179,7 @@ module Pod
# generated as result of the analyzer.
#
def pod_targets
aggregate_targets.map(&:pod_targets).flatten
aggregate_targets.map(&:pod_targets).flatten.uniq
end
# @return [Array<Specification>] The specifications that where installed.
......@@ -212,9 +212,11 @@ module Pod
# @raise If an unknown user configuration is found.
#
def validate_build_configurations
whitelisted_configs = pod_targets.map do |target|
target.target_definition.all_whitelisted_configurations.map(&:downcase)
end.flatten.uniq
whitelisted_configs = pod_targets.
flat_map(&:target_definitions).
flat_map(&:all_whitelisted_configurations).
map(&:downcase).
uniq
all_user_configurations = analysis_result.all_user_build_configurations.keys.map(&:downcase)
remainder = whitelisted_configs - all_user_configurations
......@@ -260,16 +262,14 @@ module Pod
# created by the Pod source installer as well.
#
def create_file_accessors
aggregate_targets.each do |target|
target.pod_targets.each do |pod_target|
pod_root = sandbox.pod_dir(pod_target.root_spec.name)
path_list = Sandbox::PathList.new(pod_root)
file_accessors = pod_target.specs.map do |spec|
Sandbox::FileAccessor.new(path_list, spec.consumer(pod_target.platform))
end
pod_target.file_accessors ||= []
pod_target.file_accessors.concat(file_accessors)
pod_targets.each do |pod_target|
pod_root = sandbox.pod_dir(pod_target.root_spec.name)
path_list = Sandbox::PathList.new(pod_root)
file_accessors = pod_target.specs.map do |spec|
Sandbox::FileAccessor.new(path_list, spec.consumer(pod_target.platform))
end
pod_target.file_accessors ||= []
pod_target.file_accessors.concat(file_accessors)
end
end
......@@ -351,7 +351,7 @@ module Pod
def determine_dependency_product_types
aggregate_targets.each do |aggregate_target|
aggregate_target.pod_targets.each do |pod_target|
pod_target.host_requires_frameworks = aggregate_target.requires_frameworks?
pod_target.host_requires_frameworks ||= aggregate_target.requires_frameworks?
end
end
end
......@@ -537,7 +537,7 @@ module Pod
def install_libraries
UI.message '- Installing targets' do
pod_targets.sort_by(&:name).each do |pod_target|
next if pod_target.target_definition.dependencies.empty?
next if pod_target.target_definitions.flat_map(&:dependencies).empty?
target_installer = PodTargetInstaller.new(sandbox, pod_target)
target_installer.install!
end
......@@ -628,12 +628,8 @@ module Pod
# @return [void]
#
def share_development_pod_schemes
development_pod_targets = sandbox.development_pods.keys.map do |pod|
pods_project.targets.select { |target| target.name =~ /^Pods-.*-#{pod}$/ }
end.flatten
development_pod_targets.each do |pod_target|
Xcodeproj::XCScheme.share_scheme(pods_project.path, pod_target.name)
development_pod_targets.select(&:should_build?).each do |pod_target|
Xcodeproj::XCScheme.share_scheme(pods_project.path, pod_target.label)
end
end
......@@ -740,6 +736,19 @@ module Pod
#-------------------------------------------------------------------------#
public
# @return [Array<Library>] The targets of the development pods generated by
# the installation process.
#
def development_pod_targets
pod_targets.select do |pod_target|
sandbox.development_pods.keys.include?(pod_target.pod_name)
end
end
#-------------------------------------------------------------------------#
private
# @!group Private helpers
......
This diff is collapsed.
module Pod
class Installer
class Analyzer
class AnalysisResult
# @return [SpecsState] the states of the Podfile specs.
#
attr_accessor :podfile_state
# @return [Hash{TargetDefinition => Array<Specification>}] the
# specifications grouped by target.
#
attr_accessor :specs_by_target
# @return [Array<Specification>] the specifications of the resolved
# version of Pods that should be installed.
#
attr_accessor :specifications
# @return [SpecsState] the states of the {Sandbox} respect the resolved
# specifications.
#
attr_accessor :sandbox_state
# @return [Array<Target>] The Podfile targets containing library
# dependencies.
#
attr_accessor :targets
# @return [Hash{TargetDefinition => Array<TargetInspectionResult>}] the
# results of inspecting the user targets
attr_accessor :target_inspections
# @return [Hash{String=>Symbol}] A hash representing all the user build
# configurations across all integration targets. Each key
# corresponds to the name of a configuration and its value to
# its type (`:debug` or `:release`).
#
def all_user_build_configurations
targets.reduce({}) do |result, target|
result.merge(target.user_build_configurations)
end
end
end
end
end
end
module Pod
class Installer
class Analyzer
# This class represents the state of a collection of Pods.
#
# @note The names of the pods stored by this class are always the **root**
# name of the specification.
#
# @note The motivation for this class is to ensure that the names of the
# subspecs are added instead of the name of the Pods.
#
class SpecsState
# Initialize a new instance
#
# @param [Hash{Symbol=>String}] pods_by_state
# The name of the pods grouped by their state
# (`:added`, `:removed`, `:changed` or `:unchanged`).
#
def initialize(pods_by_state = nil)
@added = []
@deleted = []
@changed = []
@unchanged = []
if pods_by_state
@added = pods_by_state[:added] || []
@deleted = pods_by_state[:removed] || []
@changed = pods_by_state[:changed] || []
@unchanged = pods_by_state[:unchanged] || []
end
end
# @return [Array<String>] the names of the pods that were added.
#
attr_accessor :added
# @return [Array<String>] the names of the pods that were changed.
#
attr_accessor :changed
# @return [Array<String>] the names of the pods that were deleted.
#
attr_accessor :deleted
# @return [Array<String>] the names of the pods that were unchanged.
#
attr_accessor :unchanged
# Displays the state of each pod.
#
# @return [void]
#
def print
added .sort.each { |pod| UI.message('A'.green + " #{pod}", '', 2) }
deleted .sort.each { |pod| UI.message('R'.red + " #{pod}", '', 2) }
changed .sort.each { |pod| UI.message('M'.yellow + " #{pod}", '', 2) }
unchanged.sort.each { |pod| UI.message('-' + " #{pod}", '', 2) }
end
# Adds the name of a Pod to the give state.
#
# @param [String] name
# the name of the Pod.
#
# @param [Symbol] state
# the state of the Pod.
#
# @return [void]
#
def add_name(name, state)
send(state) << name
end
end
end
end
end
module Pod
class Installer
class Analyzer
class TargetInspectionResult
# @return [TargetDefinition] the target definition, whose project was
# inspected
#
attr_accessor :target_definition
# @return [Pathname] the path of the user project that the
# #target_definition should integrate
#
attr_accessor :project_path
# @return [Array<String>] the uuid of the user's targets
#
attr_accessor :project_target_uuids
# @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 :build_configurations
# @return [Platform] the platform of the user targets
#
attr_accessor :platform
# @return [Array<String>] the architectures used by user's targets
#
attr_accessor :archs
# @return [Bool] whether frameworks are recommended for the integration
# due to the presence of Swift source in the user's targets
#
attr_accessor :recommends_frameworks
end
end
end
end
module Pod
class Installer
class Analyzer
class TargetInspector
# @return [TargetDefinition] the target definition to inspect
#
attr_accessor :target_definition
# @return [Pathname] the root of the CocoaPods installation where the
# Podfile is located
attr_accessor :installation_root
# Initialize a new instance
#
# @param [TargetDefinition] target_definition
# @see #target_definition
#
# @param [Pathname] installation_root
# @see #installation_root
#
def initialize(target_definition, installation_root)
@target_definition = target_definition
@installation_root = installation_root
end
# Inspect the #target_definition
#
# @return [TargetInspectionResult]
#
def compute_results
project_path = compute_project_path
user_project = Xcodeproj::Project.open(project_path)
targets = compute_targets(user_project)
result = TargetInspectionResult.new
result.target_definition = target_definition
result.project_path = project_path
result.project_target_uuids = targets.map(&:uuid)
result.build_configurations = compute_build_configurations(targets)
result.platform = compute_platform(targets)
result.archs = compute_archs(targets)
result
end
#-----------------------------------------------------------------------#
private
# Returns the path of the user project that the #target_definition
# 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_project_path
if target_definition.user_project_path
path = installation_root + target_definition.user_project_path
path = "#{path}.xcodeproj" unless File.extname(path) == '.xcodeproj'
path = Pathname.new(path)
unless path.exist?
raise Informative, 'Unable to find the Xcode project ' \
"`#{path}` for the target `#{target_definition.label}`."
end
else
xcodeprojs = installation_root.children.select { |e| e.fnmatch('*.xcodeproj') }
if xcodeprojs.size == 1
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
path
end
# Returns a list of the targets from the project of #target_definition
# 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).
#
# @param [Xcodeproj::Project] user_project
# the user project
#
# @return [Array<PBXNativeTarget>]
#
def compute_targets(user_project)
native_targets = user_project.native_targets
if link_with = target_definition.link_with
targets = native_targets.select { |t| link_with.include?(t.name) }
raise Informative, "Unable to find the targets named #{link_with.map { |x| "`#{x}`" }.to_sentence}" \
"to link with target definition `#{target_definition.name}`" if targets.empty?
elsif target_definition.link_with_first_target?
targets = [native_targets.first].compact
raise Informative, 'Unable to find a target' if targets.empty?
else
target = native_targets.find { |t| t.name == target_definition.name.to_s }
targets = [target].compact
raise Informative, "Unable to find a target named `#{target_definition.name}`" if targets.empty?
end
targets
end
# @param [Array<PBXNativeTarget] the user's targets of the project of
# #target_definition which needs to be integrated
#
# @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`).
#
def compute_build_configurations(user_targets)
if user_targets
user_targets.flat_map { |t| t.build_configurations.map(&:name) }.each_with_object({}) do |name, hash|
hash[name] = name == 'Debug' ? :debug : :release
end.merge(target_definition.build_configurations || {})
else
target_definition.build_configurations || {}
end
end
# @param [Array<PBXNativeTarget] the user's targets of the project of
# #target_definition which needs to be integrated
#
# @return [Platform] The platform of the user's targets
#
# @note This resolves to the lowest deployment target across the user
# targets.
#
# @todo Is assigning the platform to the target definition the best way
# to go?
#
def compute_platform(user_targets)
return target_definition.platform if target_definition.platform
name = nil
deployment_target = nil
user_targets.each do |target|
name ||= target.platform_name
raise Informative, '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
target_definition.set_platform(name, deployment_target)
Platform.new(name, deployment_target)
end
# Computes the architectures relevant for the user's targets.
#
# @param [Array<PBXNativeTarget] the user's targets of the project of
# #target_definition which needs to be integrated
#
# @return [Array<String>]
#
def compute_archs(user_targets)
user_targets.flat_map do |target|
Array(target.common_resolved_build_setting('ARCHS'))
end.compact.uniq.sort
end
# Checks if any of the targets for the {TargetDefinition} computed before
# by #compute_user_project_targets is recommended to be build as a framework
# due the presence of Swift source code in any of the source build phases.
#
# @param [TargetDefinition] target_definition
# the target definition
#
# @param [Array<PBXNativeTarget>] native_targets
# the targets which are checked for presence of Swift source code
#
# @return [Boolean] Whether the user project targets to integrate into
# uses Swift
#
def compute_recommends_frameworks(target_definition, native_targets)
file_predicate = nil
file_predicate = proc do |file_ref|
if file_ref.respond_to?(:last_known_file_type)
file_ref.last_known_file_type == 'sourcecode.swift'
elsif file_ref.respond_to?(:files)
file_ref.files.any?(&file_predicate)
else
false
end
end
target_definition.platform.supports_dynamic_frameworks? || native_targets.any? do |target|
target.source_build_phase.files.any? do |build_file|
file_predicate.call(build_file.file_ref)
end
end
end
end
end
end
end
......@@ -8,9 +8,9 @@ module Pod
#
attr_reader :sandbox
# @return [Array<PodTarget>] The libraries of the installation.
# @return [Array<PodTarget>] The pod targets of the installation.
#
attr_reader :libraries
attr_reader :pod_targets
# @return [Project] The Pods project.
#
......@@ -19,12 +19,12 @@ module Pod
# Initialize a new instance
#
# @param [Sandbox] sandbox @see sandbox
# @param [Array<PodTarget>] libraries @see libraries
# @param [Project] libraries @see libraries
# @param [Array<PodTarget>] pod_targets @see pod_targets
# @param [Project] pods_project @see pod_project
#
def initialize(sandbox, libraries, pods_project)
def initialize(sandbox, pod_targets, pods_project)
@sandbox = sandbox
@libraries = libraries
@pod_targets = pod_targets
@pods_project = pods_project
end
......@@ -113,23 +113,23 @@ module Pod
#
def link_headers
UI.message '- Linking headers' do
libraries.each do |library|
library.file_accessors.each do |file_accessor|
pod_targets.each do |pod_target|
pod_target.file_accessors.each do |file_accessor|
framework_exp = /.framework\//
headers_sandbox = Pathname.new(file_accessor.spec.root.name)
library.build_headers.add_search_path(headers_sandbox, library.platform)
sandbox.public_headers.add_search_path(headers_sandbox, library.platform)
pod_target.build_headers.add_search_path(headers_sandbox, pod_target.platform)
sandbox.public_headers.add_search_path(headers_sandbox, pod_target.platform)
header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
library.build_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp }, library.platform)
pod_target.build_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp }, pod_target.platform)
end
header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files|
sandbox.public_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp }, library.platform)
sandbox.public_headers.add_files(namespaced_path, files.reject { |f| f.to_path =~ framework_exp }, pod_target.platform)
end
vendored_frameworks_header_mappings(headers_sandbox, file_accessor).each do |namespaced_path, files|
sandbox.public_headers.add_files(namespaced_path, files, library.platform)
sandbox.public_headers.add_files(namespaced_path, files, pod_target.platform)
end
end
end
......@@ -146,7 +146,7 @@ module Pod
# specs platform combinations.
#
def file_accessors
@file_accessors ||= libraries.map(&:file_accessors).flatten.compact
@file_accessors ||= pod_targets.map(&:file_accessors).flatten.compact
end
# Adds file references to the list of the paths returned by the file
......
......@@ -67,7 +67,7 @@ module Pod
def custom_build_settings
settings = {}
if target.archs
unless target.archs.empty?
settings['ARCHS'] = target.archs
end
......@@ -184,12 +184,6 @@ module Pod
sandbox.project
end
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
target.target_definition
end
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
......
......@@ -31,6 +31,12 @@ module Pod
private
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
target.target_definition
end
# Ensure that vendored static frameworks and libraries are not linked
# twice to the aggregate target, which shares the xcconfig of the user
# target.
......@@ -81,7 +87,7 @@ module Pod
# @return [void]
#
def create_bridge_support_file
if target_definition.podfile.generate_bridge_support?
if target.podfile.generate_bridge_support?
path = target.bridge_support_path
headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
generator = Generator::BridgeSupport.new(headers)
......@@ -101,7 +107,7 @@ module Pod
end
resources_by_config = {}
target.user_build_configurations.keys.each do |config|
file_accessors = library_targets.select { |t| t.include_in_build_config?(config) }.flat_map(&:file_accessors)
file_accessors = library_targets.select { |t| t.include_in_build_config?(target_definition, config) }.flat_map(&:file_accessors)
resource_paths = file_accessors.flat_map { |accessor| accessor.resources.flat_map { |res| res.relative_path_from(project.path.dirname) } }
resource_bundles = file_accessors.flat_map { |accessor| accessor.resource_bundles.keys.map { |name| "${BUILT_PRODUCTS_DIR}/#{name.shellescape}.bundle" } }
resources_by_config[config] = (resource_paths + resource_bundles).uniq
......@@ -138,11 +144,14 @@ module Pod
path = target.embed_frameworks_script_path
frameworks_by_config = {}
target.user_build_configurations.keys.each do |config|
frameworks_by_config[config] = target.pod_targets.select do |pod_target|
pod_target.include_in_build_config?(config) && pod_target.should_build?
end.map(&:product_name)
relevant_pod_targets = target.pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config) && pod_target.should_build?
end
frameworks_by_config[config] = relevant_pod_targets.map do |pod_target|
"#{target_definition.label}/#{pod_target.product_name}"
end
end
generator = Generator::EmbedFrameworksScript.new(target_definition, frameworks_by_config)
generator = Generator::EmbedFrameworksScript.new(frameworks_by_config)
generator.save_as(path)
add_file_to_support_group(path)
end
......
......@@ -130,7 +130,7 @@ module Pod
bundle_target.build_configurations.each do |c|
c.build_settings['PRODUCT_NAME'] = bundle_name
if target.requires_frameworks?
if target.requires_frameworks? && target.scoped?
c.build_settings['CONFIGURATION_BUILD_DIR'] = target.configuration_build_dir
end
end
......@@ -234,7 +234,7 @@ module Pod
flags << '-DOS_OBJECT_USE_OBJC=0'
end
end
if target_definition.inhibits_warnings_for_pod?(consumer.spec.root.name)
if target.inhibit_warnings?
flags << '-w -Xanalyzer -analyzer-disable-all-checks'
end
flags * ' '
......
......@@ -6,11 +6,6 @@ module Pod
# This class is used to represent both the targets and their libraries.
#
class Target
# @return [TargetDefinition] the target definition of the Podfile that
# generated this target.
#
attr_reader :target_definition
# @return [Sandbox] The sandbox where the Pods should be installed.
#
attr_reader :sandbox
......@@ -21,6 +16,12 @@ module Pod
attr_accessor :host_requires_frameworks
alias_method :host_requires_frameworks?, :host_requires_frameworks
# Initialize a new target
#
def initialize
@archs = []
end
# @return [String] the name of the library.
#
def name
......@@ -110,13 +111,7 @@ module Pod
#
attr_accessor :native_target
# @return [Platform] the platform for this library.
#
def platform
@platform ||= target_definition.platform
end
# @return [String] The value for the ARCHS build setting.
# @return [Array<String>] The value for the ARCHS build setting.
#
attr_accessor :archs
......@@ -191,23 +186,6 @@ module Pod
support_files_dir + "#{label}-dummy.m"
end
# @return [String] The configuration build dir, if the target is integrated
# as framework.
#
# @note Namespace the pod target product with its target definition name.
# Pod target products are named after their specs. The namespacing
# cannot directly happen in the product name itself, because this
# must be equal to the module name and this will be used in source
# code, which should stay agnostic over the dependency manager.
# We need namespacing at all because multiple targets can exist for
# the same podspec and their products should not collide. This
# happens when multiple user targets require the same pod, because
# they could require different sets of subspecs.
#
def configuration_build_dir
"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/#{target_definition.label}"
end
#-------------------------------------------------------------------------#
private
......
......@@ -3,12 +3,17 @@ module Pod
# of the single Pods. The client targets will then depend on this one.
#
class AggregateTarget < Target
# @return [TargetDefinition] the target definition of the Podfile that
# generated this target.
attr_reader :target_definition
# Initialize a new instance
#
# @param [TargetDefinition] target_definition @see target_definition
# @param [Sandbox] sandbox @see sandbox
#
def initialize(target_definition, sandbox)
super()
@target_definition = target_definition
@sandbox = sandbox
@pod_targets = []
......@@ -30,6 +35,18 @@ module Pod
c99ext_identifier(label)
end
# @return [Platform] the platform for this target.
#
def platform
@platform ||= target_definition.platform
end
# @return [Podfile] The podfile which declares the dependency
#
def podfile
target_definition.podfile
end
# @return [Pathname] the folder where the client is stored used for
# computing the relative paths. If integrating it should be the
# folder where the user project is stored, otherwise it should
......@@ -94,7 +111,7 @@ module Pod
#
def pod_targets_for_build_configuration(build_configuration)
pod_targets.select do |pod_target|
pod_target.include_in_build_config?(build_configuration)
pod_target.include_in_build_config?(target_definition, build_configuration)
end
end
......@@ -182,6 +199,13 @@ module Pod
"${SRCROOT}/#{relative_to_srcroot(embed_frameworks_script_path)}"
end
# @return [String] The scoped configuration build dir, relevant if the
# target is integrated as framework.
#
def scoped_configuration_build_dir
"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/#{target_definition.label}"
end
private
# @!group Private Helpers
......
......@@ -3,31 +3,87 @@ module Pod
# A pod can have one or more activated spec/subspecs.
#
class PodTarget < Target
# @return [Specification] the spec for the target.
# @return [Array<Specification>] the spec and subspecs for the target.
#
attr_reader :specs
# @return [Array<PBXNativeTarget>] the target definitions of the Podfile
# that generated this target.
#
attr_reader :target_definitions
# @return [HeadersStore] the header directory for the target.
#
attr_reader :build_headers
# @param [Specification] spec @see spec
# @param [TargetDefinition] target_definition @see target_definition
# @return [Bool] whether the target needs to be scoped by target definition,
# because the spec is used with different subspec sets across them.
#
# @note For frameworks the target products of {PodTarget}s are named
# after their specs. The namespacing cannot directly happen in
# the product name itself, because this must be equal to the module
# name and this will be used in source code, which should stay
# agnostic over the dependency manager.
# We need namespacing because multiple targets can exist for the
# same podspec and their products should not collide. This
# duplication is needed when multiple user targets have the same
# dependency, but they require different sets of subspecs or they
# are on different platforms.
#
attr_reader :scoped
alias_method :scoped?, :scoped
# @param [Array<Specification>] @spec #see spec
# @param [Array<TargetDefinition>] target_definitions @see target_definitions
# @param [Sandbox] sandbox @see sandbox
# @param [Bool] scoped @see scoped
#
def initialize(specs, target_definition, sandbox)
def initialize(specs, target_definitions, sandbox, scoped = false)
raise "Can't initialize a PodTarget without specs!" if specs.nil? || specs.empty?
raise "Can't initialize a PodTarget without TargetDefinition!" if target_definitions.nil? || target_definitions.empty?
super()
@specs = specs
@target_definition = target_definition
@target_definitions = target_definitions
@sandbox = sandbox
@scoped = scoped
@build_headers = Sandbox::HeadersStore.new(sandbox, 'Private')
@file_accessors = []
@resource_bundle_targets = []
end
# @return [Array<PodTarget>] a scoped copy for each target definition.
#
def scoped
target_definitions.map do |target_definition|
PodTarget.new(specs, [target_definition], sandbox, true).tap do |target|
target.file_accessors = file_accessors
target.user_build_configurations = user_build_configurations
target.native_target = native_target
target.archs = archs
end
end
end
# @return [String] the label for the target.
#
def label
"#{target_definition.label}-#{root_spec.name}"
if scoped?
"#{target_definitions.first.label}-#{root_spec.name}"
else
root_spec.name
end
end
# @return [Platform] the platform for this target.
#
def platform
@platform ||= target_definitions.first.platform
end
# @return [Podfile] The podfile which declares the dependency.
#
def podfile
target_definitions.first.podfile
end
# @return [String] The name to use for the source code module constructed
......@@ -103,13 +159,16 @@ module Pod
end
# Checks if the target should be included in the build configuration with
# the given name.
# the given name of a given target definition.
#
# @param [TargetDefinition] target_definition
# The target definition to check.
#
# @param [String] configuration_name
# The name of the build configuration.
#
def include_in_build_config?(configuration_name)
whitelists = target_definition_dependencies.map do |dependency|
def include_in_build_config?(target_definition, configuration_name)
whitelists = target_definition_dependencies(target_definition).map do |dependency|
target_definition.pod_whitelisted_for_configuration?(dependency.name, configuration_name)
end.uniq
......@@ -125,14 +184,51 @@ module Pod
end
end
# Checks if warnings should be inhibited for this pod.
#
# @return [Bool]
#
def inhibit_warnings?
whitelists = target_definitions.map do |target_definition|
target_definition.inhibits_warnings_for_pod?(root_spec.name)
end.uniq
if whitelists.empty?
return false
elsif whitelists.count == 1
whitelists.first
else
UI.warn "The pod `#{pod_name}` is linked to different targets " \
"(#{target_definitions.map(&:label)}), which contain different " \
'settings to inhibit warnings. CocoaPods does not currently ' \
'support different settings and will fall back to your preference ' \
'set in the root target definition.'
return podfile.root_target_definitions.first.inhibits_warnings_for_pod?(root_spec.name)
end
end
# @return [String] The configuration build dir, relevant if the target is
# integrated as framework.
#
def configuration_build_dir
if scoped?
"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/#{target_definitions.first.label}"
else
'$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
end
end
private
# @param [TargetDefinition] target_definition
# The target definition to check.
#
# @return [Array<Dependency>] The dependency of the target definition for
# this Pod. Return an empty array if the Pod is not a direct
# dependency of the target definition but the dependency of one or
# more Pods.
#
def target_definition_dependencies
def target_definition_dependencies(target_definition)
target_definition.dependencies.select do |dependency|
Specification.root_name(dependency.name) == pod_name
end
......
Subproject commit 0ce7a32ea385cf641ef76bd7f5a8166c554086d3
Subproject commit 9793ea0fa86ceb9656ed768e58fa3d6db1407dd7
//
// main.swift
// CLITool
//
// Created by Marius Rackwitz on 3.6.15.
// Copyright (c) 2015 LJR Software Limited. All rights reserved.
//
import Foundation
println("Hello, World!")
......@@ -114,7 +114,7 @@
51E94E06164472080035348C /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0450;
LastUpgradeCheck = 0630;
ORGANIZATIONNAME = CocoaPods;
};
buildConfigurationList = 51E94E09164472080035348C /* Build configuration list for PBXProject "Sample Lib" */;
......@@ -168,6 +168,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
......@@ -235,6 +236,7 @@
51E94E1F164472090035348C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
......
......@@ -109,36 +109,31 @@ def fixture_spec(name)
Pod::Specification.from_file(file)
end
def fixture_file_accessor(name, platform = :ios)
file = SpecHelper::Fixture.fixture(name)
spec = Pod::Specification.from_file(file)
path_list = Pod::Sandbox::PathList.new(file.dirname)
def fixture_file_accessor(spec_or_name, platform = Pod::Platform.ios)
spec = spec_or_name.is_a?(Pod::Specification) ? spec_or_name : fixture_spec(spec_or_name)
path_list = Pod::Sandbox::PathList.new(spec.defined_in_file.dirname)
Pod::Sandbox::FileAccessor.new(path_list, spec.consumer(platform))
end
def fixture_target_definition(podfile = nil, &block)
podfile ||= Pod::Podfile.new(&block)
Pod::Podfile::TargetDefinition.new('Pods', podfile)
def fixture_target_definition(name = 'Pods', platform = Pod::Platform.ios)
Pod::Podfile::TargetDefinition.new(name, Pod::Podfile.new, 'name' => name, 'platform' => platform)
end
def fixture_pod_target(spec_or_name, platform = :ios, target_definition = nil)
def fixture_pod_target(spec_or_name, target_definition = nil)
spec = spec_or_name.is_a?(Pod::Specification) ? spec_or_name : fixture_spec(spec_or_name)
target_definition ||= fixture_target_definition
target_definition.store_pod(spec.name)
Pod::PodTarget.new([spec], target_definition, config.sandbox).tap do |pod_target|
pod_target.stubs(:platform).returns(platform)
pod_target.file_accessors << fixture_file_accessor(spec.defined_in_file, platform)
consumer = spec.consumer(platform)
Pod::PodTarget.new([spec], [target_definition], config.sandbox).tap do |pod_target|
pod_target.file_accessors << fixture_file_accessor(spec, pod_target.platform)
consumer = spec.consumer(pod_target.platform)
pod_target.spec_consumers << consumer
end
end
def fixture_aggregate_target(pod_targets = [], platform = :ios, target_definition = nil)
target_definition ||= pod_targets.map(&:target_definition).first || fixture_target_definition
def fixture_aggregate_target(pod_targets = [], target_definition = nil)
target_definition ||= pod_targets.flat_map(&:target_definitions).first || fixture_target_definition
target = Pod::AggregateTarget.new(target_definition, config.sandbox)
target.client_root = config.sandbox.root.dirname
version ||= (platform == :ios ? '4.3' : '10.6')
target.stubs(:platform).returns(Pod::Platform.new(platform, version))
target.pod_targets = pod_targets
target
end
......
......@@ -9,6 +9,10 @@ module SpecHelper
fixture_copy_path + "#{fixture_name}.xcodeproj"
end
def self.test_repo_url
'https://github.com/CocoaPods/test_repo.git'
end
module Fixture
ROOT = ::ROOT + 'spec/fixtures'
......
......@@ -184,6 +184,14 @@ module Pod
@config.should.lock_pod_source
end
it 'integrates a user target' do
@config.should.integrate_targets
end
it 'de-duplicates targets' do
@config.should.deduplicate_targets
end
it 'returns the cache root' do
@config.cache_root.should == Pathname.new(File.join(ENV['HOME'], 'Library/Caches/CocoaPods'))
end
......
......@@ -3,15 +3,14 @@ require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Generator::EmbedFrameworksScript do
it 'returns the embed frameworks script' do
target_definition = Podfile::TargetDefinition.new(:default, nil)
frameworks = {
'Debug' => %w(Loopback.framework Reveal.framework),
'Debug' => %w(Pods/Loopback.framework Reveal.framework),
'Release' => %w(CrashlyticsFramework.framework),
}
generator = Pod::Generator::EmbedFrameworksScript.new(target_definition, frameworks)
generator = Pod::Generator::EmbedFrameworksScript.new(frameworks)
generator.send(:script).should.include <<-eos.strip_heredoc
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework 'Loopback.framework'
install_framework 'Pods/Loopback.framework'
install_framework 'Reveal.framework'
fi
eos
......
......@@ -5,7 +5,7 @@ module Pod
before do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil)
@pod_target = PodTarget.new([spec], target_definition, config.sandbox)
@pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@gen = Generator::ModuleMap.new(@pod_target)
end
......@@ -14,7 +14,7 @@ module Pod
@gen.save_as(path)
path.read.should == <<-EOS.strip_heredoc
framework module BananaLib {
umbrella header "Pods-default-BananaLib-umbrella.h"
umbrella header "BananaLib-umbrella.h"
export *
module * { export * }
......@@ -26,7 +26,7 @@ module Pod
@gen.stubs(:private_headers).returns(['Private.h'])
@gen.generate.should == <<-EOS.strip_heredoc
framework module BananaLib {
umbrella header "Pods-default-BananaLib-umbrella.h"
umbrella header "BananaLib-umbrella.h"
export *
module * { export * }
......
......@@ -8,12 +8,16 @@ module Pod
fixture_spec('banana-lib/BananaLib.podspec')
end
def pod_target(spec)
fixture_pod_target(spec)
end
before do
@spec = spec
@pod_target = fixture_pod_target(@spec)
@pod_target = pod_target(@spec)
@consumer = @pod_target.spec_consumers.last
@target = fixture_aggregate_target([@pod_target])
@target.target_definition.should == @pod_target.target_definition
@target.target_definition.should == @pod_target.target_definitions.first
@target.target_definition.whitelist_pod_for_configuration(@spec.name, 'Release')
@podfile = @target.target_definition.podfile
@generator = AggregateXCConfig.new(@target, 'Release')
......@@ -103,8 +107,20 @@ module Pod
@xcconfig.to_hash['OTHER_CFLAGS'].should == expected
end
it 'links the pod targets with the aggregate target' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include '-l"Pods-BananaLib"'
describe 'with a scoped pod target' do
def pod_target(spec)
fixture_pod_target(spec).scoped.first
end
it 'links the pod targets with the aggregate target' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include '-l"Pods-BananaLib"'
end
end
describe 'with an unscoped pod target' do
it 'links the pod targets with the aggregate target' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include '-l"BananaLib"'
end
end
it 'does not links the pod targets with the aggregate target for non-whitelisted configuration' do
......@@ -139,13 +155,30 @@ module Pod
@xcconfig.to_hash['PODS_FRAMEWORK_BUILD_PATH'].should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods'
end
it 'adds the framework build path to the xcconfig, with quotes, as framework search paths' do
@xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should == '$(inherited) "$PODS_FRAMEWORK_BUILD_PATH"'
describe 'with a scoped pod target' do
def pod_target(spec)
fixture_pod_target(spec).scoped.first
end
it 'adds the framework build path to the xcconfig, with quotes, as framework search paths' do
@xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should == '$(inherited) "$PODS_FRAMEWORK_BUILD_PATH"'
end
it 'adds the framework header paths to the xcconfig, with quotes, as local headers' do
expected = '$(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/OrangeFramework.framework/Headers"'
@xcconfig.to_hash['OTHER_CFLAGS'].should == expected
end
end
it 'adds the framework header paths to the xcconfig, with quotes, as local headers' do
expected = '$(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/OrangeFramework.framework/Headers"'
@xcconfig.to_hash['OTHER_CFLAGS'].should == expected
describe 'with an unscoped pod target' do
it 'adds the framework build path to the xcconfig, with quotes, as framework search paths' do
@xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.be.nil
end
it 'adds the framework header paths to the xcconfig, with quotes, as local headers' do
expected = '$(inherited) -iquote "$CONFIGURATION_BUILD_DIR/OrangeFramework.framework/Headers"'
@xcconfig.to_hash['OTHER_CFLAGS'].should == expected
end
end
it 'links the pod targets with the aggregate target' do
......@@ -195,7 +228,7 @@ module Pod
@consumer_b.stubs(:user_target_xcconfig).returns('ENABLE_HEADER_DEPENDENCIES' => 'NO')
@xcconfig = @generator.generate
UI.warnings.should.include 'Can\'t merge user_target_xcconfig for pod targets: ' \
'["Pods-BananaLib", "Pods-OrangeFramework"]. Boolean build setting '\
'["BananaLib", "OrangeFramework"]. Boolean build setting '\
'ENABLE_HEADER_DEPENDENCIES has different values.'
end
end
......@@ -229,7 +262,7 @@ module Pod
@consumer_b.stubs(:user_target_xcconfig).returns('STRIP_STYLE' => 'all')
@xcconfig = @generator.generate
UI.warnings.should.include 'Can\'t merge user_target_xcconfig for pod targets: ' \
'["Pods-BananaLib", "Pods-OrangeFramework"]. Singular build setting '\
'["BananaLib", "OrangeFramework"]. Singular build setting '\
'STRIP_STYLE has different values.'
end
end
......
......@@ -7,14 +7,11 @@ module Pod
describe 'in general' do
before do
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@consumer = @spec.consumer(:ios)
target_definition = Podfile::TargetDefinition.new('Pods', nil)
@pod_target = PodTarget.new([@spec], target_definition, config.sandbox)
@pod_target.stubs(:platform).returns(:ios)
@pod_target = fixture_pod_target(@spec)
@consumer = @pod_target.spec_consumers.first
@podfile = @pod_target.podfile
public_xcconfig = Xcodeproj::Config.new('OTHER_LDFLAGS' => '-framework SystemConfiguration')
@generator = PrivatePodXCConfig.new(@pod_target, public_xcconfig)
@podfile = Podfile.new
@pod_target.target_definition.stubs(:podfile).returns(@podfile)
@xcconfig = @generator.generate
end
......
......@@ -6,23 +6,16 @@ module Pod
describe PublicPodXCConfig do
before do
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@target_definition = Podfile::TargetDefinition.new('Pods', nil)
@pod_target = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target.stubs(:platform).returns(:ios)
@pod_target = fixture_pod_target(@spec)
@generator = PublicPodXCConfig.new(@pod_target)
@podfile = Podfile.new
@spec.xcconfig = { 'OTHER_LDFLAGS' => '-no_compact_unwind' }
@spec.frameworks = ['QuartzCore']
@spec.weak_frameworks = ['iAd']
@spec.libraries = ['xml2']
file_accessors = [Sandbox::FileAccessor.new(fixture('banana-lib'), @spec.consumer(:ios))]
# vendored_framework_paths = [config.sandbox.root + 'BananaLib/BananaLib.framework']
# Sandbox::FileAccessor.any_instance.stubs(:vendored_frameworks).returns(vendored_framework_paths)
@pod_target.target_definition.stubs(:podfile).returns(@podfile)
@pod_target.stubs(:file_accessors).returns(file_accessors)
@xcconfig = @generator.generate
end
......
......@@ -13,17 +13,15 @@ module Pod
describe '::default_ld_flags' do
it 'returns the default linker flags' do
podfile = stub(:set_arc_compatibility_flag? => false)
target_definition = stub(:podfile => podfile)
target = stub(:target_definition => target_definition)
target = stub(:podfile => podfile)
result = @sut.default_ld_flags(target)
result.should == '-ObjC'
end
it 'includes the ARC compatibility flag if required by the Podfile' do
podfile = stub(:set_arc_compatibility_flag? => true)
target_definition = stub(:podfile => podfile)
spec_consumer = stub(:requires_arc? => true)
target = stub(:target_definition => target_definition, :spec_consumers => [spec_consumer])
target = stub(:podfile => podfile, :spec_consumers => [spec_consumer])
result = @sut.default_ld_flags(target)
result.should == '-ObjC -fobjc-arc'
end
......
This diff is collapsed.
This diff is collapsed.
......@@ -3,10 +3,8 @@ require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Installer::FileReferencesInstaller do
before do
@file_accessor = fixture_file_accessor('banana-lib/BananaLib.podspec')
@pod_target = PodTarget.new([], nil, config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target.file_accessors = [@file_accessor]
@pod_target = fixture_pod_target('banana-lib/BananaLib.podspec')
@file_accessor = @pod_target.file_accessors.first
@project = Project.new(config.sandbox.project_path)
@project.add_pod_group('BananaLib', fixture('banana-lib'))
@installer = Installer::FileReferencesInstaller.new(config.sandbox, [@pod_target], @project)
......@@ -79,17 +77,17 @@ module Pod
describe 'Private Helpers' do
describe '#file_accessors' do
it 'returns the file accessors' do
pod_target_1 = PodTarget.new([], nil, config.sandbox)
pod_target_1 = PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)
pod_target_1.file_accessors = [fixture_file_accessor('banana-lib/BananaLib.podspec')]
pod_target_2 = PodTarget.new([], nil, config.sandbox)
pod_target_2 = PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)
pod_target_2.file_accessors = [fixture_file_accessor('banana-lib/BananaLib.podspec')]
installer = Installer::FileReferencesInstaller.new(config.sandbox, [pod_target_1, pod_target_2], @project)
roots = installer.send(:file_accessors).map { |fa| fa.path_list.root }
roots.should == [fixture('banana-lib'), fixture('banana-lib')]
end
it 'handles libraries empty libraries without file accessors' do
pod_target_1 = PodTarget.new([], nil, config.sandbox)
it 'handles pods without file accessors' do
pod_target_1 = PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)
pod_target_1.file_accessors = []
installer = Installer::FileReferencesInstaller.new(config.sandbox, [pod_target_1], @project)
installer.send(:file_accessors).should == []
......
......@@ -8,7 +8,7 @@ module Pod
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new('Pods', nil)
pod_target = PodTarget.new([spec], target_definition, config.sandbox)
pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
umbrella = AggregateTarget.new(target_definition, config.sandbox)
umbrella.user_project_path = '/path/project.xcodeproj'
umbrella.user_target_uuids = ['UUID']
......
......@@ -28,7 +28,7 @@ module Pod
@target.client_root = config.sandbox.root.dirname
@target.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@pod_target = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target.user_build_configurations = @target.user_build_configurations
@pod_target.file_accessors = [file_accessor]
......
......@@ -6,7 +6,7 @@ module Pod
before do
config.sandbox.prepare
@podfile = Podfile.new do
platform :ios
platform :ios, '6.0'
xcodeproj 'dummy'
end
@target_definition = @podfile.target_definitions['Pods']
......@@ -25,8 +25,7 @@ module Pod
@project.add_file_reference(resource, group)
end
@pod_target = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target.file_accessors = [file_accessor]
@pod_target.user_build_configurations = { 'Debug' => :debug, 'Release' => :release }
@installer = Installer::PodTargetInstaller.new(config.sandbox, @pod_target)
......@@ -34,26 +33,6 @@ module Pod
@spec.prefix_header_contents = '#import "BlocksKit.h"'
end
it 'adds file references for the support files of the target' do
@installer.install!
@project.support_files_group
group = @project['Pods/BananaLib/Support Files']
group.children.map(&:display_name).sort.should == [
'Pods-BananaLib-Private.xcconfig',
'Pods-BananaLib-dummy.m',
'Pods-BananaLib-prefix.pch',
'Pods-BananaLib.xcconfig',
]
end
#--------------------------------------#
it 'adds the target for the static library to the project' do
@installer.install!
@project.targets.count.should == 1
@project.targets.first.name.should == 'Pods-BananaLib'
end
it 'sets the platform and the deployment target for iOS targets' do
@installer.install!
target = @project.targets.first
......@@ -100,15 +79,6 @@ module Pod
#--------------------------------------#
it 'adds the resource bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'Pods-BananaLib-banana_bundle' }
bundle_target.should.be.an.instance_of Xcodeproj::Project::Object::PBXNativeTarget
bundle_target.product_reference.name.should == 'banana_bundle.bundle'
bundle_target.product_reference.path.should == 'banana_bundle.bundle'
end
it 'adds framework resources to the framework target' do
@pod_target.stubs(:requires_frameworks? => true)
@installer.install!
......@@ -118,14 +88,91 @@ module Pod
resource.should.be.not.nil
end
it 'adds the build configurations to the resources bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'Pods-BananaLib-banana_bundle' }
#--------------------------------------#
file = config.sandbox.root + @pod_target.xcconfig_private_path
bundle_target.build_configurations.each do |bc|
bc.base_configuration_reference.real_path.should == file
describe 'with a scoped pod target' do
before do
@pod_target = @pod_target.scoped.first
@installer = Installer::PodTargetInstaller.new(config.sandbox, @pod_target)
end
it 'adds file references for the support files of the target' do
@installer.install!
group = @project['Pods/BananaLib/Support Files']
group.children.map(&:display_name).sort.should == [
'Pods-BananaLib-Private.xcconfig',
'Pods-BananaLib-dummy.m',
'Pods-BananaLib-prefix.pch',
'Pods-BananaLib.xcconfig',
]
end
it 'adds the target for the static library to the project' do
@installer.install!
@project.targets.count.should == 1
@project.targets.first.name.should == 'Pods-BananaLib'
end
it 'adds the resource bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'Pods-BananaLib-banana_bundle' }
bundle_target.should.be.an.instance_of Xcodeproj::Project::Object::PBXNativeTarget
bundle_target.product_reference.name.should == 'banana_bundle.bundle'
bundle_target.product_reference.path.should == 'banana_bundle.bundle'
end
it 'adds the build configurations to the resources bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'Pods-BananaLib-banana_bundle' }
file = config.sandbox.root + @pod_target.xcconfig_private_path
bundle_target.build_configurations.each do |bc|
bc.base_configuration_reference.real_path.should == file
end
end
end
#--------------------------------------#
describe 'with an unscoped pod target' do
it 'adds file references for the support files of the target' do
@installer.install!
@project.support_files_group
group = @project['Pods/BananaLib/Support Files']
group.children.map(&:display_name).sort.should == [
'BananaLib-Private.xcconfig',
'BananaLib-dummy.m',
'BananaLib-prefix.pch',
'BananaLib.xcconfig',
]
end
it 'adds the target for the static library to the project' do
@installer.install!
@project.targets.count.should == 1
@project.targets.first.name.should == 'BananaLib'
end
it 'adds the resource bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'BananaLib-banana_bundle' }
bundle_target.should.be.an.instance_of Xcodeproj::Project::Object::PBXNativeTarget
bundle_target.product_reference.name.should == 'banana_bundle.bundle'
bundle_target.product_reference.path.should == 'banana_bundle.bundle'
end
it 'adds the build configurations to the resources bundle targets' do
@pod_target.file_accessors.first.stubs(:resource_bundles).returns('banana_bundle' => [])
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'BananaLib-banana_bundle' }
file = config.sandbox.root + @pod_target.xcconfig_private_path
bundle_target.build_configurations.each do |bc|
bc.base_configuration_reference.real_path.should == file
end
end
end
......@@ -141,9 +188,7 @@ module Pod
it "creates a prefix header, including the contents of the specification's prefix header" do
@spec.prefix_header_contents = '#import "BlocksKit.h"'
@installer.install!
support_files_dir = config.sandbox.target_support_files_dir('Pods-BananaLib')
prefix_header = support_files_dir + 'Pods-BananaLib-prefix.pch'
generated = prefix_header.read
generated = @pod_target.prefix_header_path.read
expected = <<-EOS.strip_heredoc
#ifdef __OBJC__
#import <UIKit/UIKit.h>
......@@ -157,13 +202,12 @@ module Pod
it 'creates a dummy source to ensure the compilation of libraries with only categories' do
@installer.install!
dummy_source_basename = @pod_target.dummy_source_path.basename.to_s
build_files = @installer.target.native_target.source_build_phase.files
build_file = build_files.find { |bf| bf.file_ref.display_name == 'Pods-BananaLib-dummy.m' }
build_file = build_files.find { |bf| bf.file_ref.display_name == dummy_source_basename }
build_file.should.be.not.nil
build_file.file_ref.path.should == 'Pods-BananaLib-dummy.m'
support_files_dir = config.sandbox.target_support_files_dir('Pods-BananaLib')
dummy = support_files_dir + 'Pods-BananaLib-dummy.m'
dummy.read.should.include?('@interface PodsDummy_Pods')
build_file.file_ref.path.should == dummy_source_basename
@pod_target.dummy_source_path.read.should.include?('@interface PodsDummy_BananaLib')
end
#--------------------------------------------------------------------------------#
......@@ -181,7 +225,7 @@ module Pod
end
it 'flags should not be added to dtrace files' do
@installer.target.target_definition.stubs(:inhibits_warnings_for_pod?).returns(true)
@installer.target.target_definitions.first.stubs(:inhibits_warnings_for_pod?).returns(true)
@installer.install!
dtrace_files = @installer.target.native_target.source_build_phase.files.select do |sf|
......@@ -193,7 +237,7 @@ module Pod
end
it 'adds -w per pod if target definition inhibits warnings for that pod' do
@installer.target.target_definition.stubs(:inhibits_warnings_for_pod?).returns(true)
@installer.target.target_definitions.first.stubs(:inhibits_warnings_for_pod?).returns(true)
flags = @installer.send(:compiler_flags_for_consumer, @spec.consumer(:ios), true)
flags.should.include?('-w')
......@@ -205,7 +249,7 @@ module Pod
end
it 'adds -Xanalyzer -analyzer-disable-checker per pod' do
@installer.target.target_definition.stubs(:inhibits_warnings_for_pod?).returns(true)
@installer.target.target_definitions.first.stubs(:inhibits_warnings_for_pod?).returns(true)
flags = @installer.send(:compiler_flags_for_consumer, @spec.consumer(:ios), true)
flags.should.include?('-Xanalyzer -analyzer-disable-all-checks')
......
......@@ -20,7 +20,7 @@ module Pod
@project.add_file_reference(file, group)
end
@pod_target = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@pod_target.file_accessors = [file_accessor]
......
......@@ -130,6 +130,10 @@ module Pod
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'TestRunner', :exclusive => true do
pod 'monkey', :path => (fixture_path + 'monkey').to_s
end
end
lockfile = generate_lockfile
config.integrate_targets = false
......@@ -139,11 +143,11 @@ module Pod
target = @installer.aggregate_targets.first
target.requires_frameworks?.should == true
target.pod_targets.select(&:requires_frameworks?).map(&:name).sort.should == [
'Pods-BananaLib',
'Pods-OrangeFramework',
'Pods-monkey',
]
target.pod_targets.select(&:requires_frameworks?).map(&:name).sort.should == %w(
BananaLib
OrangeFramework
monkey
)
end
end
......@@ -261,7 +265,7 @@ module Pod
it 'stores the targets created by the analyzer' do
@installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods']
@installer.pod_targets.map(&:name).sort.should == ['Pods-JSONKit']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end
it 'configures the analyzer to use update mode if appropriate' do
......@@ -269,7 +273,7 @@ module Pod
Installer::Analyzer.any_instance.expects(:update=).with(true)
@installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods']
@installer.pod_targets.map(&:name).sort.should == ['Pods-JSONKit']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end
end
......@@ -302,7 +306,7 @@ module Pod
@analysis_result = Installer::Analyzer::AnalysisResult.new
@analysis_result.specifications = []
@analysis_result.sandbox_state = Installer::Analyzer::SpecsState.new
@pod_targets = [PodTarget.new([], nil, config.sandbox)]
@pod_targets = [PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)]
@installer.stubs(:analysis_result).returns(@analysis_result)
@installer.stubs(:pod_targets).returns(@pod_targets)
end
......@@ -360,7 +364,7 @@ module Pod
it 'correctly configures the Pod source installer' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
pod_target = PodTarget.new([spec], nil, config.sandbox)
pod_target = PodTarget.new([spec], [stub('TargetDefinition')], config.sandbox)
pod_target.stubs(:platform).returns(:ios)
@installer.stubs(:pod_targets).returns([pod_target])
@installer.instance_variable_set(:@installed_specs, [])
......@@ -370,7 +374,7 @@ module Pod
it 'maintains the list of the installed specs' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
pod_target = PodTarget.new([spec], nil, config.sandbox)
pod_target = PodTarget.new([spec], [stub('TargetDefinition')], config.sandbox)
pod_target.stubs(:platform).returns(:ios)
@installer.stubs(:pod_targets).returns([pod_target, pod_target])
@installer.instance_variable_set(:@installed_specs, [])
......@@ -459,8 +463,8 @@ module Pod
end
it 'sets the deployment target for the whole project' do
pod_target_ios = PodTarget.new([], nil, config.sandbox)
pod_target_osx = PodTarget.new([], nil, config.sandbox)
pod_target_ios = PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)
pod_target_osx = PodTarget.new([stub('Spec')], [stub('TargetDefinition')], config.sandbox)
pod_target_ios.stubs(:platform).returns(Platform.new(:ios, '6.0'))
pod_target_osx.stubs(:platform).returns(Platform.new(:osx, '10.8'))
aggregate_target_ios = AggregateTarget.new(nil, config.sandbox)
......@@ -495,7 +499,7 @@ module Pod
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil)
target_definition.store_pod('BananaLib')
pod_target = PodTarget.new([spec], target_definition, config.sandbox)
pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:pod_targets).returns([pod_target])
Installer::PodTargetInstaller.any_instance.expects(:install!)
......@@ -505,7 +509,7 @@ module Pod
it 'skips empty pod targets' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil)
pod_target = PodTarget.new([spec], target_definition, config.sandbox)
pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:pod_targets).returns([pod_target])
Installer::PodTargetInstaller.any_instance.expects(:install!).never
......@@ -540,7 +544,7 @@ module Pod
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, @installer.podfile)
@pod_target = PodTarget.new([spec], target_definition, config.sandbox)
@pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@target = AggregateTarget.new(target_definition, config.sandbox)
@mock_target = mock('PodNativeTarget')
......@@ -615,15 +619,14 @@ module Pod
it 'shares schemes of development pods' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, @installer.podfile)
pod_target = PodTarget.new([spec], target_definition, config.sandbox)
pod_target = fixture_pod_target(spec)
@installer.pods_project.stubs(:targets).returns([pod_target])
@installer.stubs(:pod_targets).returns([pod_target])
@installer.sandbox.stubs(:development_pods).returns('BananaLib' => nil)
Xcodeproj::XCScheme.expects(:share_scheme).with(
@installer.pods_project.path,
'Pods-default-BananaLib')
'BananaLib')
@installer.send(:share_development_pod_schemes)
end
......
......@@ -13,6 +13,10 @@ module Pod
@target.target_definition.should == @target_definition
end
it 'is initialized with empty archs' do
@target.archs.should == []
end
it 'returns the label of the target definition' do
@target.label.should == 'Pods'
end
......@@ -80,7 +84,7 @@ module Pod
end
it 'returns the path for the CONFIGURATION_BUILD_DIR build setting' do
@target.configuration_build_dir.should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods'
@target.scoped_configuration_build_dir.should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods'
end
end
......@@ -88,7 +92,7 @@ module Pod
before do
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@target_definition = Podfile::TargetDefinition.new('Pods', nil)
@pod_target = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@target = AggregateTarget.new(@target_definition, config.sandbox)
@target.stubs(:platform).returns(:ios)
@target.pod_targets = [@pod_target]
......@@ -96,9 +100,9 @@ module Pod
describe 'with configuration dependent pod targets' do
before do
@pod_target_release = PodTarget.new([@spec], @target_definition, config.sandbox)
@pod_target_release.expects(:include_in_build_config?).with('Debug').returns(false)
@pod_target_release.expects(:include_in_build_config?).with('Release').returns(true)
@pod_target_release = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target_release.expects(:include_in_build_config?).with(@target_definition, 'Debug').returns(false)
@pod_target_release.expects(:include_in_build_config?).with(@target_definition, 'Release').returns(true)
@target.pod_targets = [@pod_target, @pod_target_release]
@target.user_build_configurations = {
'Debug' => :debug,
......@@ -137,7 +141,7 @@ module Pod
describe 'With libraries' do
before do
@pod_target = fixture_pod_target('banana-lib/BananaLib.podspec')
@target = AggregateTarget.new(@pod_target.target_definition, config.sandbox)
@target = AggregateTarget.new(@pod_target.target_definitions.first, config.sandbox)
@target.pod_targets = [@pod_target]
end
......@@ -196,8 +200,8 @@ module Pod
describe 'With frameworks' do
before do
@pod_target = fixture_pod_target('orange-framework/OrangeFramework.podspec', :ios, Podfile::TargetDefinition.new('iOS Example', nil))
@target = AggregateTarget.new(@pod_target.target_definition, config.sandbox)
@pod_target = fixture_pod_target('orange-framework/OrangeFramework.podspec', fixture_target_definition('iOS Example'))
@target = AggregateTarget.new(@pod_target.target_definitions.first, config.sandbox)
@target.stubs(:requires_frameworks?).returns(true)
@target.pod_targets = [@pod_target]
end
......
......@@ -5,21 +5,42 @@ module Pod
before do
spec = fixture_spec('banana-lib/BananaLib.podspec')
@target_definition = Podfile::TargetDefinition.new('Pods', nil)
@pod_target = PodTarget.new([spec], @target_definition, config.sandbox)
@pod_target = PodTarget.new([spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(:ios)
end
describe 'Meta' do
describe '#scoped' do
it 'returns target copies per target definition, which are scoped' do
@pod_target.should.not.be.scoped
@pod_target.scoped.first.should.be.scoped
@pod_target.should.not.be.scoped
end
end
end
describe 'In general' do
it 'returns the target_definition that generated it' do
@pod_target.target_definition.should == @target_definition
it 'returns the target definitions' do
@pod_target.target_definitions.should == [@target_definition]
end
it 'is initialized with empty archs' do
@pod_target.archs.should == []
end
it 'returns its name' do
@pod_target.name.should == 'Pods-BananaLib'
@pod_target.name.should == 'BananaLib'
@pod_target.scoped.first.name.should == 'Pods-BananaLib'
end
it 'returns its label' do
@pod_target.label.should == 'BananaLib'
@pod_target.scoped.first.label.should == 'Pods-BananaLib'
end
it 'returns the name of its product' do
@pod_target.product_name.should == 'libPods-BananaLib.a'
@pod_target.product_name.should == 'libBananaLib.a'
@pod_target.scoped.first.product_name.should == 'libPods-BananaLib.a'
end
it 'returns the spec consumers for the pod targets' do
......@@ -35,7 +56,8 @@ module Pod
end
it 'returns the name of the resources bundle target' do
@pod_target.resources_bundle_target_label('Fruits').should == 'Pods-BananaLib-Fruits'
@pod_target.resources_bundle_target_label('Fruits').should == 'BananaLib-Fruits'
@pod_target.scoped.first.resources_bundle_target_label('Fruits').should == 'Pods-BananaLib-Fruits'
end
it 'returns the name of the Pods on which this target depends' do
......@@ -45,13 +67,13 @@ module Pod
it 'returns whether it is whitelisted in a build configuration' do
@target_definition.store_pod('BananaLib')
@target_definition.whitelist_pod_for_configuration('BananaLib', 'debug')
@pod_target.include_in_build_config?('Debug').should.be.true
@pod_target.include_in_build_config?('Release').should.be.false
@pod_target.include_in_build_config?(@target_definition, 'Debug').should.be.true
@pod_target.include_in_build_config?(@target_definition, 'Release').should.be.false
end
it 'is whitelisted on all build configurations of it is a dependency of other Pods' do
@pod_target.include_in_build_config?('Debug').should.be.true
@pod_target.include_in_build_config?('Release').should.be.true
@pod_target.include_in_build_config?(@target_definition, 'Debug').should.be.true
@pod_target.include_in_build_config?(@target_definition, 'Release').should.be.true
end
it 'raises if a Pod is whitelisted for different build configurations' do
......@@ -59,7 +81,7 @@ module Pod
@target_definition.store_pod('BananaLib/Subspec')
@target_definition.whitelist_pod_for_configuration('BananaLib', 'debug')
message = should.raise Informative do
@pod_target.include_in_build_config?('release').should.be.true
@pod_target.include_in_build_config?(@target_definition, 'release').should.be.true
end.message
message.should.match /subspecs across different build configurations/
end
......@@ -84,45 +106,67 @@ module Pod
describe 'Support files' do
it 'returns the absolute path of the xcconfig file' do
@pod_target.xcconfig_path('Release').to_s.should.include?(
'Pods/Target Support Files/BananaLib/BananaLib.release.xcconfig',
)
@pod_target.scoped.first.xcconfig_path('Release').to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib.release.xcconfig',
)
end
it 'escapes the file separators in variant build configuration name in the xcconfig file' do
@pod_target.xcconfig_path("Release#{File::SEPARATOR}1").to_s.should.include?(
'Pods/Target Support Files/BananaLib/BananaLib.release-1.xcconfig',
)
@pod_target.scoped.first.xcconfig_path("Release#{File::SEPARATOR}1").to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib.release-1.xcconfig',
)
end
it 'returns the absolute path of the prefix header file' do
@pod_target.prefix_header_path.to_s.should.include?(
'Pods/Target Support Files/BananaLib/BananaLib-prefix.pch',
)
@pod_target.scoped.first.prefix_header_path.to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib-prefix.pch',
)
end
it 'returns the absolute path of the bridge support file' do
@pod_target.bridge_support_path.to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib.bridgesupport',
'Pods/Target Support Files/BananaLib/BananaLib.bridgesupport',
)
end
it 'returns the absolute path of the info plist file' do
@pod_target.info_plist_path.to_s.should.include?(
'Pods/Target Support Files/BananaLib/Info.plist',
)
@pod_target.scoped.first.info_plist_path.to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Info.plist',
)
end
it 'returns the absolute path of the dummy source file' do
@pod_target.dummy_source_path.to_s.should.include?(
'Pods/Target Support Files/BananaLib/BananaLib-dummy.m',
)
@pod_target.scoped.first.dummy_source_path.to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib-dummy.m',
)
end
it 'returns the absolute path of the public and private xcconfig files' do
@pod_target.xcconfig_path.to_s.should.include?(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib.xcconfig',
'Pods/Target Support Files/BananaLib/BananaLib.xcconfig',
)
@pod_target.xcconfig_private_path.to_s.should.include(
'Pods/Target Support Files/Pods-BananaLib/Pods-BananaLib-Private.xcconfig',
'Pods/Target Support Files/BananaLib/BananaLib-Private.xcconfig',
)
end
it 'returns the path for the CONFIGURATION_BUILD_DIR build setting' do
@pod_target.configuration_build_dir.should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods'
@pod_target.configuration_build_dir.should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
@pod_target.scoped.first.configuration_build_dir.should == '$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods'
end
end
......@@ -150,7 +194,8 @@ module Pod
end
it 'returns the library name' do
@pod_target.static_library_name.should == 'libPods-BananaLib.a'
@pod_target.static_library_name.should == 'libBananaLib.a'
@pod_target.scoped.first.static_library_name.should == 'libPods-BananaLib.a'
end
it 'returns :framework as product type' do
......@@ -164,7 +209,8 @@ module Pod
describe 'Host does not requires frameworks' do
it 'returns the product name' do
@pod_target.product_name.should == 'libPods-BananaLib.a'
@pod_target.product_name.should == 'libBananaLib.a'
@pod_target.scoped.first.product_name.should == 'libPods-BananaLib.a'
end
it 'returns the framework name' do
......@@ -172,7 +218,8 @@ module Pod
end
it 'returns the library name' do
@pod_target.static_library_name.should == 'libPods-BananaLib.a'
@pod_target.static_library_name.should == 'libBananaLib.a'
@pod_target.scoped.first.static_library_name.should == 'libPods-BananaLib.a'
end
it 'returns :static_library as product type' do
......@@ -208,7 +255,8 @@ module Pod
end
it 'returns the library name' do
@pod_target.static_library_name.should == 'libPods-OrangeFramework.a'
@pod_target.static_library_name.should == 'libOrangeFramework.a'
@pod_target.scoped.first.static_library_name.should == 'libPods-OrangeFramework.a'
end
it 'returns :framework as product type' do
......
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