Commit 9cc30d15 authored by Samuel E. Giddins's avatar Samuel E. Giddins

Merge pull request #3713 from CocoaPods/seg-resolver-platform

[Resolver] Take supported platforms into account when resolving
parents e9ef020c 4e0dbfe4
...@@ -4,6 +4,16 @@ To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides ...@@ -4,6 +4,16 @@ To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides
To install release candidates run `[sudo] gem install cocoapods --pre` To install release candidates run `[sudo] gem install cocoapods --pre`
## Master
##### Enhancements
* The resolver will now take supported platform deployment targets into account
when resolving dependencies.
[Samuel Giddins](https://github.com/segiddins)
[#2443](https://github.com/CocoaPods/CocoaPods/issues/2443)
## 0.38.0.beta.1 ## 0.38.0.beta.1
##### Highlighted Enhancement That Needs Testing ##### Highlighted Enhancement That Needs Testing
......
...@@ -37,6 +37,7 @@ module Pod ...@@ -37,6 +37,7 @@ module Pod
@podfile = podfile @podfile = podfile
@locked_dependencies = locked_dependencies @locked_dependencies = locked_dependencies
@sources = Array(sources) @sources = Array(sources)
@platforms_by_dependency = Hash.new { |h, k| h[k] = [] }
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
...@@ -52,7 +53,11 @@ module Pod ...@@ -52,7 +53,11 @@ module Pod
# definition. # definition.
# #
def resolve def resolve
dependencies = podfile.target_definition_list.map(&:dependencies).flatten dependencies = podfile.target_definition_list.flat_map do |target|
target.dependencies.each do |dep|
@platforms_by_dependency[dep].push(target.platform).uniq!
end
end
@cached_sets = {} @cached_sets = {}
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies) @activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
specs_by_target.tap do |specs_by_target| specs_by_target.tap do |specs_by_target|
...@@ -181,7 +186,7 @@ module Pod ...@@ -181,7 +186,7 @@ module Pod
requirement_satisfied && !( requirement_satisfied && !(
spec.version.prerelease? && spec.version.prerelease? &&
existing_vertices.flat_map(&:requirements).none? { |r| r.prerelease? || r.external_source || r.head? } existing_vertices.flat_map(&:requirements).none? { |r| r.prerelease? || r.external_source || r.head? }
) ) && spec_is_platform_compatible?(activated, requirement, spec)
end end
# 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.
...@@ -395,6 +400,31 @@ module Pod ...@@ -395,6 +400,31 @@ module Pod
raise Informative, error.message raise Informative, error.message
end end
# Returns whether the given spec is platform-compatible with the dependency
# graph, taking into account the dependency that has required the spec.
#
# @param [Molinillo::DependencyGraph] dependency_graph
#
# @param [Dependency] dependency
#
# @param [Specification] specification
#
# @return [Bool]
def spec_is_platform_compatible?(dependency_graph, dependency, spec)
all_predecessors = ->(vertex) do
pred = vertex.predecessors
pred + pred.map(&all_predecessors).reduce(Set.new, &:&) << vertex
end
vertex = dependency_graph.vertex_named(dependency.name)
predecessors = all_predecessors[vertex].reject { |v| v.explicit_requirements.empty? }
platforms_to_satisfy = predecessors.flat_map(&:explicit_requirements).flat_map { |r| @platforms_by_dependency[r] }
platforms_to_satisfy.all? do |platform_to_satisfy|
spec.available_platforms.select { |spec_platform| spec_platform.name == platform_to_satisfy.name }.
all? { |spec_platform| platform_to_satisfy.supports?(spec_platform) }
end
end
# Returns the target-appropriate nodes that are `successors` of `node`, # Returns the target-appropriate nodes that are `successors` of `node`,
# rejecting those that are scoped by target platform and have incompatible # rejecting those that are scoped by target platform and have incompatible
# targets. # targets.
......
...@@ -328,12 +328,6 @@ module Pod ...@@ -328,12 +328,6 @@ module Pod
] ]
end end
it 'warns once any of the dependencies does not match the platform of its podfile target' do
Specification.any_instance.stubs(:available_platforms).returns([Platform.new(:ios, '999')])
@analyzer.analyze
UI.warnings.should.match(/platform .* may not be compatible/)
end
xit 'removes the specifications of the changed pods to prevent confusion in the resolution process' do xit 'removes the specifications of the changed pods to prevent confusion in the resolution process' do
@analyzer.allow_pre_downloads = true @analyzer.allow_pre_downloads = true
podspec = @analyzer.sandbox.root + 'Local Podspecs/JSONKit.podspec' podspec = @analyzer.sandbox.root + 'Local Podspecs/JSONKit.podspec'
......
...@@ -180,6 +180,17 @@ module Pod ...@@ -180,6 +180,17 @@ module Pod
end.message.should.match /platform .* not compatible/ end.message.should.match /platform .* not compatible/
end end
it 'selects only platform-compatible versions' do
@podfile = Podfile.new do
platform :osx, '10.7'
pod 'AFNetworking' # the most recent version requires 10.8
end
@resolver.stubs(:podfile).returns(@podfile)
@resolver.resolve.values.flatten.map(&:to_s).sort.should == [
'AFNetworking (1.3.4)',
]
end
it 'raises if unable to find a specification' do it 'raises if unable to find a specification' do
Specification.any_instance.stubs(:all_dependencies).returns([Dependency.new('Windows')]) Specification.any_instance.stubs(:all_dependencies).returns([Dependency.new('Windows')])
message = should.raise Informative do message = should.raise Informative do
...@@ -340,7 +351,7 @@ module Pod ...@@ -340,7 +351,7 @@ module Pod
it 'raises if it finds two conflicting dependencies' do it 'raises if it finds two conflicting dependencies' do
podfile = Podfile.new do podfile = Podfile.new do
platform :ios platform :ios, '8.0'
pod 'RestKit', '0.23.3' # dependends on AFNetworking ~> 1.3.0 pod 'RestKit', '0.23.3' # dependends on AFNetworking ~> 1.3.0
pod 'AFNetworking', '> 2' pod 'AFNetworking', '> 2'
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment