Commit 7eb9ef04 authored by Danielle Tomlinson's avatar Danielle Tomlinson Committed by GitHub

Merge pull request #5984 from CocoaPods/dani_swift_version_errors

Improve handling of mismatched Swift versions
parents ca42ac95 76a76654
...@@ -28,6 +28,14 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -28,6 +28,14 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Ben Asher](https://github.com/benasher44) [Ben Asher](https://github.com/benasher44)
[#5959](https://github.com/CocoaPods/CocoaPods/pull/5959) [#5959](https://github.com/CocoaPods/CocoaPods/pull/5959)
* Error with helpful message when integrating a pod into targets that have mismatched Swift versions.
[Ben Asher](https://github.com/benasher44)
[#5984](https://github.com/CocoaPods/CocoaPods/pull/5984)
* Allow users to share pods between Objective-C and Swift targets.
[Danielle Tomlinson](https://github.com/dantoml)
[#5984](https://github.com/CocoaPods/CocoaPods/pull/5984)
##### Bug Fixes ##### Bug Fixes
* Remove special handling for messages apps * Remove special handling for messages apps
...@@ -42,6 +50,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -42,6 +50,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Stefan Pühringer](https://github.com/b-ray) [Stefan Pühringer](https://github.com/b-ray)
[#5891](https://github.com/CocoaPods/CocoaPods/issues/5891) [#5891](https://github.com/CocoaPods/CocoaPods/issues/5891)
## 1.1.0.rc.2 (2016-09-13) ## 1.1.0.rc.2 (2016-09-13)
##### Enhancements ##### Enhancements
......
GIT GIT
remote: https://github.com/CocoaPods/CLAide.git remote: https://github.com/CocoaPods/CLAide.git
revision: 61071679fc965083b6d43fdc1aa042afbaf172d1 revision: 8106d0d779ae1c9f571404a9f38950905ad5c803
branch: master branch: master
specs: specs:
claide (1.0.0) claide (1.0.0)
GIT GIT
remote: https://github.com/CocoaPods/Core.git remote: https://github.com/CocoaPods/Core.git
revision: fc8c258d0bce73e091f09de260a1a65bed3482a1 revision: fef34047643147b09955f8aeb1277a47d01ff1c1
branch: master branch: master
specs: specs:
cocoapods-core (1.1.0.rc.2) cocoapods-core (1.1.0.rc.2)
...@@ -24,7 +24,7 @@ GIT ...@@ -24,7 +24,7 @@ GIT
GIT GIT
remote: https://github.com/CocoaPods/Xcodeproj.git remote: https://github.com/CocoaPods/Xcodeproj.git
revision: c8b7277072c3c2432ac99ef9b45cd1a6d181409e revision: 4020ac913be863bdc4925fbb132aa94af71850f4
branch: master branch: master
specs: specs:
xcodeproj (1.3.1) xcodeproj (1.3.1)
......
...@@ -349,6 +349,7 @@ module Pod ...@@ -349,6 +349,7 @@ module Pod
# #
def generate_targets def generate_targets
specs_by_target = result.specs_by_target.reject { |td, _| td.abstract? } specs_by_target = result.specs_by_target.reject { |td, _| td.abstract? }
check_pod_target_swift_versions(specs_by_target)
pod_targets = generate_pod_targets(specs_by_target) pod_targets = generate_pod_targets(specs_by_target)
aggregate_targets = specs_by_target.keys.map do |target_definition| aggregate_targets = specs_by_target.keys.map do |target_definition|
generate_target(target_definition, pod_targets) generate_target(target_definition, pod_targets)
...@@ -406,6 +407,39 @@ module Pod ...@@ -406,6 +407,39 @@ module Pod
target target
end end
# Verify that targets using a pod have the same swift version
#
# @param [Hash{Podfile::TargetDefinition => Array<Specification>}] specs_by_target
# the resolved specifications grouped by target.
#
# @note raises Informative if targets using a pod do not have
# the same swift version
#
def check_pod_target_swift_versions(specs_by_target)
targets_by_spec = {}
specs_by_target.each do |target, specs|
specs.each do |spec|
(targets_by_spec[spec] ||= []) << target
end
end
error_message_for_target = lambda do |target|
"#{target.name} (Swift #{target.swift_version})"
end
error_messages = targets_by_spec.map do |spec, targets|
swift_targets = targets.reject { |target| target.swift_version.blank? }
next if swift_targets.empty? || swift_targets.uniq(&:swift_version).count == 1
target_errors = swift_targets.map(&error_message_for_target).join(', ')
"- #{spec.name} required by #{target_errors}"
end.compact
unless error_messages.empty?
raise Informative, 'The following pods are integrated into targets ' \
"that do not have the same Swift version:\n\n#{error_messages.join("\n")}"
end
end
# Setup the pod targets for an aggregate target. Deduplicates resulting # Setup the pod targets for an aggregate target. Deduplicates resulting
# targets by grouping by platform and subspec by their root # targets by grouping by platform and subspec by their root
# to create a {PodTarget} for each spec. # to create a {PodTarget} for each spec.
...@@ -420,7 +454,7 @@ module Pod ...@@ -420,7 +454,7 @@ module Pod
distinct_targets = specs_by_target.each_with_object({}) do |dependency, hash| distinct_targets = specs_by_target.each_with_object({}) do |dependency, hash|
target_definition, dependent_specs = *dependency target_definition, dependent_specs = *dependency
dependent_specs.group_by(&:root).each do |root_spec, specs| dependent_specs.group_by(&:root).each do |root_spec, specs|
pod_variant = PodVariant.new(specs, target_definition.platform, target_definition.uses_frameworks?, target_definition.swift_version) pod_variant = PodVariant.new(specs, target_definition.platform, target_definition.uses_frameworks?)
hash[root_spec] ||= {} hash[root_spec] ||= {}
(hash[root_spec][pod_variant] ||= []) << target_definition (hash[root_spec][pod_variant] ||= []) << target_definition
end end
......
...@@ -16,10 +16,6 @@ module Pod ...@@ -16,10 +16,6 @@ module Pod
attr_accessor :requires_frameworks attr_accessor :requires_frameworks
alias_method :requires_frameworks?, :requires_frameworks alias_method :requires_frameworks?, :requires_frameworks
# @return [String] the Swift version
#
attr_accessor :swift_version
# @return [Specification] the root specification # @return [Specification] the root specification
# #
def root_spec def root_spec
...@@ -32,11 +28,10 @@ module Pod ...@@ -32,11 +28,10 @@ module Pod
# @param [Platform] platform @see #platform # @param [Platform] platform @see #platform
# @param [Bool] requires_frameworks @see #requires_frameworks? # @param [Bool] requires_frameworks @see #requires_frameworks?
# #
def initialize(specs, platform, requires_frameworks = false, swift_version = nil) def initialize(specs, platform, requires_frameworks = false)
self.specs = specs self.specs = specs
self.platform = platform self.platform = platform
self.requires_frameworks = requires_frameworks self.requires_frameworks = requires_frameworks
self.swift_version = swift_version
end end
# @return [Bool] whether the {PodVariant} is equal to another taking all # @return [Bool] whether the {PodVariant} is equal to another taking all
...@@ -46,8 +41,7 @@ module Pod ...@@ -46,8 +41,7 @@ module Pod
self.class == other.class && self.class == other.class &&
specs == other.specs && specs == other.specs &&
platform == other.platform && platform == other.platform &&
requires_frameworks == other.requires_frameworks && requires_frameworks == other.requires_frameworks
swift_version == other.swift_version
end end
alias_method :eql?, :== alias_method :eql?, :==
...@@ -57,7 +51,7 @@ module Pod ...@@ -57,7 +51,7 @@ module Pod
# #
# @!visibility private # @!visibility private
def hash def hash
[specs, platform, requires_frameworks, swift_version].hash [specs, platform, requires_frameworks].hash
end end
end end
end end
......
require File.expand_path('../../../../spec_helper', __FILE__) require File.expand_path('../../../../spec_helper', __FILE__)
module Pod module Pod
describe PodVariant = Installer::Analyzer::PodVariant do class Installer
class Analyzer
describe PodVariant do
before do before do
@specs = [stub('Spec'), stub('Spec/Foo')] @specs = [stub('Spec'), stub('Spec/Foo')]
@platform = Platform.ios @platform = Platform.ios
...@@ -12,7 +14,6 @@ module Pod ...@@ -12,7 +14,6 @@ module Pod
variant.specs.should == @specs variant.specs.should == @specs
variant.platform.should == @platform variant.platform.should == @platform
variant.requires_frameworks.should == false variant.requires_frameworks.should == false
variant.swift_version.should.nil?
end end
it 'can be initialized with specs, platform and whether it requires frameworks' do it 'can be initialized with specs, platform and whether it requires frameworks' do
...@@ -20,15 +21,6 @@ module Pod ...@@ -20,15 +21,6 @@ module Pod
variant.specs.should == @specs variant.specs.should == @specs
variant.platform.should == @platform variant.platform.should == @platform
variant.requires_frameworks.should == true variant.requires_frameworks.should == true
variant.swift_version.should.nil?
end
it 'can be initialized with specs, platform, whether it requires frameworks, and a Swift version' do
variant = PodVariant.new(@specs, @platform, true, '2.3')
variant.specs.should == @specs
variant.platform.should == @platform
variant.requires_frameworks.should == true
variant.swift_version.should == '2.3'
end end
it 'can return the root spec' do it 'can return the root spec' do
...@@ -37,12 +29,11 @@ module Pod ...@@ -37,12 +29,11 @@ module Pod
variant.root_spec.should == spec variant.root_spec.should == spec
end end
it 'can be compared for equality with another variant with the same specs, platform, value for whether it requires frameworks and Swift version' do it 'can be compared for equality with another variant with the same specs, platform, and whether it requires frameworks' do
spec = PodVariant.new(@specs, @platform, false, '2.3') spec = PodVariant.new(@specs, @platform, false)
spec.should == PodVariant.new(@specs, @platform, false, '2.3') spec.should == PodVariant.new(@specs, @platform, false)
spec.should.not == PodVariant.new(@specs, @platform, false, '3.0') spec.should.not == PodVariant.new([@specs.first], @platform)
spec.should.not == PodVariant.new([@specs.first], @platform, false) spec.should.not == PodVariant.new(@specs, Platform.osx, false)
spec.should.not == PodVariant.new(@specs, Platform.osx, false, '2.3')
spec.should.not == PodVariant.new(@specs, @platform, true) spec.should.not == PodVariant.new(@specs, @platform, true)
end end
...@@ -56,4 +47,6 @@ module Pod ...@@ -56,4 +47,6 @@ module Pod
hash[k1].should == v1 hash[k1].should == v1
end end
end end
end
end
end end
...@@ -662,6 +662,40 @@ module Pod ...@@ -662,6 +662,40 @@ module Pod
should.raise(Informative) { analyzer.analyze } should.raise(Informative) { analyzer.analyze }
end end
it 'raises when targets integrate the same swift pod but have different swift versions' do
podfile = Podfile.new do
source SpecHelper.test_repo_url
project 'SampleProject/SampleProject'
platform :ios, '8.0'
pod 'OrangeFramework'
target 'SampleProject'
target 'TestRunner'
end
podfile.target_definitions['SampleProject'].stubs(:swift_version).returns('3.0')
podfile.target_definitions['TestRunner'].stubs(:swift_version).returns('2.3')
analyzer = Pod::Installer::Analyzer.new(config.sandbox, podfile)
should.raise Informative do
analyzer.analyze
end.message.should.match /The following pods are integrated into targets that do not have the same Swift version:/
end
it 'does not raise when targets integrate the same pod but only one of the targets is a swift target' do
podfile = Podfile.new do
source SpecHelper.test_repo_url
project 'SampleProject/SampleProject'
platform :ios, '8.0'
pod 'OrangeFramework'
target 'SampleProject'
target 'TestRunner'
end
podfile.target_definitions['SampleProject'].stubs(:swift_version).returns('3.0')
# when the swift version is unset at the project level, but set in one target, swift_version is nil
podfile.target_definitions['TestRunner'].stubs(:swift_version).returns(nil)
analyzer = Pod::Installer::Analyzer.new(config.sandbox, podfile)
lambda { analyzer.analyze }.should.not.raise
end
#--------------------------------------# #--------------------------------------#
it 'computes the state of the Sandbox respect to the resolved dependencies' do it 'computes the state of the Sandbox respect to the resolved dependencies' 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