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`
[Ben Asher](https://github.com/benasher44)
[#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
* Remove special handling for messages apps
......@@ -42,6 +50,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Stefan Pühringer](https://github.com/b-ray)
[#5891](https://github.com/CocoaPods/CocoaPods/issues/5891)
## 1.1.0.rc.2 (2016-09-13)
##### Enhancements
......
GIT
remote: https://github.com/CocoaPods/CLAide.git
revision: 61071679fc965083b6d43fdc1aa042afbaf172d1
revision: 8106d0d779ae1c9f571404a9f38950905ad5c803
branch: master
specs:
claide (1.0.0)
GIT
remote: https://github.com/CocoaPods/Core.git
revision: fc8c258d0bce73e091f09de260a1a65bed3482a1
revision: fef34047643147b09955f8aeb1277a47d01ff1c1
branch: master
specs:
cocoapods-core (1.1.0.rc.2)
......@@ -24,7 +24,7 @@ GIT
GIT
remote: https://github.com/CocoaPods/Xcodeproj.git
revision: c8b7277072c3c2432ac99ef9b45cd1a6d181409e
revision: 4020ac913be863bdc4925fbb132aa94af71850f4
branch: master
specs:
xcodeproj (1.3.1)
......
......@@ -349,6 +349,7 @@ module Pod
#
def generate_targets
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)
aggregate_targets = specs_by_target.keys.map do |target_definition|
generate_target(target_definition, pod_targets)
......@@ -406,6 +407,39 @@ module Pod
target
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
# targets by grouping by platform and subspec by their root
# to create a {PodTarget} for each spec.
......@@ -420,7 +454,7 @@ module Pod
distinct_targets = specs_by_target.each_with_object({}) do |dependency, hash|
target_definition, dependent_specs = *dependency
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][pod_variant] ||= []) << target_definition
end
......
......@@ -16,10 +16,6 @@ module Pod
attr_accessor :requires_frameworks
alias_method :requires_frameworks?, :requires_frameworks
# @return [String] the Swift version
#
attr_accessor :swift_version
# @return [Specification] the root specification
#
def root_spec
......@@ -32,11 +28,10 @@ module Pod
# @param [Platform] platform @see #platform
# @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.platform = platform
self.requires_frameworks = requires_frameworks
self.swift_version = swift_version
end
# @return [Bool] whether the {PodVariant} is equal to another taking all
......@@ -46,8 +41,7 @@ module Pod
self.class == other.class &&
specs == other.specs &&
platform == other.platform &&
requires_frameworks == other.requires_frameworks &&
swift_version == other.swift_version
requires_frameworks == other.requires_frameworks
end
alias_method :eql?, :==
......@@ -57,7 +51,7 @@ module Pod
#
# @!visibility private
def hash
[specs, platform, requires_frameworks, swift_version].hash
[specs, platform, requires_frameworks].hash
end
end
end
......
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
describe PodVariant = Installer::Analyzer::PodVariant do
class Installer
class Analyzer
describe PodVariant do
before do
@specs = [stub('Spec'), stub('Spec/Foo')]
@platform = Platform.ios
......@@ -12,7 +14,6 @@ module Pod
variant.specs.should == @specs
variant.platform.should == @platform
variant.requires_frameworks.should == false
variant.swift_version.should.nil?
end
it 'can be initialized with specs, platform and whether it requires frameworks' do
......@@ -20,15 +21,6 @@ module Pod
variant.specs.should == @specs
variant.platform.should == @platform
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
it 'can return the root spec' do
......@@ -37,12 +29,11 @@ module Pod
variant.root_spec.should == spec
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
spec = PodVariant.new(@specs, @platform, false, '2.3')
spec.should == PodVariant.new(@specs, @platform, false, '2.3')
spec.should.not == PodVariant.new(@specs, @platform, false, '3.0')
spec.should.not == PodVariant.new([@specs.first], @platform, false)
spec.should.not == PodVariant.new(@specs, Platform.osx, false, '2.3')
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)
spec.should == PodVariant.new(@specs, @platform, false)
spec.should.not == PodVariant.new([@specs.first], @platform)
spec.should.not == PodVariant.new(@specs, Platform.osx, false)
spec.should.not == PodVariant.new(@specs, @platform, true)
end
......@@ -56,4 +47,6 @@ module Pod
hash[k1].should == v1
end
end
end
end
end
......@@ -662,6 +662,40 @@ module Pod
should.raise(Informative) { analyzer.analyze }
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
......
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