Unverified Commit 719a238c authored by Samuel Giddins's avatar Samuel Giddins Committed by GitHub

Merge pull request #7541 from CocoaPods/segiddins/yes-more-performance

Yes, improving performance again
parents ac26c003 8f2f979c
...@@ -7,7 +7,7 @@ GIT ...@@ -7,7 +7,7 @@ GIT
GIT GIT
remote: https://github.com/CocoaPods/Core.git remote: https://github.com/CocoaPods/Core.git
revision: a5fafbc2bfe80966917307c2deaa1664898af5bc revision: 35b53a939c553c510e81fcf2cec0ff6682399b9a
branch: master branch: master
specs: specs:
cocoapods-core (1.5.0) cocoapods-core (1.5.0)
......
...@@ -119,10 +119,14 @@ module Pod ...@@ -119,10 +119,14 @@ module Pod
rescue => _ rescue => _
raise Informative, "Failed to download '#{name}'." raise Informative, "Failed to download '#{name}'."
end end
spec = download_result.spec
spec = download_result.spec
raise Informative, "Unable to find a specification for '#{name}'." unless spec raise Informative, "Unable to find a specification for '#{name}'." unless spec
# since the podspec might be cleaned, we want the checksum to refer
# to the json in the sandbox
spec.defined_in_file = nil
store_podspec(sandbox, spec) store_podspec(sandbox, spec)
sandbox.store_pre_downloaded_pod(name) sandbox.store_pre_downloaded_pod(name)
sandbox.store_checkout_source(name, download_result.checkout_options) sandbox.store_checkout_source(name, download_result.checkout_options)
...@@ -161,7 +165,7 @@ module Pod ...@@ -161,7 +165,7 @@ module Pod
when String when String
path = "#{name}.podspec" path = "#{name}.podspec"
path << '.json' if json path << '.json' if json
Specification.from_string(spec, path) Specification.from_string(spec, path).tap { |s| s.defined_in_file = nil }
when Specification when Specification
spec.dup spec.dup
else else
...@@ -170,12 +174,15 @@ module Pod ...@@ -170,12 +174,15 @@ module Pod
rescue Pod::DSLError => e rescue Pod::DSLError => e
raise Informative, "Failed to load '#{name}' podspec: #{e.message}" raise Informative, "Failed to load '#{name}' podspec: #{e.message}"
end end
spec.defined_in_file = nil
validate_podspec(spec) validate_podspec(spec)
sandbox.store_podspec(name, spec.to_pretty_json, true, true) sandbox.store_podspec(name, spec, true, true)
end end
def validate_podspec(podspec) def validate_podspec(podspec)
defined_in_file = podspec.defined_in_file
podspec.defined_in_file = nil
validator = validator_for_podspec(podspec) validator = validator_for_podspec(podspec)
validator.quick = true validator.quick = true
validator.allow_warnings = true validator.allow_warnings = true
...@@ -186,6 +193,8 @@ module Pod ...@@ -186,6 +193,8 @@ module Pod
unless validator.validated? unless validator.validated?
raise Informative, "The `#{name}` pod failed to validate due to #{validator.failure_reason}:\n#{validator.results_message}" raise Informative, "The `#{name}` pod failed to validate due to #{validator.failure_reason}:\n#{validator.results_message}"
end end
ensure
podspec.defined_in_file = defined_in_file
end end
def validator_for_podspec(podspec) def validator_for_podspec(podspec)
......
...@@ -66,8 +66,8 @@ module Pod ...@@ -66,8 +66,8 @@ module Pod
# @param [Lockfile] lockfile @see #lockfile # @param [Lockfile] lockfile @see #lockfile
# #
def initialize(sandbox, podfile, lockfile = nil) def initialize(sandbox, podfile, lockfile = nil)
@sandbox = sandbox @sandbox = sandbox || raise(ArgumentError, 'Missing required argument `sandbox`')
@podfile = podfile @podfile = podfile || raise(ArgumentError, 'Missing required argument `podfile`')
@lockfile = lockfile @lockfile = lockfile
@use_default_plugins = true @use_default_plugins = true
...@@ -669,5 +669,28 @@ module Pod ...@@ -669,5 +669,28 @@ module Pod
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
public
# @!group Convenience Methods
def self.targets_from_sandbox(sandbox, podfile, lockfile)
raise Informative, 'You must run `pod install` to be able to generate target information' unless lockfile
new(sandbox, podfile, lockfile).instance_exec do
plugin_sources = run_source_provider_hooks
analyzer = create_analyzer(plugin_sources)
analyze(analyzer)
if analyzer.podfile_needs_install?(analyzer.result)
raise Pod::Informative, 'The Podfile has changed, you must run `pod install`'
elsif analyzer.sandbox_needs_install?(analyzer.result)
raise Pod::Informative, 'The `Pods` directory is out-of-date, you must run `pod install`'
end
aggregate_targets
end
end
#-------------------------------------------------------------------------#
end end
end end
...@@ -56,6 +56,7 @@ module Pod ...@@ -56,6 +56,7 @@ module Pod
@test_pod_target_analyzer_cache = {} @test_pod_target_analyzer_cache = {}
@test_pod_target_key = Struct.new(:name, :pod_targets) @test_pod_target_key = Struct.new(:name, :pod_targets)
@podfile_dependency_cache = PodfileDependencyCache.from_podfile(podfile) @podfile_dependency_cache = PodfileDependencyCache.from_podfile(podfile)
@result = nil
end end
# Performs the analysis. # Performs the analysis.
...@@ -70,6 +71,7 @@ module Pod ...@@ -70,6 +71,7 @@ module Pod
# @return [AnalysisResult] # @return [AnalysisResult]
# #
def analyze(allow_fetches = true) def analyze(allow_fetches = true)
return @result if @result
validate_podfile! validate_podfile!
validate_lockfile_version! validate_lockfile_version!
@result = AnalysisResult.new @result = AnalysisResult.new
...@@ -229,7 +231,7 @@ module Pod ...@@ -229,7 +231,7 @@ module Pod
UI.section 'Finding Podfile changes' do UI.section 'Finding Podfile changes' do
pods_by_state = lockfile.detect_changes_with_podfile(podfile) pods_by_state = lockfile.detect_changes_with_podfile(podfile)
pods_state = SpecsState.new(pods_by_state) pods_state = SpecsState.new(pods_by_state)
pods_state.print pods_state.print if config.verbose?
end end
pods_state pods_state
else else
...@@ -467,9 +469,8 @@ module Pod ...@@ -467,9 +469,8 @@ module Pod
# #
def filter_pod_targets_for_target_definition(target_definition, pod_targets, resolver_specs_by_target) def filter_pod_targets_for_target_definition(target_definition, pod_targets, resolver_specs_by_target)
pod_targets.select do |pod_target| pod_targets.select do |pod_target|
included_in_target_definition = pod_target.target_definitions.include?(target_definition) next false unless pod_target.target_definitions.include?(target_definition)
used_by_tests_only = resolver_specs_by_target[target_definition].select { |resolver_spec| pod_target.specs.include?(resolver_spec.spec) }.all?(&:used_by_tests_only?) resolver_specs_by_target[target_definition].any? { |resolver_spec| !resolver_spec.used_by_tests_only? && pod_target.specs.include?(resolver_spec.spec) }
included_in_target_definition && !used_by_tests_only
end end
end end
...@@ -510,9 +511,9 @@ module Pod ...@@ -510,9 +511,9 @@ module Pod
hash[name] = values.sort_by { |pt| pt.specs.count } hash[name] = values.sort_by { |pt| pt.specs.count }
end end
pod_targets.each do |target| pod_targets.each do |target|
all_specs = all_resolver_specs.to_set all_specs = all_resolver_specs.group_by(&:name)
dependencies = transitive_dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs).group_by(&:root) dependencies = transitive_dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs).group_by(&:root) test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
test_dependencies.delete_if { |k| dependencies.key? k } test_dependencies.delete_if { |k| dependencies.key? k }
target.dependent_targets = filter_dependencies(dependencies, pod_targets_by_name, target) target.dependent_targets = filter_dependencies(dependencies, pod_targets_by_name, target)
target.test_dependent_targets = filter_dependencies(test_dependencies, pod_targets_by_name, target) target.test_dependent_targets = filter_dependencies(test_dependencies, pod_targets_by_name, target)
...@@ -526,9 +527,9 @@ module Pod ...@@ -526,9 +527,9 @@ module Pod
end end
pod_targets.each do |target| pod_targets.each do |target|
all_specs = specs.map(&:spec).to_set all_specs = specs.map(&:spec).group_by(&:name)
dependencies = transitive_dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs).group_by(&:root) dependencies = transitive_dependencies_for_specs(target.non_test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs).group_by(&:root) test_dependencies = transitive_dependencies_for_specs(target.test_specs.to_set, target.platform, all_specs.dup).group_by(&:root)
test_dependencies.delete_if { |k| dependencies.key? k } test_dependencies.delete_if { |k| dependencies.key? k }
target.dependent_targets = pod_targets.reject { |t| dependencies[t.root_spec].nil? } target.dependent_targets = pod_targets.reject { |t| dependencies[t.root_spec].nil? }
target.test_dependent_targets = pod_targets.reject { |t| test_dependencies[t.root_spec].nil? } target.test_dependent_targets = pod_targets.reject { |t| test_dependencies[t.root_spec].nil? }
...@@ -559,7 +560,7 @@ module Pod ...@@ -559,7 +560,7 @@ module Pod
# @param [Platform] platform # @param [Platform] platform
# The platform for which the dependencies should be returned. # The platform for which the dependencies should be returned.
# #
# @param [Array<Specification>] all_specs # @param [Hash<String, Specification>] all_specs
# All specifications which are installed alongside. # All specifications which are installed alongside.
# #
# @return [Array<Specification>] # @return [Array<Specification>]
...@@ -568,20 +569,20 @@ module Pod ...@@ -568,20 +569,20 @@ module Pod
return [] if specs.empty? || all_specs.empty? return [] if specs.empty? || all_specs.empty?
dependent_specs = Set.new dependent_specs = Set.new
specs.each do |spec| to_process = specs
spec.consumer(platform).dependencies.each do |dependency| loop do
match = all_specs.find do |s| break if to_process.empty?
next false unless s.name == dependency.name next_to_process = Set.new
next false if specs.include?(s) to_process.each do |s|
true s.dependencies(platform).each do |dep|
all_specs[dep.name].each do |spec|
next_to_process.add(spec) if dependent_specs.add?(spec)
end end
dependent_specs << match if match
end end
end end
to_process = next_to_process
remaining_specs = all_specs - dependent_specs end
dependent_specs - specs
dependent_specs.union transitive_dependencies_for_specs(dependent_specs, platform, remaining_specs)
end end
# Create a target for each spec group # Create a target for each spec group
...@@ -679,7 +680,7 @@ module Pod ...@@ -679,7 +680,7 @@ module Pod
pods_to_update = result.podfile_state.changed + result.podfile_state.deleted pods_to_update = result.podfile_state.changed + result.podfile_state.deleted
pods_to_update += update[:pods] if update_mode == :selected pods_to_update += update[:pods] if update_mode == :selected
local_pod_names = @podfile_dependency_cache.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| pods_to_unlock = local_pod_names.to_set.delete_if do |pod_name|
sandbox.specification(pod_name).checksum == lockfile.checksum(pod_name) sandbox.specification(pod_name).checksum == lockfile.checksum(pod_name)
end end
LockingDependencyAnalyzer.generate_version_locking_dependencies(lockfile, pods_to_update, pods_to_unlock) LockingDependencyAnalyzer.generate_version_locking_dependencies(lockfile, pods_to_update, pods_to_unlock)
...@@ -747,7 +748,7 @@ module Pod ...@@ -747,7 +748,7 @@ module Pod
deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) } deps_to_fetch = deps_with_external_source.select { |dep| pods_to_fetch.include?(dep.root_name) }
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.root_name) } deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.root_name) }
deps_to_fetch += deps_to_fetch_if_needed.select do |dep| deps_to_fetch += deps_to_fetch_if_needed.select do |dep|
sandbox.specification(dep.root_name).nil? || sandbox.specification_path(dep.root_name).nil? ||
!dep.external_source[:path].nil? || !dep.external_source[:path].nil? ||
!sandbox.pod_dir(dep.root_name).directory? || !sandbox.pod_dir(dep.root_name).directory? ||
checkout_requires_update?(dep) checkout_requires_update?(dep)
......
...@@ -33,6 +33,8 @@ module Pod ...@@ -33,6 +33,8 @@ module Pod
dependency_graph = Molinillo::DependencyGraph.new dependency_graph = Molinillo::DependencyGraph.new
if lockfile if lockfile
added_dependency_strings = Set.new
explicit_dependencies = lockfile.dependencies explicit_dependencies = lockfile.dependencies
explicit_dependencies.each do |dependency| explicit_dependencies.each do |dependency|
dependency_graph.add_vertex(dependency.name, dependency, true) dependency_graph.add_vertex(dependency.name, dependency, true)
...@@ -40,7 +42,7 @@ module Pod ...@@ -40,7 +42,7 @@ module Pod
pods = lockfile.to_hash['PODS'] || [] pods = lockfile.to_hash['PODS'] || []
pods.each do |pod| pods.each do |pod|
add_to_dependency_graph(pod, [], dependency_graph, pods_to_unlock) add_to_dependency_graph(pod, [], dependency_graph, pods_to_unlock, added_dependency_strings)
end end
pods_to_update = pods_to_update.flat_map do |u| pods_to_update = pods_to_update.flat_map do |u|
...@@ -67,7 +69,8 @@ module Pod ...@@ -67,7 +69,8 @@ module Pod
private private
def self.add_child_vertex_to_graph(dependency_string, parents, dependency_graph, pods_to_unlock) def self.add_child_vertex_to_graph(dependency_string, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
return unless added_dependency_strings.add?(dependency_string)
dependency = Dependency.from_string(dependency_string) dependency = Dependency.from_string(dependency_string)
if pods_to_unlock.include?(dependency.root_name) if pods_to_unlock.include?(dependency.root_name)
dependency = Dependency.new(dependency.name) dependency = Dependency.new(dependency.name)
...@@ -78,14 +81,14 @@ module Pod ...@@ -78,14 +81,14 @@ module Pod
dependency dependency
end end
def self.add_to_dependency_graph(object, parents, dependency_graph, pods_to_unlock) def self.add_to_dependency_graph(object, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
case object case object
when String when String
add_child_vertex_to_graph(object, parents, dependency_graph, pods_to_unlock) add_child_vertex_to_graph(object, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
when Hash when Hash
object.each do |key, value| object.each do |key, value|
dependency = add_child_vertex_to_graph(key, parents, dependency_graph, pods_to_unlock) dependency = add_child_vertex_to_graph(key, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
value.each { |v| add_to_dependency_graph(v, [dependency.name], dependency_graph, pods_to_unlock) } value.each { |v| add_to_dependency_graph(v, [dependency.name], dependency_graph, pods_to_unlock, added_dependency_strings) }
end end
end end
end end
......
...@@ -38,6 +38,7 @@ module Pod ...@@ -38,6 +38,7 @@ module Pod
@test_specs = test_specs @test_specs = test_specs
@platform = platform @platform = platform
@requires_frameworks = requires_frameworks @requires_frameworks = requires_frameworks
@hash = [specs, platform, requires_frameworks].hash
end end
# @note Test specs are intentionally not included as part of the equality for pod variants since a # @note Test specs are intentionally not included as part of the equality for pod variants since a
...@@ -48,9 +49,9 @@ module Pod ...@@ -48,9 +49,9 @@ module Pod
# #
def ==(other) def ==(other)
self.class == other.class && self.class == other.class &&
specs == other.specs && requires_frameworks == other.requires_frameworks &&
platform == other.platform && platform == other.platform &&
requires_frameworks == other.requires_frameworks specs == other.specs
end end
alias_method :eql?, :== alias_method :eql?, :==
...@@ -59,9 +60,7 @@ module Pod ...@@ -59,9 +60,7 @@ module Pod
# This adds support to make instances usable as Hash keys. # This adds support to make instances usable as Hash keys.
# #
# @!visibility private # @!visibility private
def hash attr_reader :hash
[specs, platform, requires_frameworks].hash
end
end end
end end
end end
......
...@@ -103,7 +103,7 @@ module Pod ...@@ -103,7 +103,7 @@ module Pod
# #
def pod_added?(pod) def pod_added?(pod)
return true if resolved_pods.include?(pod) && !sandbox_pods.include?(pod) return true if resolved_pods.include?(pod) && !sandbox_pods.include?(pod)
return true unless folder_exist?(pod) return true if !folder_exist?(pod) && !sandbox.local?(pod)
false false
end end
......
...@@ -115,8 +115,9 @@ module Pod ...@@ -115,8 +115,9 @@ module Pod
next unless sandbox.local?(pod_name) next unless sandbox.local?(pod_name)
root_name = Specification.root_name(pod_name) root_name = Specification.root_name(pod_name)
paths = file_accessor.developer_files paths = file_accessor.developer_files
paths.each do |path| next if paths.empty?
group = pods_project.group_for_spec(root_name, :developer) group = pods_project.group_for_spec(root_name, :developer)
paths.each do |path|
ref = pods_project.add_file_reference(path, group, false) ref = pods_project.add_file_reference(path, group, false)
if path.extname == '.podspec' if path.extname == '.podspec'
pods_project.mark_ruby_file_ref(ref) pods_project.mark_ruby_file_ref(ref)
...@@ -203,13 +204,15 @@ module Pod ...@@ -203,13 +204,15 @@ module Pod
# #
def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false) def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false)
file_accessors.each do |file_accessor| file_accessors.each do |file_accessor|
pod_name = file_accessor.spec.name
local = sandbox.local?(pod_name)
paths = file_accessor.send(file_accessor_key) paths = file_accessor.send(file_accessor_key)
paths = allowable_project_paths(paths) paths = allowable_project_paths(paths)
next if paths.empty?
pod_name = file_accessor.spec.name
local = sandbox.local?(pod_name)
base_path = local ? common_path(paths) : nil base_path = local ? common_path(paths) : nil
paths.each do |path|
group = pods_project.group_for_spec(pod_name, group_key) group = pods_project.group_for_spec(pod_name, group_key)
paths.each do |path|
pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path) pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
end end
end end
......
...@@ -109,13 +109,13 @@ module Pod ...@@ -109,13 +109,13 @@ module Pod
# @return [Object] the result of the generator. # @return [Object] the result of the generator.
# #
def update_changed_file(generator, path) def update_changed_file(generator, path)
path.dirname.mkpath
if path.exist? if path.exist?
result = generator.save_as(support_files_temp_dir) result = generator.save_as(support_files_temp_dir)
unless FileUtils.identical?(support_files_temp_dir, path) unless FileUtils.identical?(support_files_temp_dir, path)
FileUtils.mv(support_files_temp_dir, path) FileUtils.mv(support_files_temp_dir, path)
end end
else else
path.dirname.mkpath
result = generator.save_as(path) result = generator.save_as(path)
end end
clean_support_files_temp_dir if support_files_temp_dir.exist? clean_support_files_temp_dir if support_files_temp_dir.exist?
......
...@@ -133,19 +133,13 @@ module Pod ...@@ -133,19 +133,13 @@ module Pod
# #
def resolver_specs_by_target def resolver_specs_by_target
@resolver_specs_by_target ||= {}.tap do |resolver_specs_by_target| @resolver_specs_by_target ||= {}.tap do |resolver_specs_by_target|
dependencies = {}
@podfile_dependency_cache.target_definition_list.each do |target| @podfile_dependency_cache.target_definition_list.each do |target|
specs = @podfile_dependency_cache.target_definition_dependencies(target).flat_map do |dep| vertices = valid_dependencies_for_target(target)
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?] }
end
resolver_specs_by_target[target] = specs. resolver_specs_by_target[target] = vertices.
group_by(&:first). map do |vertex|
map do |vertex, spec_test_only_tuples|
test_only = spec_test_only_tuples.all? { |tuple| tuple[1] }
payload = vertex.payload payload = vertex.payload
test_only = (!vertex.root? || payload.test_specification?) && vertex.recursive_predecessors.all? { |v| !v.root? || v.payload.test_specification? }
spec_source = payload.respond_to?(:spec_source) && payload.spec_source spec_source = payload.respond_to?(:spec_source) && payload.spec_source
ResolverSpecification.new(payload, test_only, spec_source) ResolverSpecification.new(payload, test_only, spec_source)
end. end.
...@@ -235,31 +229,29 @@ module Pod ...@@ -235,31 +229,29 @@ module Pod
def requirement_satisfied_by?(requirement, activated, spec) def requirement_satisfied_by?(requirement, activated, spec)
version = spec.version version = spec.version
return false unless requirement.requirement.satisfied_by?(version) return false unless requirement.requirement.satisfied_by?(version)
shared_possibility_versions, prerelease_requirement = possibility_versions_for_root_name(requirement, activated) return false unless valid_possibility_version_for_root_name?(requirement, activated, spec)
return false if !shared_possibility_versions.empty? && !shared_possibility_versions.include?(version)
return false if version.prerelease? && !prerelease_requirement
return false unless spec_is_platform_compatible?(activated, requirement, spec) return false unless spec_is_platform_compatible?(activated, requirement, spec)
true true
end end
def possibility_versions_for_root_name(requirement, activated) def valid_possibility_version_for_root_name?(requirement, activated, spec)
prerelease_requirement = requirement.prerelease? || requirement.external_source prerelease_requirement = requirement.prerelease? || requirement.external_source || !spec.version.prerelease?
existing = activated.vertices.values.flat_map do |vertex|
activated.each do |vertex|
next unless vertex.payload next unless vertex.payload
next unless Specification.root_name(vertex.name) == requirement.root_name next unless Specification.root_name(vertex.name) == requirement.root_name
prerelease_requirement ||= vertex.requirements.any? { |r| r.prerelease? || r.external_source } prerelease_requirement ||= vertex.requirements.any? { |r| r.prerelease? || r.external_source }
if vertex.payload.respond_to?(:possibilities) if vertex.payload.respond_to?(:version)
vertex.payload.possibilities.map(&:version) return true if vertex.payload.version == spec.version
else break
vertex.payload.version end
end end
end.compact
[existing, prerelease_requirement] prerelease_requirement
end end
private :possibility_versions_for_root_name private :valid_possibility_version_for_root_name?
# Sort dependencies so that the ones that are easiest to resolve are first. # Sort dependencies so that the ones that are easiest to resolve are first.
# Easiest to resolve is (usually) defined by: # Easiest to resolve is (usually) defined by:
...@@ -543,8 +535,12 @@ module Pod ...@@ -543,8 +535,12 @@ module Pod
# #
# @return [Bool] # @return [Bool]
def spec_is_platform_compatible?(dependency_graph, dependency, spec) def spec_is_platform_compatible?(dependency_graph, dependency, spec)
# This is safe since a pod will only be in locked dependencies if we're
# using the same exact version
return true if locked_dependencies.vertex_named(spec.name)
vertex = dependency_graph.vertex_named(dependency.name) vertex = dependency_graph.vertex_named(dependency.name)
predecessors = vertex.recursive_predecessors.select(&:root) predecessors = vertex.recursive_predecessors.select(&:root?)
predecessors << vertex if vertex.root? predecessors << vertex if vertex.root?
platforms_to_satisfy = predecessors.flat_map(&:explicit_requirements).flat_map { |r| @platforms_by_dependency[r] }.uniq platforms_to_satisfy = predecessors.flat_map(&:explicit_requirements).flat_map { |r| @platforms_by_dependency[r] }.uniq
...@@ -566,18 +562,21 @@ module Pod ...@@ -566,18 +562,21 @@ module Pod
# An array of target-appropriate nodes whose `payload`s are # An array of target-appropriate nodes whose `payload`s are
# dependencies for `target`. # dependencies for `target`.
# #
def valid_dependencies_for_target_from_node(target, dependencies, node) def valid_dependencies_for_target(target)
dependencies[[node.name, target.platform]] ||= begin dependencies = Set.new
@podfile_dependency_cache.target_definition_dependencies(target).each do |dep|
node = @activated.vertex_named(dep.name)
add_valid_dependencies_from_node(node, target, dependencies)
end
dependencies
end
def add_valid_dependencies_from_node(node, target, dependencies)
return unless dependencies.add?(node)
validate_platform(node.payload, target) validate_platform(node.payload, target)
dependency_nodes = []
node.outgoing_edges.each do |edge| node.outgoing_edges.each do |edge|
next unless edge_is_valid_for_target_platform?(edge, target.platform) next unless edge_is_valid_for_target_platform?(edge, target.platform)
dependency_nodes << edge.destination add_valid_dependencies_from_node(edge.destination, target, dependencies)
end
dependency_nodes.flat_map do |item|
valid_dependencies_for_target_from_node(target, dependencies, item)
end.concat(dependency_nodes).uniq
end end
end end
......
...@@ -62,6 +62,7 @@ module Pod ...@@ -62,6 +62,7 @@ module Pod
@checkout_sources = {} @checkout_sources = {}
@development_pods = {} @development_pods = {}
@pods_with_absolute_path = [] @pods_with_absolute_path = []
@stored_podspecs = {}
end end
# @return [Lockfile] the manifest which contains the information about the # @return [Lockfile] the manifest which contains the information about the
...@@ -209,7 +210,7 @@ module Pod ...@@ -209,7 +210,7 @@ module Pod
# @return [Specification] the specification if the file is found. # @return [Specification] the specification if the file is found.
# #
def specification(name) def specification(name)
if file = specification_path(name) @stored_podspecs[name] ||= if file = specification_path(name)
original_path = development_pods[name] original_path = development_pods[name]
Specification.from_file(original_path || file) Specification.from_file(original_path || file)
end end
...@@ -242,7 +243,7 @@ module Pod ...@@ -242,7 +243,7 @@ module Pod
# @param [String] name # @param [String] name
# the name of the pod # the name of the pod
# #
# @param [String, Pathname] podspec # @param [String, Pathname, Specification] podspec
# The contents of the specification (String) or the path to a # The contents of the specification (String) or the path to a
# podspec file (Pathname). # podspec file (Pathname).
# #
...@@ -252,23 +253,31 @@ module Pod ...@@ -252,23 +253,31 @@ module Pod
def store_podspec(name, podspec, _external_source = false, json = false) def store_podspec(name, podspec, _external_source = false, json = false)
file_name = json ? "#{name}.podspec.json" : "#{name}.podspec" file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
output_path = specifications_root + file_name output_path = specifications_root + file_name
output_path.dirname.mkpath
if podspec.is_a?(String) case podspec
when String
output_path.open('w') { |f| f.puts(podspec) } output_path.open('w') { |f| f.puts(podspec) }
else when Pathname
unless podspec.exist? unless podspec.exist?
raise Informative, "No podspec found for `#{name}` in #{podspec}" raise Informative, "No podspec found for `#{name}` in #{podspec}"
end end
spec = Specification.from_file(podspec)
FileUtils.copy(podspec, output_path) FileUtils.copy(podspec, output_path)
when Specification
raise ArgumentError, 'can only store Specification objects as json' unless json
output_path.open('w') { |f| f.puts(podspec.to_pretty_json) }
spec = podspec.dup
else
raise ArgumentError, "Unknown type for podspec: #{podspec.inspect}"
end end
Dir.chdir(podspec.is_a?(Pathname) ? File.dirname(podspec) : Dir.pwd) do spec ||= Specification.from_file(output_path)
spec = Specification.from_file(output_path) spec.defined_in_file ||= output_path
unless spec.name == name unless spec.name == name
raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`" raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
end end
end @stored_podspecs[spec.name] = spec
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
......
...@@ -54,7 +54,7 @@ module Pod ...@@ -54,7 +54,7 @@ module Pod
return @search_paths_cache[key] if @search_paths_cache.key?(key) return @search_paths_cache[key] if @search_paths_cache.key?(key)
search_paths = @search_paths.select do |entry| search_paths = @search_paths.select do |entry|
matches_platform = entry[:platform] == platform.name matches_platform = entry[:platform] == platform.name
matches_target = target_name.nil? || (entry[:path].basename.to_s == target_name) matches_target = target_name.nil? || (File.basename(entry[:path]) == target_name)
matches_platform && matches_target matches_platform && matches_target
end end
headers_dir = root.relative_path_from(sandbox.root).dirname headers_dir = root.relative_path_from(sandbox.root).dirname
...@@ -96,8 +96,9 @@ module Pod ...@@ -96,8 +96,9 @@ module Pod
# @return [Array<Pathname>] # @return [Array<Pathname>]
# #
def add_files(namespace, relative_header_paths) def add_files(namespace, relative_header_paths)
root.join(namespace).mkpath unless relative_header_paths.empty?
relative_header_paths.map do |relative_header_path| relative_header_paths.map do |relative_header_path|
add_file(namespace, relative_header_path) add_file(namespace, relative_header_path, :mkdir => false)
end end
end end
...@@ -115,9 +116,9 @@ module Pod ...@@ -115,9 +116,9 @@ module Pod
# #
# @return [Pathname] # @return [Pathname]
# #
def add_file(namespace, relative_header_path) def add_file(namespace, relative_header_path, mkdir: true)
namespaced_path = root + namespace namespaced_path = root + namespace
namespaced_path.mkpath unless File.exist?(namespaced_path) namespaced_path.mkpath if mkdir
absolute_source = (sandbox.root + relative_header_path) absolute_source = (sandbox.root + relative_header_path)
source = absolute_source.relative_path_from(namespaced_path) source = absolute_source.relative_path_from(namespaced_path)
...@@ -128,7 +129,7 @@ module Pod ...@@ -128,7 +129,7 @@ module Pod
# Adds an header search path to the sandbox. # Adds an header search path to the sandbox.
# #
# @param [Pathname] path # @param [Pathname] path
# the path tho add. # the path to add.
# #
# @param [String] platform # @param [String] platform
# the platform the search path applies to # the platform the search path applies to
...@@ -136,7 +137,7 @@ module Pod ...@@ -136,7 +137,7 @@ module Pod
# @return [void] # @return [void]
# #
def add_search_path(path, platform) def add_search_path(path, platform)
@search_paths << { :platform => platform.name, :path => (Pathname.new(@relative_path) + path) } @search_paths << { :platform => platform.name, :path => File.join(@relative_path, path) }
end end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
......
Subproject commit d7a64c03deab9decfa5c7e3af0af88ae225b1fc9 Subproject commit 2ede36e05798057b7d21e6bd953497c52fad71bb
...@@ -185,10 +185,10 @@ module Pod ...@@ -185,10 +185,10 @@ module Pod
end end
it 'validates specs as frameworks by default' do it 'validates specs as frameworks by default' do
Validator.any_instance.expects(:podfile_from_spec).with(:ios, '8.0', true, []).times(3) Validator.any_instance.expects(:podfile_from_spec).with(:ios, '8.0', true, []).times(3).returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, true, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, true, []).twice.returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, true, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, true, []).twice.returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, true, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, true, []).twice.returns(stub('Podfile'))
cmd = command('repo', 'push', 'master') cmd = command('repo', 'push', 'master')
# Git push will throw an exception here since this is a local custom git repo. All we care is the validator # Git push will throw an exception here since this is a local custom git repo. All we care is the validator
...@@ -199,10 +199,10 @@ module Pod ...@@ -199,10 +199,10 @@ module Pod
end end
it 'validates specs as libraries if requested' do it 'validates specs as libraries if requested' do
Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, []).times(3) Validator.any_instance.expects(:podfile_from_spec).with(:ios, nil, false, []).times(3).returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:osx, nil, false, []).twice.returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:watchos, nil, false, []).twice.returns(stub('Podfile'))
Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, []).twice Validator.any_instance.expects(:podfile_from_spec).with(:tvos, nil, false, []).twice.returns(stub('Podfile'))
cmd = command('repo', 'push', 'master', '--use-libraries') cmd = command('repo', 'push', 'master', '--use-libraries')
# Git push will throw an exception here since this is a local custom git repo. All we care is the validator # Git push will throw an exception here since this is a local custom git repo. All we care is the validator
......
...@@ -55,14 +55,10 @@ require 'spec_helper/webmock' # Cleans up mocks after each spec ...@@ -55,14 +55,10 @@ require 'spec_helper/webmock' # Cleans up mocks after each spec
# #
module Pod module Pod
class Specification class Specification
alias_method :original_source, :source
def source def source
fixture = SpecHelper.fixture("integration/#{name}") fixture = SpecHelper.fixture("integration/#{name}")
result = super result = super
if fixture.exist? result[:git] = fixture.to_s if fixture.exist?
# puts "Using fixture [#{name}]"
result[:git] = fixture.to_s
end
result result
end end
end end
...@@ -99,6 +95,17 @@ module SpecHelper ...@@ -99,6 +95,17 @@ module SpecHelper
def self.temporary_directory def self.temporary_directory
ROOT + 'tmp' ROOT + 'tmp'
end end
def self.reset_config_instance
::Pod::Config.instance = nil
::Pod::Config.instance.tap do |c|
c.verbose = false
c.silent = true
c.repos_dir = fixture('spec-repos')
c.installation_root = SpecHelper.temporary_directory
c.cache_root = SpecHelper.temporary_directory + 'Cache'
end
end
end end
def temporary_sandbox def temporary_sandbox
......
...@@ -5,14 +5,7 @@ module Bacon ...@@ -5,14 +5,7 @@ module Bacon
old_run_requirement = instance_method(:run_requirement) old_run_requirement = instance_method(:run_requirement)
define_method(:run_requirement) do |description, spec| define_method(:run_requirement) do |description, spec|
::Pod::Config.instance = nil ::SpecHelper.reset_config_instance
::Pod::Config.instance.tap do |c|
c.verbose = false
c.silent = true
c.repos_dir = fixture('spec-repos')
c.installation_root = SpecHelper.temporary_directory
c.cache_root = SpecHelper.temporary_directory + 'Cache'
end
::Pod::UI.output = '' ::Pod::UI.output = ''
::Pod::UI.warnings = '' ::Pod::UI.warnings = ''
......
...@@ -69,7 +69,6 @@ module Pod ...@@ -69,7 +69,6 @@ module Pod
describe 'Subclasses helpers' do describe 'Subclasses helpers' do
it 'pre-downloads the Pod and stores the relevant information in the sandbox' do it 'pre-downloads the Pod and stores the relevant information in the sandbox' do
@subject.expects(:validate_podspec).with do |spec| @subject.expects(:validate_podspec).with do |spec|
spec.defined_in_file.should.be.nil
spec.name.should == 'Reachability' spec.name.should == 'Reachability'
end end
@subject.send(:pre_download, config.sandbox) @subject.send(:pre_download, config.sandbox)
......
...@@ -9,6 +9,7 @@ module Pod ...@@ -9,6 +9,7 @@ module Pod
} }
dep = Dependency.new('Reachability', params) dep = Dependency.new('Reachability', params)
@subject = ExternalSources.from_dependency(dep, nil, true) @subject = ExternalSources.from_dependency(dep, nil, true)
config.sandbox.specifications_root.mkpath
end end
it 'creates a copy of the podspec' do it 'creates a copy of the podspec' do
......
...@@ -7,6 +7,7 @@ module Pod ...@@ -7,6 +7,7 @@ module Pod
dependency = Dependency.new('Reachability', params) dependency = Dependency.new('Reachability', params)
podfile_path = fixture('integration/Podfile') podfile_path = fixture('integration/Podfile')
@subject = ExternalSources.from_dependency(dependency, podfile_path, true) @subject = ExternalSources.from_dependency(dependency, podfile_path, true)
config.sandbox.specifications_root.mkpath
end end
it 'creates a copy of the podspec' do it 'creates a copy of the podspec' do
......
...@@ -11,6 +11,7 @@ module Pod ...@@ -11,6 +11,7 @@ module Pod
end end
it 'creates a copy of the podspec' do it 'creates a copy of the podspec' do
config.sandbox.specifications_root.mkpath
@subject.fetch(config.sandbox) @subject.fetch(config.sandbox)
path = config.sandbox.specifications_root + 'Reachability.podspec.json' path = config.sandbox.specifications_root + 'Reachability.podspec.json'
path.should.exist? path.should.exist?
......
...@@ -713,7 +713,7 @@ module Pod ...@@ -713,7 +713,7 @@ module Pod
it 'does not include pod target if its used by tests only' do it 'does not include pod target if its used by tests only' do
spec1 = Resolver::ResolverSpecification.new(stub, true, nil) spec1 = Resolver::ResolverSpecification.new(stub, true, nil)
spec2 = Resolver::ResolverSpecification.new(stub, true, nil) spec2 = Resolver::ResolverSpecification.new(stub, true, nil)
target_definition = stub target_definition = stub('TargetDefinition')
pod_target = stub(:name => 'Pod1', :target_definitions => [target_definition], :specs => [spec1.spec, spec2.spec]) pod_target = stub(:name => 'Pod1', :target_definitions => [target_definition], :specs => [spec1.spec, spec2.spec])
resolver_specs_by_target = { target_definition => [spec1, spec2] } resolver_specs_by_target = { target_definition => [spec1, spec2] }
@analyzer.send(:filter_pod_targets_for_target_definition, target_definition, [pod_target], resolver_specs_by_target).should.be.empty @analyzer.send(:filter_pod_targets_for_target_definition, target_definition, [pod_target], resolver_specs_by_target).should.be.empty
...@@ -1040,6 +1040,7 @@ module Pod ...@@ -1040,6 +1040,7 @@ module Pod
@sandbox_manifest = Pod::Lockfile.new(@lockfile.internal_data.deep_dup) @sandbox_manifest = Pod::Lockfile.new(@lockfile.internal_data.deep_dup)
@analyzer.sandbox.manifest = @sandbox_manifest @analyzer.sandbox.manifest = @sandbox_manifest
@analyzer.sandbox.stubs(:specification).with('BananaLib').returns(stub) @analyzer.sandbox.stubs(:specification).with('BananaLib').returns(stub)
@analyzer.sandbox.stubs(:specification_path).with('BananaLib').returns(stub)
pod_dir = stub pod_dir = stub
pod_dir.stubs(:directory?).returns(true) pod_dir.stubs(:directory?).returns(true)
@analyzer.sandbox.stubs(:pod_dir).with('BananaLib').returns(pod_dir) @analyzer.sandbox.stubs(:pod_dir).with('BananaLib').returns(pod_dir)
......
...@@ -22,6 +22,7 @@ module Pod ...@@ -22,6 +22,7 @@ module Pod
options.integrate_targets = integrate_targets options.integrate_targets = integrate_targets
end end
sandbox.specifications_root.mkpath
@analyzer = Analyzer.new(sandbox, podfile, lockfile).tap do |analyzer| @analyzer = Analyzer.new(sandbox, podfile, lockfile).tap do |analyzer|
analyzer.installation_options = installation_options analyzer.installation_options = installation_options
end end
......
...@@ -35,7 +35,7 @@ def generate_local_podfile ...@@ -35,7 +35,7 @@ def generate_local_podfile
platform :ios platform :ios
project SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release project SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release
target 'SampleProject' do target 'SampleProject' do
pod 'Reachability', :path => SpecHelper.fixture('integration/Reachability') pod 'Reachability', :path => SpecHelper.fixture('integration/Reachability').to_s
target 'SampleProjectTests' do target 'SampleProjectTests' do
inherit! :search_paths inherit! :search_paths
end end
...@@ -734,5 +734,94 @@ module Pod ...@@ -734,5 +734,94 @@ module Pod
@installer.install! @installer.install!
end end
end end
#-------------------------------------------------------------------------#
describe '.targets_from_sandbox' do
it 'raises when there is no lockfile' do
sandbox = config.sandbox
podfile = generate_podfile
lockfile = nil
should.raise Informative do
Installer.targets_from_sandbox(sandbox, podfile, lockfile)
end.message.should.include 'You must run `pod install` to be able to generate target information'
end
it 'raises when the podfile has changed' do
sandbox = config.sandbox
podfile = generate_podfile(['AFNetworking'])
lockfile = generate_lockfile
should.raise Informative do
Installer.targets_from_sandbox(sandbox, podfile, lockfile)
end.message.should.include 'The Podfile has changed, you must run `pod install`'
end
it 'raises when the sandbox has changed' do
sandbox = config.sandbox
podfile = generate_podfile
lockfile = generate_lockfile
lockfile.internal_data['DEPENDENCIES'] = podfile.dependencies.map(&:to_s)
should.raise Informative do
Installer.targets_from_sandbox(sandbox, podfile, lockfile)
end.message.should.include 'The `Pods` directory is out-of-date, you must run `pod install`'
end
it 'returns the aggregate targets without performing installation' do
podfile = generate_podfile
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.expects(:integrate_user_project)
@installer.install!
::SpecHelper.reset_config_instance
aggregate_targets = Installer.targets_from_sandbox(config.sandbox, podfile, config.lockfile)
aggregate_targets.map(&:target_definition).should == [
podfile.target_definitions['SampleProject'], podfile.target_definitions['SampleProjectTests']
]
aggregate_targets.last.pod_targets.should == []
sample_project_target = aggregate_targets.first
sample_project_target.pod_targets.map(&:label).should == %w(JSONKit)
jsonkit = sample_project_target.pod_targets.first
jsonkit.sandbox.should == config.sandbox
jsonkit.file_accessors.flat_map(&:root).should == [config.sandbox.pod_dir('JSONKit')]
jsonkit.archs.should == []
end
it 'returns the aggregate targets without performing installation with local pods' do
podfile = generate_local_podfile
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.expects(:integrate_user_project)
@installer.install!
::SpecHelper.reset_config_instance
aggregate_targets = Installer.targets_from_sandbox(config.sandbox, podfile, config.lockfile)
aggregate_targets.map(&:target_definition).should == [
podfile.target_definitions['SampleProject'], podfile.target_definitions['SampleProjectTests']
]
aggregate_targets.last.pod_targets.should == []
sample_project_target = aggregate_targets.first
sample_project_target.pod_targets.map(&:label).should == %w(Reachability)
jsonkit = sample_project_target.pod_targets.first
jsonkit.sandbox.should == config.sandbox
jsonkit.file_accessors.flat_map(&:root).should == [config.sandbox.pod_dir('Reachability')]
jsonkit.archs.should == []
end
end
end end
end end
...@@ -470,9 +470,9 @@ module Pod ...@@ -470,9 +470,9 @@ module Pod
spec_names.should == %w( spec_names.should == %w(
Expecta MainSpec MainSpec/Tests Expecta MainSpec MainSpec/Tests
) )
resolved_specs.find { |rs| rs.name == 'Expecta' }.used_by_tests_only?.should.be.false resolved_specs.find { |rs| rs.name == 'Expecta' }.should.not.be.used_by_tests_only
resolved_specs.find { |rs| rs.name == 'MainSpec' }.used_by_tests_only?.should.be.false resolved_specs.find { |rs| rs.name == 'MainSpec' }.should.not.be.used_by_tests_only
resolved_specs.find { |rs| rs.name == 'MainSpec/Tests' }.used_by_tests_only?.should.be.true resolved_specs.find { |rs| rs.name == 'MainSpec/Tests' }.should.be.used_by_tests_only
end end
it 'allows pre-release spec versions when a requirement has an ' \ it 'allows pre-release spec versions when a requirement has an ' \
......
...@@ -38,6 +38,7 @@ module Pod ...@@ -38,6 +38,7 @@ module Pod
it 'cleans any trace of the Pod with the given name' do it 'cleans any trace of the Pod with the given name' do
pod_root = @sandbox.pod_dir('BananaLib') pod_root = @sandbox.pod_dir('BananaLib')
pod_root.mkpath pod_root.mkpath
@sandbox.specifications_root.mkpath
@sandbox.store_podspec('BananaLib', fixture('banana-lib/BananaLib.podspec')) @sandbox.store_podspec('BananaLib', fixture('banana-lib/BananaLib.podspec'))
specification_path = @sandbox.specification_path('BananaLib') specification_path = @sandbox.specification_path('BananaLib')
@sandbox.clean_pod('BananaLib') @sandbox.clean_pod('BananaLib')
...@@ -93,8 +94,12 @@ module Pod ...@@ -93,8 +94,12 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
describe 'Specification store' do describe 'Specification store' do
before do
# This is normally done in #prepare
@sandbox.specifications_root.mkdir
end
it 'loads the stored specification with the given name' do it 'loads the stored specification with the given name' do
(@sandbox.specifications_root).mkdir
FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.specifications_root) FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.specifications_root)
@sandbox.specification('BananaLib').name.should == 'BananaLib' @sandbox.specification('BananaLib').name.should == 'BananaLib'
end end
...@@ -102,13 +107,8 @@ module Pod ...@@ -102,13 +107,8 @@ module Pod
it 'loads the stored specification from the original path' do it 'loads the stored specification from the original path' do
spec_file = fixture('banana-lib/BananaLib.podspec') spec_file = fixture('banana-lib/BananaLib.podspec')
spec = Specification.from_file(spec_file) spec = Specification.from_file(spec_file)
Specification.expects(:from_file).with do
Dir.pwd == fixture('banana-lib').to_s
end.once.returns(spec)
Specification.expects(:from_file).with do |path| Specification.expects(:from_file).with(spec_file).once.returns(spec)
path == spec_file
end.once.returns(spec)
@sandbox.store_podspec('BananaLib', spec_file) @sandbox.store_podspec('BananaLib', spec_file)
@sandbox.store_local_path('BananaLib', spec_file) @sandbox.store_local_path('BananaLib', spec_file)
...@@ -121,7 +121,6 @@ module Pod ...@@ -121,7 +121,6 @@ module Pod
end end
it "returns the path to a spec file in the 'Local Podspecs' dir" do it "returns the path to a spec file in the 'Local Podspecs' dir" do
(@sandbox.root + 'Local Podspecs').mkdir
FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.root + 'Local Podspecs') FileUtils.cp(fixture('banana-lib/BananaLib.podspec'), @sandbox.root + 'Local Podspecs')
@sandbox.specification_path('BananaLib').should == @sandbox.specification_path('BananaLib').should ==
@sandbox.root + 'Local Podspecs/BananaLib.podspec' @sandbox.root + 'Local Podspecs/BananaLib.podspec'
......
...@@ -360,12 +360,14 @@ module Pod ...@@ -360,12 +360,14 @@ module Pod
s.ios.deployment_target = '7.0' s.ios.deployment_target = '7.0'
end end
validator.spec.stubs(:subspecs).returns([subspec]) validator.spec.stubs(:subspecs).returns([subspec])
validator.expects(:podfile_from_spec).with(:osx, nil, nil, []).once validator.expects(:podfile_from_spec).with(:osx, nil, nil, []).once.returns(stub('Podfile'))
validator.expects(:podfile_from_spec).with(:ios, nil, nil, []).once validator.expects(:podfile_from_spec).with(:ios, nil, nil, []).once.returns(stub('Podfile'))
validator.expects(:podfile_from_spec).with(:ios, '7.0', nil, []).once validator.expects(:podfile_from_spec).with(:ios, '7.0', nil, []).once.returns(stub('Podfile'))
validator.expects(:podfile_from_spec).with(:tvos, nil, nil, []).once validator.expects(:podfile_from_spec).with(:tvos, nil, nil, []).once.returns(stub('Podfile'))
validator.expects(:podfile_from_spec).with(:watchos, nil, nil, []).once validator.expects(:podfile_from_spec).with(:watchos, nil, nil, []).once.returns(stub('Podfile'))
validator.send(:perform_extensive_analysis, validator.spec) validator.send(:perform_extensive_analysis, validator.spec)
validator.results_message.strip.should.be.empty
end end
describe '#podfile_from_spec' do describe '#podfile_from_spec' do
...@@ -799,11 +801,13 @@ module Pod ...@@ -799,11 +801,13 @@ module Pod
setup_validator setup_validator
@validator.expects(:podfile_from_spec).with(:osx, nil, true, []).once @validator.expects(:podfile_from_spec).with(:osx, nil, true, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:ios, '8.0', true, []).once @validator.expects(:podfile_from_spec).with(:ios, '8.0', true, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:tvos, nil, true, []).once @validator.expects(:podfile_from_spec).with(:tvos, nil, true, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:watchos, nil, true, []).once @validator.expects(:podfile_from_spec).with(:watchos, nil, true, []).once.returns(stub('Podfile'))
@validator.send(:perform_extensive_analysis, @validator.spec) @validator.send(:perform_extensive_analysis, @validator.spec)
@validator.results_message.strip.should.be.empty
end end
it 'lint as a static library if specified' do it 'lint as a static library if specified' do
...@@ -811,11 +815,13 @@ module Pod ...@@ -811,11 +815,13 @@ module Pod
setup_validator setup_validator
@validator.expects(:podfile_from_spec).with(:osx, nil, false, []).once @validator.expects(:podfile_from_spec).with(:osx, nil, false, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:ios, nil, false, []).once @validator.expects(:podfile_from_spec).with(:ios, nil, false, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:tvos, nil, false, []).once @validator.expects(:podfile_from_spec).with(:tvos, nil, false, []).once.returns(stub('Podfile'))
@validator.expects(:podfile_from_spec).with(:watchos, nil, false, []).once @validator.expects(:podfile_from_spec).with(:watchos, nil, false, []).once.returns(stub('Podfile'))
@validator.send(:perform_extensive_analysis, @validator.spec) @validator.send(:perform_extensive_analysis, @validator.spec)
@validator.results_message.strip.should.be.empty
end end
it 'shows an error when performing extensive analysis on a test spec' do it 'shows an error when performing extensive analysis on a test spec' 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