Unverified Commit 93011ece authored by Samuel Giddins's avatar Samuel Giddins Committed by GitHub

Merge pull request #7449 from CocoaPods/seg-more-perf

More performance improvements
parents 2619458c bb81dffc
......@@ -140,8 +140,7 @@ module Pod
#
def self.links_dependency?(aggregate_target, pod_target)
return true if aggregate_target.nil? || aggregate_target.target_definition.inheritance == 'complete'
targets = aggregate_target.pod_targets - aggregate_target.search_paths_aggregate_targets.flat_map(&:pod_targets)
targets.include?(pod_target)
aggregate_target.pod_targets_to_link.include?(pod_target)
end
# Adds build settings for dynamic vendored frameworks and libraries.
......
......@@ -429,7 +429,7 @@ module Pod
end
def print_post_install_message
podfile_dependencies = podfile.dependencies.uniq.size
podfile_dependencies = analysis_result.podfile_dependency_cache.podfile_dependencies.size
pods_installed = root_specs.size
title_options = { :verbose_prefix => '-> '.green }
UI.titled_section('Pod installation complete! ' \
......@@ -548,7 +548,7 @@ module Pod
# @return [void]
#
def write_lockfiles
external_source_pods = podfile.dependencies.select(&:external_source).map(&:root_name).uniq
external_source_pods = analysis_result.podfile_dependency_cache.podfile_dependencies.select(&:external_source).map(&:root_name).uniq
checkout_options = sandbox.checkout_sources.select { |root_name, _| external_source_pods.include? root_name }
@lockfile = Lockfile.generate(podfile, analysis_result.specifications, checkout_options, analysis_result.specs_by_source)
......
......@@ -10,11 +10,12 @@ module Pod
delegate_installation_options { podfile }
autoload :AnalysisResult, 'cocoapods/installer/analyzer/analysis_result'
autoload :SandboxAnalyzer, 'cocoapods/installer/analyzer/sandbox_analyzer'
autoload :SpecsState, 'cocoapods/installer/analyzer/specs_state'
autoload :LockingDependencyAnalyzer, 'cocoapods/installer/analyzer/locking_dependency_analyzer'
autoload :PodfileDependencyCache, 'cocoapods/installer/analyzer/podfile_dependency_cache'
autoload :PodVariant, 'cocoapods/installer/analyzer/pod_variant'
autoload :PodVariantSet, 'cocoapods/installer/analyzer/pod_variant_set'
autoload :SandboxAnalyzer, 'cocoapods/installer/analyzer/sandbox_analyzer'
autoload :SpecsState, 'cocoapods/installer/analyzer/specs_state'
autoload :TargetInspectionResult, 'cocoapods/installer/analyzer/target_inspection_result'
autoload :TargetInspector, 'cocoapods/installer/analyzer/target_inspector'
......@@ -54,6 +55,7 @@ module Pod
@has_dependencies = true
@test_pod_target_analyzer_cache = {}
@test_pod_target_key = Struct.new(:name, :pod_targets)
@podfile_dependency_cache = PodfileDependencyCache.from_podfile(podfile)
end
# Performs the analysis.
......@@ -71,6 +73,7 @@ module Pod
validate_podfile!
validate_lockfile_version!
@result = AnalysisResult.new
@result.podfile_dependency_cache = @podfile_dependency_cache
if installation_options.integrate_targets?
@result.target_inspections = inspect_targets_to_integrate
else
......@@ -186,7 +189,7 @@ module Pod
alias_method :specs_updated?, :specs_updated
def validate_podfile!
validator = Installer::PodfileValidator.new(podfile)
validator = Installer::PodfileValidator.new(podfile, @podfile_dependency_cache)
validator.validate
unless validator.valid?
......@@ -234,7 +237,7 @@ module Pod
pods_state
else
state = SpecsState.new
state.added.merge(podfile.dependencies.map(&:root_name))
state.added.merge(@podfile_dependency_cache.podfile_dependencies.map(&:root_name))
state
end
end
......@@ -395,8 +398,7 @@ module Pod
embedded_targets = aggregate_targets.select(&:requires_host_target?)
analyze_host_targets_in_podfile(aggregate_targets, embedded_targets)
use_frameworks_embedded_targets = embedded_targets.select(&:requires_frameworks?)
non_use_frameworks_embedded_targets = embedded_targets.reject(&:requires_frameworks?)
use_frameworks_embedded_targets, non_use_frameworks_embedded_targets = embedded_targets.partition(&:requires_frameworks?)
aggregate_targets.each do |target|
# For targets that require frameworks, we always have to copy their pods to their
# host targets because those frameworks will all be loaded from the host target's bundle
......@@ -408,9 +410,9 @@ module Pod
end
end
aggregate_targets.each do |target|
target.search_paths_aggregate_targets = aggregate_targets.select do |aggregate_target|
target.search_paths_aggregate_targets.concat(aggregate_targets.select do |aggregate_target|
target.target_definition.targets_to_inherit_search_paths.include?(aggregate_target.target_definition)
end
end).freeze
end
end
......@@ -634,7 +636,7 @@ module Pod
else
pods_to_update = result.podfile_state.changed + result.podfile_state.deleted
pods_to_update += update[:pods] if update_mode == :selected
local_pod_names = podfile.dependencies.select(&:local?).map(&:root_name)
local_pod_names = @podfile_dependency_cache.podfile_dependencies.select(&:local?).map(&:root_name)
pods_to_unlock = local_pod_names.reject do |pod_name|
sandbox.specification(pod_name).checksum == lockfile.checksum(pod_name)
end
......@@ -675,7 +677,7 @@ module Pod
end
def verify_no_pods_with_different_sources!
deps_with_different_sources = podfile.dependencies.group_by(&:root_name).
deps_with_different_sources = @podfile_dependency_cache.podfile_dependencies.group_by(&:root_name).
select { |_root_name, dependencies| dependencies.map(&:external_source).uniq.count > 1 }
deps_with_different_sources.each do |root_name, dependencies|
raise Informative, 'There are multiple dependencies with different ' \
......@@ -698,7 +700,7 @@ module Pod
def dependencies_to_fetch
@deps_to_fetch ||= begin
deps_to_fetch = []
deps_with_external_source = podfile.dependencies.select(&:external_source)
deps_with_external_source = @podfile_dependency_cache.podfile_dependencies.select(&:external_source)
if update_mode == :all
deps_to_fetch = deps_with_external_source
......@@ -731,7 +733,7 @@ module Pod
elsif update_mode == :all
pods_to_fetch += result.podfile_state.unchanged + result.podfile_state.deleted
end
pods_to_fetch += podfile.dependencies.
pods_to_fetch += @podfile_dependency_cache.podfile_dependencies.
select { |dep| Hash(dep.external_source).key?(:podspec) && sandbox.specification_path(dep.root_name).nil? }.
map(&:root_name)
pods_to_fetch
......@@ -739,7 +741,7 @@ module Pod
end
def store_existing_checkout_options
podfile.dependencies.select(&:external_source).each do |dep|
@podfile_dependency_cache.podfile_dependencies.select(&:external_source).each do |dep|
if checkout_options = lockfile && lockfile.checkout_options_for_pod_named(dep.root_name)
sandbox.store_checkout_source(dep.root_name, checkout_options)
end
......@@ -766,7 +768,7 @@ module Pod
# grouped by target.
#
def resolve_dependencies
duplicate_dependencies = podfile.dependencies.group_by(&:name).
duplicate_dependencies = @podfile_dependency_cache.podfile_dependencies.group_by(&:name).
select { |_name, dependencies| dependencies.count > 1 }
duplicate_dependencies.each do |name, dependencies|
UI.warn "There are duplicate dependencies on `#{name}` in #{UI.path podfile.defined_in_file}:\n\n" \
......@@ -857,8 +859,8 @@ module Pod
plugin_sources = @plugin_sources || []
# Add any sources specified using the :source flag on individual dependencies.
dependency_sources = podfile.dependencies.map(&:podspec_repo).compact
all_dependencies_have_sources = dependency_sources.count == podfile.dependencies.count
dependency_sources = @podfile_dependency_cache.podfile_dependencies.map(&:podspec_repo).compact
all_dependencies_have_sources = dependency_sources.count == @podfile_dependency_cache.podfile_dependencies.count
if all_dependencies_have_sources
sources = dependency_sources
......@@ -890,7 +892,7 @@ module Pod
#
def verify_platforms_specified!
unless installation_options.integrate_targets?
podfile.target_definition_list.each do |target_definition|
@podfile_dependency_cache.target_definition_list.each do |target_definition|
if !target_definition.empty? && target_definition.platform.nil?
raise Informative, 'It is necessary to specify the platform in the Podfile if not integrating.'
end
......@@ -909,7 +911,7 @@ module Pod
def inspect_targets_to_integrate
inspection_result = {}
UI.section 'Inspecting targets to integrate' do
inspectors = podfile.target_definition_list.map do |target_definition|
inspectors = @podfile_dependency_cache.target_definition_list.map do |target_definition|
next if target_definition.abstract?
TargetInspector.new(target_definition, config.installation_root)
end.compact
......
......@@ -33,8 +33,14 @@ module Pod
# @return [Hash{TargetDefinition => Array<TargetInspectionResult>}] the
# results of inspecting the user targets
#
attr_accessor :target_inspections
# @return [PodfileDependencyCache] the cache of all dependencies in the
# podfile.
#
attr_accessor :podfile_dependency_cache
# @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
......
module Pod
class Installer
class Analyzer
# Caches podfile & target definition dependencies, so they do not need to be re-computed
# from the internal hash on each access
#
class PodfileDependencyCache
# @return [Array<Pod::Dependency>]
# All the dependencies in the podfile
#
attr_reader :podfile_dependencies
def initialize(podfile_dependencies, dependencies_by_target_definition)
@podfile_dependencies = podfile_dependencies
@dependencies_by_target_definition = dependencies_by_target_definition
end
# Returns the dependencies for the given target definition
#
def target_definition_dependencies(target_definition)
@dependencies_by_target_definition[target_definition] ||
raise(ArgumentError, "dependencies for #{target_definition.inspect} do not exist in the cache")
end
# Returns a list of all of the target definitions in the Podfile
#
def target_definition_list
@dependencies_by_target_definition.keys
end
# Creates a {PodfileDependencyCache} from the given {Podfile}
#
def self.from_podfile(podfile)
podfile_dependencies = []
dependencies_by_target_definition = {}
podfile.target_definition_list.each do |target_definition|
deps = target_definition.dependencies.freeze
podfile_dependencies.concat deps
dependencies_by_target_definition[target_definition] = deps
end
podfile_dependencies.uniq!
new(podfile_dependencies.freeze, dependencies_by_target_definition.freeze)
end
end
end
end
end
......@@ -20,8 +20,9 @@ module Pod
# @param [Podfile] podfile
# The podfile to validate
#
def initialize(podfile)
def initialize(podfile, podfile_dependency_cache = Analyzer::PodfileDependencyCache.from_podfile(podfile))
@podfile = podfile
@podfile_dependency_cache = podfile_dependency_cache
@errors = []
@warnings = []
@validated = false
......@@ -67,11 +68,7 @@ module Pod
end
def validate_pod_directives
dependencies = podfile.target_definitions.flat_map do |_, target|
target.dependencies
end.uniq
dependencies.each do |dependency|
@podfile_dependency_cache.podfile_dependencies.each do |dependency|
validate_conflicting_external_sources!(dependency)
end
end
......@@ -106,7 +103,7 @@ module Pod
# @return [void]
#
def validate_dependencies_are_present!
if podfile.target_definitions.values.all?(&:empty?)
if @podfile_dependency_cache.target_definition_list.all?(&:empty?)
add_warning 'The Podfile does not contain any dependencies.'
end
end
......@@ -116,8 +113,8 @@ module Pod
# target, or be inherited by a target where `inheritance == complete`.
#
def validate_no_abstract_only_pods!
all_dependencies = podfile.dependencies
concrete_dependencies = podfile.target_definition_list.reject(&:abstract?).flat_map(&:dependencies).uniq
all_dependencies = @podfile_dependency_cache.podfile_dependencies
concrete_dependencies = @podfile_dependency_cache.target_definition_list.reject(&:abstract?).flat_map { |td| @podfile_dependency_cache.target_definition_dependencies(td) }
abstract_only_dependencies = all_dependencies - concrete_dependencies
abstract_only_dependencies.each do |dep|
add_error "The dependency `#{dep}` is not used in any concrete target."
......@@ -125,7 +122,7 @@ module Pod
end
def validate_no_duplicate_targets!
podfile.target_definition_list.group_by { |td| [td.name, td.user_project_path] }.
@podfile_dependency_cache.target_definition_list.group_by { |td| [td.name, td.user_project_path] }.
each do |(name, project), definitions|
next unless definitions.size > 1
error = "The target `#{name}` is declared twice"
......
......@@ -40,6 +40,15 @@ module Pod
#
attr_reader :development_pods
# Overridden to generate UUIDs in a much faster way, since we don't need to check for collisions
# (as the Pods project is regenerated each time, and thus all UUIDs will have come from this method)
def generate_available_uuid_list(count = 100)
start = @generated_uuids.size
uniques = Array.new(count) { |i| format('%011X0', start + i) }
@generated_uuids += uniques
@available_uuids += uniques
end
public
# @!group Legacy Xcode build root
......
......@@ -85,9 +85,11 @@ module Pod
# @param [Array<Dependency>] locked_dependencies @see locked_dependencies
# @param [Array<Source>, Source] sources @see sources
#
def initialize(sandbox, podfile, locked_dependencies, sources)
def initialize(sandbox, podfile, locked_dependencies, sources,
podfile_dependency_cache: Installer::Analyzer::PodfileDependencyCache.from_podfile(podfile))
@sandbox = sandbox
@podfile = podfile
@podfile_dependency_cache = podfile_dependency_cache
@locked_dependencies = locked_dependencies
@sources = Array(sources)
@platforms_by_dependency = Hash.new { |h, k| h[k] = [] }
......@@ -107,11 +109,13 @@ module Pod
# definition.
#
def resolve
dependencies = podfile.target_definition_list.flat_map do |target|
target.dependencies.each do |dep|
@platforms_by_dependency[dep].push(target.platform).uniq! if target.platform
dependencies = @podfile_dependency_cache.target_definition_list.flat_map do |target|
@podfile_dependency_cache.target_definition_dependencies(target).each do |dep|
next unless target.platform
@platforms_by_dependency[dep].push(target.platform)
end
end
@platforms_by_dependency.each_value(&:uniq!)
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
resolver_specs_by_target
rescue Molinillo::ResolverError => e
......@@ -125,9 +129,9 @@ module Pod
#
def resolver_specs_by_target
@resolver_specs_by_target ||= {}.tap do |resolver_specs_by_target|
podfile.target_definition_list.each do |target|
dependencies = {}
specs = target.dependencies.flat_map do |dep|
dependencies = {}
@podfile_dependency_cache.target_definition_list.each do |target|
specs = @podfile_dependency_cache.target_definition_dependencies(target).flat_map do |dep|
name = dep.name
node = @activated.vertex_named(name)
(valid_dependencies_for_target_from_node(target, dependencies, node) << node).map { |s| [s, node.payload.test_specification?] }
......@@ -559,11 +563,11 @@ module Pod
# dependencies for `target`.
#
def valid_dependencies_for_target_from_node(target, dependencies, node)
dependencies[node.name] ||= begin
dependencies[[node.name, target.platform]] ||= begin
validate_platform(node.payload, target)
dependency_nodes = []
node.outgoing_edges.each do |edge|
next unless edge_is_valid_for_target?(edge, target)
next unless edge_is_valid_for_target_platform?(edge, target.platform)
dependency_nodes << edge.destination
end
......@@ -574,14 +578,14 @@ module Pod
end
# Whether the given `edge` should be followed to find dependencies for the
# given `target`.
# given `target_platform`.
#
# @return [Bool]
#
def edge_is_valid_for_target?(edge, target)
def edge_is_valid_for_target_platform?(edge, target_platform)
requirement_name = edge.requirement.name
edge.origin.payload.all_dependencies(target.platform).any? do |dep|
edge.origin.payload.all_dependencies(target_platform).any? do |dep|
dep.name == requirement_name
end
end
......
......@@ -140,7 +140,7 @@ module Pod
# @return [Array<AggregateTarget>] The aggregate targets whose pods this
# target must be able to import, but will not directly link against.
#
attr_accessor :search_paths_aggregate_targets
attr_reader :search_paths_aggregate_targets
# @param [String] build_configuration The build configuration for which the
# the pod targets should be returned.
......@@ -149,11 +149,16 @@ module Pod
# configuration.
#
def pod_targets_for_build_configuration(build_configuration)
pod_targets.select do |pod_target|
@pod_targets_for_build_configuration ||= {}
@pod_targets_for_build_configuration[build_configuration] ||= pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, build_configuration)
end
end
def pod_targets_to_link
@pod_targets_to_link ||= pod_targets.to_set - search_paths_aggregate_targets.flat_map(&:pod_targets)
end
# @return [Array<Specification>] The specifications used by this aggregate target.
#
def specs
......@@ -191,9 +196,7 @@ module Pod
@framework_paths_by_config ||= begin
framework_paths_by_config = {}
user_build_configurations.keys.each do |config|
relevant_pod_targets = pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config)
end
relevant_pod_targets = pod_targets_for_build_configuration(config)
framework_paths_by_config[config] = relevant_pod_targets.flat_map { |pt| pt.framework_paths(false) }
end
framework_paths_by_config
......@@ -208,8 +211,7 @@ module Pod
pod_target.should_build? && pod_target.requires_frameworks? && !pod_target.static_framework?
end
user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
resources_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
next [] unless pod_target.include_in_build_config?(target_definition, config)
resources_by_config[config] = (relevant_pod_targets & pod_targets_for_build_configuration(config)).flat_map do |pod_target|
(pod_target.resource_paths(false) + [bridge_support_file].compact).uniq
end
end
......
......@@ -522,10 +522,8 @@ module Pod
if whitelists.empty?
@build_config_cache[key] = true
true
elsif whitelists.count == 1
@build_config_cache[key] = whitelists.first
whitelists.first
else
raise Informative, "The subspecs of `#{pod_name}` are linked to " \
"different build configurations for the `#{target_definition}` " \
......
......@@ -497,7 +497,7 @@ module Pod
it 'should include inherited search paths' do
# It's the responsibility of the analyzer to
# populate this when the file is loaded.
@blank_target.search_paths_aggregate_targets = [@target]
@blank_target.search_paths_aggregate_targets.replace [@target]
@xcconfig = @generator.generate
@xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.not.be.nil
end
......
......@@ -12,8 +12,8 @@ module Pod
describe '::default_ld_flags' do
it 'returns the default linker flags' do
podfile = stub(:set_arc_compatibility_flag? => false)
target = stub(:podfile => podfile)
podfile = stub('podfile', :set_arc_compatibility_flag? => false)
target = stub('target', :podfile => podfile)
result = @sut.default_ld_flags(target)
result.should == ''
......@@ -22,9 +22,9 @@ module Pod
end
it 'includes the ARC compatibility flag if required by the Podfile' do
podfile = stub(:set_arc_compatibility_flag? => true)
spec_consumer = stub(:requires_arc? => true)
target = stub(:podfile => podfile, :spec_consumers => [spec_consumer])
podfile = stub('podfile', :set_arc_compatibility_flag? => true)
spec_consumer = stub('spec_consumer', :requires_arc? => true)
target = stub('target', :podfile => podfile, :spec_consumers => [spec_consumer])
result = @sut.default_ld_flags(target)
result.should == '-fobjc-arc'
......@@ -52,107 +52,109 @@ module Pod
describe '::add_spec_build_settings_to_xcconfig' do
it 'adds the libraries of the xcconfig' do
xcconfig = Xcodeproj::Config.new
consumer = stub(
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
@sut.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-l"xml2"'
end
it 'check that subspec subsets are removed from frameworks search paths' do
target1 = stub(
:specs => %w(A, B),
:should_build? => true,
:requires_frameworks? => true,
:configuration_build_dir => 'AB',
)
target2 = stub(
:specs => ['B'],
:should_build? => true,
:requires_frameworks? => true,
:configuration_build_dir => 'B',
)
target1 = stub('target1',
:specs => %w(A, B),
:should_build? => true,
:requires_frameworks? => true,
:configuration_build_dir => 'AB',
)
target2 = stub('target2',
:specs => ['B'],
:should_build? => true,
:requires_frameworks? => true,
:configuration_build_dir => 'B',
)
dependent_targets = [target1, target2]
build_settings = @sut.search_paths_for_dependent_targets(nil, dependent_targets)
build_settings['FRAMEWORK_SEARCH_PATHS'].should == '"AB"'
end
it 'adds the libraries of the xcconfig for a static framework' do
spec = stub(:test_specification? => false)
target_definition = stub(:inheritance => 'search_paths')
consumer = stub(
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [],
:vendored_dynamic_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub(
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => true,
:requires_frameworks? => true,
:static_framework? => true,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
spec = stub('spec', :test_specification? => false)
target_definition = stub('target_definition', :inheritance => 'search_paths')
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [],
:vendored_dynamic_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub('pod_target',
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => true,
:requires_frameworks? => true,
:static_framework? => true,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
pod_targets = [pod_target]
aggregate_target = stub(
:target_definition => target_definition,
:pod_targets => pod_targets,
:search_paths_aggregate_targets => [],
)
aggregate_target = stub('aggregate_target',
:target_definition => target_definition,
:pod_targets => pod_targets,
:search_paths_aggregate_targets => [],
:pod_targets_to_link => pod_targets,
)
xcconfig = Xcodeproj::Config.new
@sut.generate_vendored_build_settings(aggregate_target, pod_targets, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-l"xml2"'
end
it 'checks OTHER_LDFLAGS and FRAMEWORK_SEARCH_PATHS for a vendored dependencies to a static framework' do
spec = stub(:test_specification? => false)
target_definition = stub(:inheritance => 'search_paths')
consumer = stub(
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
dep_target = stub(
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => false,
:requires_frameworks? => true,
:static_framework? => false,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
spec = stub('spec', :test_specification? => false)
target_definition = stub('target_definition', :inheritance => 'search_paths')
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
dep_target = stub('dep_target',
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => false,
:requires_frameworks? => true,
:static_framework? => false,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
dep_targets = [dep_target]
target = stub(
:target_definition => target_definition,
:pod_targets => dep_targets,
:search_paths_aggregate_targets => [],
:static_framework => true,
)
target = stub('target',
:target_definition => target_definition,
:pod_targets => dep_targets,
:search_paths_aggregate_targets => [],
:static_framework => true,
:pod_targets_to_link => dep_targets,
)
xcconfig = Xcodeproj::Config.new
@sut.generate_vendored_build_settings(target, dep_targets, xcconfig, true)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-l"StaticLibrary" -l"VendoredDyld" -l"xml2" -framework "StaticFramework" -framework "VendoredFramework"'
......@@ -172,38 +174,38 @@ module Pod
end
it 'check that include_ld_flags being false doesnt generate OTHER_LDFLAGS' do
spec = stub(:test_specification? => false)
target_definition = stub(:inheritance => 'search_paths')
consumer = stub(
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
dep_target = stub(
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => false,
:requires_frameworks? => true,
:static_framework? => false,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
spec = stub('spec', :test_specification? => false)
target_definition = stub('target_definition', :inheritance => 'search_paths')
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => [],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
dep_target = stub('dep_target',
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => false,
:requires_frameworks? => true,
:static_framework? => false,
:dependent_targets => [],
:file_accessors => [file_accessor],
)
dep_targets = [dep_target]
target = stub(
:target_definition => target_definition,
:pod_targets => dep_targets,
:search_paths_aggregate_targets => [],
)
target = stub('target',
:target_definition => target_definition,
:pod_targets => dep_targets,
:search_paths_aggregate_targets => [],
)
xcconfig = Xcodeproj::Config.new
@sut.generate_vendored_build_settings(target, dep_targets, xcconfig, false)
xcconfig.to_hash['OTHER_LDFLAGS'].should.nil?
......@@ -211,42 +213,42 @@ module Pod
end
it 'makes sure setting from search_paths get propagated for static frameworks' do
target_definition = stub(:inheritance => 'search_paths')
consumer = stub(
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => ['Foo'],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub(
:spec_consumer => consumer,
:vendored_static_frameworks => [],
:vendored_dynamic_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub(
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => true,
:requires_frameworks? => true,
:static_framework? => true,
:dependent_targets => [],
:file_accessors => [file_accessor],
:product_basename => 'Foo',
)
target_definition = stub('target_definition', :inheritance => 'search_paths')
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => ['xml2'],
:frameworks => ['Foo'],
:weak_frameworks => [],
:platform_name => :ios,
)
file_accessor = stub('file_accessor',
:spec_consumer => consumer,
:vendored_static_frameworks => [],
:vendored_dynamic_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub('pod_target',
:name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => true,
:requires_frameworks? => true,
:static_framework? => true,
:dependent_targets => [],
:file_accessors => [file_accessor],
:product_basename => 'Foo',
)
pod_targets = [pod_target]
aggregate_target = stub(
:target_definition => target_definition,
:pod_targets => pod_targets,
:search_paths_aggregate_targets => [],
)
test_aggregate_target = stub(
:target_definition => target_definition,
:pod_targets => [],
:search_paths_aggregate_targets => [aggregate_target],
)
aggregate_target = stub('aggregate_target',
:target_definition => target_definition,
:pod_targets => pod_targets,
:search_paths_aggregate_targets => [],
)
test_aggregate_target = stub('test_aggregate_target',
:target_definition => target_definition,
:pod_targets => [],
:search_paths_aggregate_targets => [aggregate_target],
)
xcconfig = Xcodeproj::Config.new
@sut.generate_other_ld_flags(test_aggregate_target, [], xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-framework "Foo"'
......@@ -254,51 +256,51 @@ module Pod
it 'includes HEADER_SEARCH_PATHS from search paths' do
xcconfig = Xcodeproj::Config.new
spec_consumer = stub(:user_target_xcconfig => { 'HEADER_SEARCH_PATHS' => 'my/path' })
pod_target = stub(:spec_consumers => [spec_consumer])
search_path_target = stub(
:pod_targets_for_build_configuration => [pod_target],
:pod_targets => [pod_target],
)
spec_consumer = stub('spec_consumer', :user_target_xcconfig => { 'HEADER_SEARCH_PATHS' => 'my/path' })
pod_target = stub('pod_target', :spec_consumers => [spec_consumer])
search_path_target = stub('search_path_target',
:pod_targets_for_build_configuration => [pod_target],
:pod_targets => [pod_target],
)
@sut.propagate_header_search_paths_from_search_paths(search_path_target, xcconfig)
xcconfig.to_hash['HEADER_SEARCH_PATHS'].should == '$(inherited) my/path'
end
it 'adds the frameworks of the xcconfig' do
xcconfig = Xcodeproj::Config.new
consumer = stub(
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['CoreAnimation'],
:weak_frameworks => [],
:platform_name => :ios,
)
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['CoreAnimation'],
:weak_frameworks => [],
:platform_name => :ios,
)
@sut.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-framework "CoreAnimation"'
end
it 'adds the weak frameworks of the xcconfig' do
xcconfig = Xcodeproj::Config.new
consumer = stub(
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => [],
:weak_frameworks => ['iAd'],
:platform_name => :ios,
)
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => [],
:weak_frameworks => ['iAd'],
:platform_name => :ios,
)
@sut.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-weak_framework "iAd"'
end
it 'adds the ios developer frameworks search paths if needed' do
xcconfig = Xcodeproj::Config.new
consumer = stub(
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['SenTestingKit'],
:weak_frameworks => [],
:platform_name => :ios,
)
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['SenTestingKit'],
:weak_frameworks => [],
:platform_name => :ios,
)
@sut.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.not.include('SDKROOT')
xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.not.include('DEVELOPER_LIBRARY_DIR')
......@@ -306,13 +308,13 @@ module Pod
it 'adds the osx developer frameworks search paths if needed' do
xcconfig = Xcodeproj::Config.new
consumer = stub(
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['SenTestingKit'],
:weak_frameworks => [],
:platform_name => :osx,
)
consumer = stub('consumer',
:pod_target_xcconfig => {},
:libraries => [],
:frameworks => ['SenTestingKit'],
:weak_frameworks => [],
:platform_name => :osx,
)
@sut.add_spec_build_settings_to_xcconfig(consumer, xcconfig)
xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.not.include('DEVELOPER_LIBRARY_DIR')
xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.not.include('SDKROOT')
......@@ -398,7 +400,7 @@ module Pod
describe '::add_language_specific_settings' do
it 'does not add OTHER_SWIFT_FLAGS to the xcconfig if the target does not use swift' do
target = stub(:uses_swift? => false)
target = stub('target', :uses_swift? => false)
xcconfig = Xcodeproj::Config.new
@sut.add_language_specific_settings(target, xcconfig)
other_swift_flags = xcconfig.to_hash['OTHER_SWIFT_FLAGS']
......@@ -406,7 +408,7 @@ module Pod
end
it 'does not add the -suppress-warnings flag to the xcconfig if the target uses swift, but does not inhibit warnings' do
target = stub(:uses_swift? => true, :inhibit_warnings? => false)
target = stub('target', :uses_swift? => true, :inhibit_warnings? => false)
xcconfig = Xcodeproj::Config.new
@sut.add_language_specific_settings(target, xcconfig)
other_swift_flags = xcconfig.to_hash['OTHER_SWIFT_FLAGS']
......@@ -414,7 +416,7 @@ module Pod
end
it 'adds the -suppress-warnings flag to the xcconfig if the target uses swift and inhibits warnings' do
target = stub(:uses_swift? => true, :inhibit_warnings? => true)
target = stub('target', :uses_swift? => true, :inhibit_warnings? => true)
xcconfig = Xcodeproj::Config.new
@sut.add_language_specific_settings(target, xcconfig)
other_swift_flags = xcconfig.to_hash['OTHER_SWIFT_FLAGS']
......@@ -426,71 +428,71 @@ module Pod
describe 'concerning settings for file accessors' do
it 'does not propagate framework or libraries from a test specification to an aggregate target' do
spec = stub(:test_specification? => true)
consumer = stub(
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub(
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
target_definition = stub(:inheritance => 'complete')
aggregate_target = stub(:target_definition => target_definition)
spec = stub('spec', :test_specification? => true)
consumer = stub('consumer',
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub('pod_target',
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
target_definition = stub('target_definition', :inheritance => 'complete')
aggregate_target = stub('aggregate_target', :target_definition => target_definition)
xcconfig = Xcodeproj::Config.new
@sut.add_settings_for_file_accessors_of_target(aggregate_target, pod_target, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should.be.nil
end
it 'propagates correct frameworks or libraries to both test and non test xcconfigs' do
spec = stub(:test_specification? => false)
consumer = stub(
:libraries => [],
:frameworks => [],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
test_spec = stub(:test_specification? => true)
test_consumer = stub(
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => test_spec,
)
test_file_accessor = stub(
:spec => test_spec,
:spec_consumer => test_consumer,
:vendored_static_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_frameworks => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub(
:file_accessors => [file_accessor, test_file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
spec = stub('spec', :test_specification? => false)
consumer = stub('consumer',
:libraries => [],
:frameworks => [],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
test_spec = stub('test_spec', :test_specification? => true)
test_consumer = stub('test_consumer',
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => test_spec,
)
test_file_accessor = stub('test_file_accessor',
:spec => test_spec,
:spec_consumer => test_consumer,
:vendored_static_frameworks => [],
:vendored_static_libraries => [],
:vendored_dynamic_frameworks => [],
:vendored_dynamic_libraries => [],
)
pod_target = stub('pod_target',
:file_accessors => [file_accessor, test_file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
xcconfig = Xcodeproj::Config.new
@sut.add_settings_for_file_accessors_of_target(nil, pod_target, xcconfig, true, false)
xcconfig.to_hash['OTHER_LDFLAGS'].should == '-l"StaticLibrary" -l"VendoredDyld" -framework "StaticFramework" -framework "VendoredFramework"'
......@@ -500,56 +502,56 @@ module Pod
end
it 'does propagate framework or libraries from a non test specification to an aggregate target' do
spec = stub(:test_specification? => false)
consumer = stub(
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub(
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
target_definition = stub(:inheritance => 'complete')
aggregate_target = stub(:target_definition => target_definition)
spec = stub('spec', :test_specification? => false)
consumer = stub('consumer',
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub('pod_target',
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
target_definition = stub('target_definition', :inheritance => 'complete')
aggregate_target = stub('aggregate_target', :target_definition => target_definition)
xcconfig = Xcodeproj::Config.new
@sut.add_settings_for_file_accessors_of_target(aggregate_target, pod_target, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should.be == '-l"StaticLibrary" -l"VendoredDyld" -l"xml2" -framework "StaticFramework" -framework "VendoredFramework" -framework "XCTest"'
end
it 'does propagate framework or libraries to a nil aggregate target' do
spec = stub(:test_specification? => false)
consumer = stub(
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub(
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub(
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
spec = stub('spec', :test_specification? => false)
consumer = stub('consumer',
:libraries => ['xml2'],
:frameworks => ['XCTest'],
:weak_frameworks => [],
:spec => spec,
)
file_accessor = stub('file_accessor',
:spec => spec,
:spec_consumer => consumer,
:vendored_static_frameworks => [config.sandbox.root + 'StaticFramework.framework'],
:vendored_static_libraries => [config.sandbox.root + 'StaticLibrary.a'],
:vendored_dynamic_frameworks => [config.sandbox.root + 'VendoredFramework.framework'],
:vendored_dynamic_libraries => [config.sandbox.root + 'VendoredDyld.dyld'],
)
pod_target = stub('pod_target',
:file_accessors => [file_accessor],
:requires_frameworks? => true,
:dependent_targets => [],
:sandbox => config.sandbox,
)
xcconfig = Xcodeproj::Config.new
@sut.add_settings_for_file_accessors_of_target(nil, pod_target, xcconfig)
xcconfig.to_hash['OTHER_LDFLAGS'].should.be == '-l"StaticLibrary" -l"VendoredDyld" -l"xml2" -framework "StaticFramework" -framework "VendoredFramework" -framework "XCTest"'
......@@ -557,6 +559,13 @@ module Pod
end
describe 'for proper other ld flags' do
def stub_aggregate_target(pod_targets, target_definition = nil, search_paths_aggregate_targets: [])
target_definition.stubs(:abstract? => false) unless target_definition.respond_to?(:abstract?)
fixture_aggregate_target(pod_targets, target_definition).tap do |aggregate_target|
aggregate_target.search_paths_aggregate_targets.concat(search_paths_aggregate_targets).freeze
end
end
before do
@root = fixture('banana-lib')
@path_list = Sandbox::PathList.new(@root)
......@@ -566,9 +575,9 @@ module Pod
end
it 'should not include static framework other ld flags when inheriting search paths' do
target_definition = stub(:inheritance => 'search_paths')
aggregate_target = stub(:target_definition => target_definition, :pod_targets => [], :search_paths_aggregate_targets => [])
pod_target = stub(:sandbox => config.sandbox)
target_definition = stub('target_definition', :inheritance => 'search_paths')
aggregate_target = stub_aggregate_target([], target_definition)
pod_target = stub('pod_target', :sandbox => config.sandbox)
xcconfig = Xcodeproj::Config.new
@sut.add_static_dependency_build_settings(aggregate_target, pod_target, xcconfig, @accessor, true)
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should == '"${PODS_ROOT}/../../spec/fixtures/banana-lib"'
......@@ -577,9 +586,9 @@ module Pod
end
it 'should include static framework other ld flags when inheriting search paths but explicitly declared' do
target_definition = stub(:inheritance => 'search_paths')
pod_target = stub(:name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub(:target_definition => target_definition, :pod_targets => [pod_target], :search_paths_aggregate_targets => [])
target_definition = stub('target_definition', :inheritance => 'search_paths')
pod_target = stub('pod_target', :name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub_aggregate_target([pod_target], target_definition)
xcconfig = Xcodeproj::Config.new
@sut.add_static_dependency_build_settings(aggregate_target, pod_target, xcconfig, @accessor, true)
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should == '"${PODS_ROOT}/../../spec/fixtures/banana-lib"'
......@@ -588,9 +597,9 @@ module Pod
end
it 'should include static framework other ld flags when not inheriting search paths' do
target_definition = stub(:inheritance => 'complete')
aggregate_target = stub(:target_definition => target_definition)
pod_target = stub(:sandbox => config.sandbox)
target_definition = stub('target_definition', :inheritance => 'complete')
aggregate_target = stub_aggregate_target([], target_definition)
pod_target = stub('pod_target', :sandbox => config.sandbox)
xcconfig = Xcodeproj::Config.new
@sut.add_static_dependency_build_settings(aggregate_target, pod_target, xcconfig, @accessor, true)
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should == '"${PODS_ROOT}/../../spec/fixtures/banana-lib"'
......@@ -599,7 +608,7 @@ module Pod
end
it 'should include static framework for pod targets' do
pod_target = stub(:sandbox => config.sandbox)
pod_target = stub('pod_target', :sandbox => config.sandbox)
xcconfig = Xcodeproj::Config.new
@sut.add_static_dependency_build_settings(nil, pod_target, xcconfig, @accessor, true)
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should == '"${PODS_ROOT}/../../spec/fixtures/banana-lib"'
......@@ -608,55 +617,55 @@ module Pod
end
it 'should link static dependency for pod targets' do
pod_target = stub(:name => 'BananaLib', :sandbox => config.sandbox)
pod_target = stub('pod_target', :name => 'BananaLib', :sandbox => config.sandbox)
@sut.links_dependency?(nil, pod_target).should.be.true
end
it 'should link static dependency when target explicitly specifies it' do
target_definition = stub(:inheritance => 'complete')
pod_target = stub(:name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub(:target_definition => target_definition, :pod_targets => [pod_target], :search_paths_aggregate_targets => [])
target_definition = stub('target_definition', :inheritance => 'complete')
pod_target = stub('pod_target', :name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub_aggregate_target([pod_target], target_definition)
@sut.links_dependency?(aggregate_target, pod_target).should.be.true
end
it 'should link static dependency when target explicitly specifies it even with search paths' do
target_definition = stub(:inheritance => 'search_paths')
pod_target = stub(:name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub(:target_definition => target_definition, :pod_targets => [pod_target], :search_paths_aggregate_targets => [])
target_definition = stub('target_definition', :inheritance => 'search_paths')
pod_target = stub('pod_target', :name => 'BananaLib', :sandbox => config.sandbox)
aggregate_target = stub_aggregate_target([pod_target], target_definition)
@sut.links_dependency?(aggregate_target, pod_target).should.be.true
end
it 'should not link static dependency when inheriting search paths and parent includes dependency' do
parent_target_definition = stub
child_target_definition = stub(:inheritance => 'search_paths')
pod_target = stub(:name => 'BananaLib', :sandbox => config.sandbox)
parent_aggregate_target = stub(:target_definition => parent_target_definition, :pod_targets => [pod_target], :search_paths_aggregate_targets => [])
child_aggregate_target = stub(:target_definition => child_target_definition, :pod_targets => [], :search_paths_aggregate_targets => [parent_aggregate_target])
child_target_definition = stub('child_target_definition', :inheritance => 'search_paths')
pod_target = stub('pod_target', :name => 'BananaLib', :sandbox => config.sandbox)
parent_aggregate_target = stub_aggregate_target([pod_target], parent_target_definition)
child_aggregate_target = stub_aggregate_target([], child_target_definition, :search_paths_aggregate_targets => [parent_aggregate_target])
@sut.links_dependency?(child_aggregate_target, pod_target).should.be.false
end
it 'should link static transitive dependencies if the parent does not link them' do
child_pod_target = stub(:name => 'ChildPod', :sandbox => config.sandbox)
parent_pod_target = stub(:name => 'ParentPod', :sandbox => config.sandbox, :dependent_targets => [child_pod_target])
child_pod_target = stub('child_pod_target', :name => 'ChildPod', :sandbox => config.sandbox)
parent_pod_target = stub('parent_pod_target', :name => 'ParentPod', :sandbox => config.sandbox, :dependent_targets => [child_pod_target])
parent_target_definition = stub
child_target_definition = stub(:inheritance => 'search_paths')
child_target_definition = stub('child_target_definition', :inheritance => 'search_paths')
parent_aggregate_target = stub(:target_definition => parent_target_definition, :pod_targets => [], :search_paths_aggregate_targets => [])
child_aggregate_target = stub(:target_definition => child_target_definition, :pod_targets => [parent_pod_target, child_pod_target], :search_paths_aggregate_targets => [parent_aggregate_target])
parent_aggregate_target = stub_aggregate_target([], parent_target_definition)
child_aggregate_target = stub_aggregate_target([parent_pod_target, child_pod_target], child_target_definition, :search_paths_aggregate_targets => [parent_aggregate_target])
@sut.links_dependency?(child_aggregate_target, child_pod_target).should.be.true
@sut.links_dependency?(child_aggregate_target, parent_pod_target).should.be.true
end
it 'should link static only transitive dependencies that the parent does not link' do
child_pod_target = stub(:name => 'ChildPod', :sandbox => config.sandbox)
parent_pod_target = stub(:name => 'ParentPod', :sandbox => config.sandbox, :dependent_targets => [child_pod_target])
child_pod_target = stub('child_pod_target', :name => 'ChildPod', :sandbox => config.sandbox)
parent_pod_target = stub('parent_pod_target', :name => 'ParentPod', :sandbox => config.sandbox, :dependent_targets => [child_pod_target])
parent_target_definition = stub
child_target_definition = stub(:inheritance => 'search_paths')
child_target_definition = stub('child_target_definition', :inheritance => 'search_paths')
parent_aggregate_target = stub(:target_definition => parent_target_definition, :pod_targets => [child_pod_target], :search_paths_aggregate_targets => [])
child_aggregate_target = stub(:target_definition => child_target_definition, :pod_targets => [parent_pod_target, child_pod_target], :search_paths_aggregate_targets => [parent_aggregate_target])
parent_aggregate_target = stub('parent_aggregate_target', :target_definition => parent_target_definition, :pod_targets => [child_pod_target], :search_paths_aggregate_targets => [], :pod_targets_to_link => [child_pod_target])
child_aggregate_target = stub('child_aggregate_target', :target_definition => child_target_definition, :pod_targets => [parent_pod_target, child_pod_target], :search_paths_aggregate_targets => [parent_aggregate_target], :pod_targets_to_link => [parent_pod_target])
@sut.links_dependency?(child_aggregate_target, child_pod_target).should.be.false
@sut.links_dependency?(child_aggregate_target, parent_pod_target).should.be.true
end
......
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
class Installer
class Analyzer
describe PodfileDependencyCache do
describe '.from_podfile' do
it 'returns a warmed cache' do
podfile = Podfile.new do
pod 'A'
target 'T1' do
pod 'B'
target 'T1T' do
inherit! :search_paths
pod 'C'
end
end
target 'T2' do
pod 'B'
target 'T2T' do
inherit! :none
pod 'D'
end
end
end
cache = PodfileDependencyCache.from_podfile(podfile)
cache.podfile_dependencies.should == podfile.dependencies
target_definitions = podfile.target_definition_list
cache.target_definition_list.should == target_definitions
podfile.target_definition_list.each do |td|
cache.target_definition_dependencies(td).should == td.dependencies
end
lambda { cache.target_definition_dependencies(nil) }.should.raise(ArgumentError)
end
end
end
end
end
end
......@@ -598,8 +598,11 @@ module Pod
it 'fetches the dependencies with external sources' do
podfile_state = Installer::Analyzer::SpecsState.new
podfile_state.added << 'BananaLib'
@podfile = Podfile.new do
pod 'BananaLib', :git => 'example.com'
end
@analyzer = Installer::Analyzer.new(@sandbox, @podfile)
@analyzer.stubs(:result).returns(stub(:podfile_state => podfile_state))
@podfile.stubs(:dependencies).returns([Dependency.new('BananaLib', :git => 'example.com')])
ExternalSources::DownloaderSource.any_instance.expects(:fetch)
@analyzer.send(:fetch_external_sources)
end
......@@ -607,11 +610,12 @@ module Pod
it 'does not download the same source multiple times for different subspecs' do
podfile_state = Installer::Analyzer::SpecsState.new
podfile_state.added << 'ARAnalytics'
@podfile = Podfile.new do
pod 'ARAnalytics/Mixpanel', :git => 'https://github.com/orta/ARAnalytics', :commit => '6f1a1c314894437e7e5c09572c276e644dbfb64b'
pod 'ARAnalytics/HockeyApp', :git => 'https://github.com/orta/ARAnalytics', :commit => '6f1a1c314894437e7e5c09572c276e644dbfb64b'
end
@analyzer = Installer::Analyzer.new(@sandbox, @podfile)
@analyzer.stubs(:result).returns(stub(:podfile_state => podfile_state))
@podfile.stubs(:dependencies).returns([
Dependency.new('ARAnalytics/Mixpanel', :git => 'https://github.com/orta/ARAnalytics', :commit => '6f1a1c314894437e7e5c09572c276e644dbfb64b'),
Dependency.new('ARAnalytics/HockeyApp', :git => 'https://github.com/orta/ARAnalytics', :commit => '6f1a1c314894437e7e5c09572c276e644dbfb64b'),
])
ExternalSources::DownloaderSource.any_instance.expects(:fetch).once
@analyzer.send(:fetch_external_sources)
end
......@@ -984,7 +988,7 @@ module Pod
describe 'podfile validation' do
before do
@sandbox = stub('Sandbox')
@podfile = stub('Podfile')
@podfile = Podfile.new
@analyzer = Installer::Analyzer.new(@sandbox, @podfile)
end
......
......@@ -371,6 +371,7 @@ module Pod
describe '#clean_sandbox' do
before do
@analysis_result = Installer::Analyzer::AnalysisResult.new
@analysis_result.podfile_dependency_cache = Installer::Analyzer::PodfileDependencyCache.from_podfile(@installer.podfile)
@analysis_result.specifications = []
@analysis_result.sandbox_state = Installer::Analyzer::SpecsState.new
@spec = stub(:name => 'Spec', :test_specification? => false)
......@@ -563,6 +564,7 @@ module Pod
describe '#write_lockfiles' do
before do
@analysis_result = Installer::Analyzer::AnalysisResult.new
@analysis_result.podfile_dependency_cache = Installer::Analyzer::PodfileDependencyCache.from_podfile(@installer.podfile)
@analysis_result.specifications = [fixture_spec('banana-lib/BananaLib.podspec')]
@analysis_result.specs_by_source = {}
@installer.stubs(:analysis_result).returns(@analysis_result)
......
......@@ -159,12 +159,8 @@ module Pod
#-------------------------------------------------------------------------#
describe 'Resolution' do
before do
@podfile = Podfile.new do
platform :ios, '6.0'
pod 'BlocksKit', '1.5.2'
end
@resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
def create_resolver(podfile = @podfile, locked_deps = empty_graph)
@resolver = Resolver.new(config.sandbox, podfile, locked_deps, config.sources_manager.all)
end
it 'cross resolves dependencies' do
......@@ -174,7 +170,7 @@ module Pod
pod 'AFQuickLookView', '= 0.1.0' # requires 'AFNetworking', '>= 0.9.0'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort
specs.should == ['AFNetworking (0.9.1)', 'AFQuickLookView (0.1.0)']
end
......@@ -186,7 +182,7 @@ module Pod
pod 'AFNetworking', '~> 1.2.0'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort
specs.should == ['AFNetworking (1.2.1)', 'RestKit (0.20.1)',
'RestKit/Core (0.20.1)', 'RestKit/CoreData (0.20.1)',
......@@ -202,7 +198,7 @@ module Pod
pod 'AFOAuth2Client' # latest version (0.1.2) requires 'AFNetworking', '~> 1.3'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort
specs.should == ['AFAmazonS3Client (1.0.1)', 'AFNetworking (1.3.4)',
'AFOAuth2Client (1.0.0)', 'CargoBay (1.0.0)']
......@@ -216,12 +212,17 @@ module Pod
pod 'AFNetworking', '2.0.1'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:spec).map(&:root).map(&:to_s).uniq.sort
specs.should == ['AFNetworking (2.0.1)', 'InstagramKit (3.7)']
end
it 'holds the context state, such as cached specification sets' do
@podfile = Podfile.new do
platform :ios, '6.0'
pod 'BlocksKit', '1.5.2'
end
create_resolver
@resolver.resolve
cached_sets = @resolver.send(:cached_sets)
cached_sets.values.sort_by(&:name).should == [
......@@ -236,7 +237,7 @@ module Pod
platform :osx, '10.7'
pod 'ReactiveCocoa', '0.16.1' # this version is iOS-only
end
@resolver.stubs(:podfile).returns(@podfile)
create_resolver
should.raise Informative do
@resolver.resolve
end.message.should.match /platform .* not compatible/
......@@ -247,7 +248,7 @@ module Pod
platform :osx, '10.7'
pod 'AFNetworking' # the most recent version requires 10.8
end
@resolver.stubs(:podfile).returns(@podfile)
create_resolver
@resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort.should == [
'AFNetworking (1.3.4)',
]
......@@ -270,7 +271,7 @@ module Pod
platform :ios, '5.0'
pod 'lib'
end
@resolver.stubs(:podfile).returns(@podfile)
create_resolver
@resolver.send(:cached_sets)['lib'] = stub(:all_specifications => [spec])
@resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort.should == [
'AFNetworking (1.3.4)', 'lib (1.0)', 'lib/Calendar (1.0)', 'lib/Classes (1.0)', 'lib/RequestManager (1.0)'
......@@ -282,7 +283,7 @@ module Pod
platform :osx, '10.7'
pod 'AFNetworking', '2.0.0' # requires 10.8
end
@resolver.stubs(:podfile).returns(@podfile)
create_resolver
message = should.raise(Informative) { @resolver.resolve }.message
message.should.match /required a higher minimum deployment target/
end
......@@ -297,13 +298,18 @@ module Pod
pod 'LocalPod', :path => '../'
end
end
@resolver.stubs(:podfile).returns(@podfile)
create_resolver
message = should.raise(Informative) { @resolver.resolve }.message
message.should.match /required a higher minimum deployment target/
end
it 'raises if unable to find a specification' do
@podfile = Podfile.new do
platform :ios, '6'
pod 'BlocksKit', '1.5.2'
end
Specification.any_instance.stubs(:all_dependencies).returns([Dependency.new('Windows')])
create_resolver
message = should.raise Informative do
@resolver.resolve
end.message
......@@ -312,6 +318,11 @@ module Pod
end
it 'does not raise if all dependencies are supported by the platform of the target definition' do
@podfile = Podfile.new do
platform :ios, '6'
pod 'BlocksKit', '1.5.2'
end
create_resolver
lambda { @resolver.resolve }.should.not.raise
end
......@@ -320,7 +331,7 @@ module Pod
platform :ios, '7.0'
pod 'RestKit', '0.10.3'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
resolver.resolve.values.flatten.map(&:name).sort.should == %w(
FileMD5Hash
ISO8601DateFormatter
......@@ -348,7 +359,7 @@ module Pod
platform :ios, '7.0'
pod 'RestKit', '0.20.0-rc1'
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort.should == [
'AFNetworking (1.1.0)',
'RestKit (0.20.0-rc1)',
......@@ -377,7 +388,7 @@ module Pod
end
end
config.sandbox.expects(:specification).with('MainSpec').returns(spec)
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:name).sort
specs.should == %w(
MainSpec/FirstSubSpec MainSpec/FirstSubSpec/SecondSubSpec
......@@ -399,7 +410,7 @@ module Pod
end
end
config.sandbox.expects(:specification).with('MainSpec').returns(spec)
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
resolved_specs = resolver.resolve.values.flatten
spec_names = resolved_specs.map(&:name).sort
spec_names.should == %w(
......@@ -425,7 +436,7 @@ module Pod
end
end
config.sandbox.expects(:specification).with('MainSpec').returns(spec)
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
resolved_specs = resolver.resolve.values.flatten
spec_names = resolved_specs.map(&:name).sort
spec_names.should == %w(
......@@ -453,7 +464,7 @@ module Pod
end
end
config.sandbox.expects(:specification).with('MainSpec').returns(spec)
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
resolved_specs = resolver.resolve.values.flatten
spec_names = resolved_specs.map(&:name).sort
spec_names.should == %w(
......@@ -476,7 +487,7 @@ module Pod
s.platform = :ios
end
config.sandbox.expects(:specification).with('MainSpec').returns(spec)
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver
specs = resolver.resolve.values.flatten.map(&:spec).map(&:to_s).sort
specs.should == [
'MainSpec (1.2.3-pre)',
......@@ -489,7 +500,7 @@ module Pod
pod 'JSONKit', '1.4'
pod 'JSONKit', '1.5pre'
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver(podfile)
e = lambda { resolver.resolve }.should.raise Informative
e.message.should.include <<-EOS.strip
[!] CocoaPods could not find compatible versions for pod "JSONKit":
......@@ -506,7 +517,7 @@ module Pod
pod 'RestKit', '0.23.3' # dependends on AFNetworking ~> 1.3.0
pod 'AFNetworking', '> 2'
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver(podfile)
e = lambda { resolver.resolve }.should.raise Informative
e.message.should.include <<-EOS.strip
[!] CocoaPods could not find compatible versions for pod "AFNetworking":
......@@ -525,7 +536,7 @@ module Pod
platform :ios
pod 'AFNetworking', '999.999.999'
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver(podfile)
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.include <<-EOS.strip
[!] CocoaPods could not find compatible versions for pod "AFNetworking":
......@@ -549,7 +560,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
platform :ios
pod 'AFNetworking', '999.999.999'
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver(podfile)
resolver.specs_updated = true
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.include <<-EOS.strip
......@@ -575,7 +586,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
end
locked_deps = dependency_graph_from_array([Dependency.new('AFNetworking', '= 1.4')])
resolver = Resolver.new(config.sandbox, podfile, locked_deps, config.sources_manager.all)
resolver = create_resolver(podfile, locked_deps)
e = lambda { resolver.resolve }.should.raise NoSpecFoundError
e.message.should.include <<-EOS.strip
[!] CocoaPods could not find compatible versions for pod "AFNetworking":
......@@ -602,12 +613,12 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
platform :ios
pod 'JSONKit', '<= 1.5pre'
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, config.sources_manager.all)
resolver = create_resolver(podfile)
version = resolver.resolve.values.flatten.first.spec.version
version.to_s.should == '1.5pre'
locked_deps = dependency_graph_from_array([Dependency.new('JSONKit', '= 1.4')])
resolver = Resolver.new(config.sandbox, podfile, locked_deps, config.sources_manager.all)
resolver = create_resolver(podfile, locked_deps)
version = resolver.resolve.values.flatten.first.spec.version
version.to_s.should == '1.4'
end
......@@ -620,7 +631,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
pod 'CocoaLumberjack'
end
locked_deps = dependency_graph_from_array([Dependency.new('CocoaLumberjack', '= 2.0.0-beta2')])
resolver = Resolver.new(config.sandbox, podfile, locked_deps, config.sources_manager.all)
resolver = create_resolver(podfile, locked_deps)
e = lambda { puts resolver.resolve.values.flatten }.should.raise Informative
e.message.should.match(/you were using a pre-release version of `CocoaLumberjack`/)
e.message.should.match(/`pod 'CocoaLumberjack', '= 2.0.0-beta2'`/)
......
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