Integrate `swift_version` DSL support into pod targets
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dbe1d10..269d361 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@
##### Enhancements
+* Integrate `swift_version` DSL support into pod targets.
+ [Dimitris Koutsogiorgas](https://github.com/dnkoutso)
+ [#7134](https://github.com/CocoaPods/CocoaPods/issues/7134)
+
* Add color indication to output of `pod outdated`
[iv-mexx](https://github.com/iv-mexx)
[#7204](https://github.com/CocoaPods/CocoaPods/pull/7204)
diff --git a/lib/cocoapods/target/pod_target.rb b/lib/cocoapods/target/pod_target.rb
index 3df5578..bffbca5 100644
--- a/lib/cocoapods/target/pod_target.rb
+++ b/lib/cocoapods/target/pod_target.rb
@@ -95,10 +95,12 @@
end
end
- # @return [String] the Swift version for the target.
+ # @return [String] the Swift version for the target. If the pod author has provided a swift version
+ # then that is the one returned, otherwise the Swift version is determined by the user
+ # targets that include this pod target.
#
def swift_version
- target_definitions.map(&:swift_version).compact.uniq.first
+ root_spec.swift_version || target_definitions.map(&:swift_version).compact.uniq.first
end
# @note The deployment target for the pod target is the maximum of all
diff --git a/lib/cocoapods/validator.rb b/lib/cocoapods/validator.rb
index acb37d9..2a13f44 100644
--- a/lib/cocoapods/validator.rb
+++ b/lib/cocoapods/validator.rb
@@ -395,19 +395,39 @@
# Performs validation for which version of Swift is used during validation.
#
+ #
+ #
# The user will be warned that the default version of Swift was used if the following things are true:
# - The project uses Swift at all
# - The user did not supply a Swift version via a parameter
+ # - There is no `swift_version` attribute set within the specification
# - There is no `.swift-version` file present either.
#
def validate_swift_version
- if uses_swift? && @swift_version.nil? && dot_swift_version.nil?
- warning(:swift_version,
- 'The validator used ' \
- "Swift #{DEFAULT_SWIFT_VERSION} by default because no Swift version was specified. " \
- 'If you want to use a different version of Swift during validation, then either use the `--swift-version` parameter ' \
- 'or use a `.swift-version` file to set the version of Swift to use for ' \
- 'your Pod. For example to use Swift 4.0, run: `echo "4.0" > .swift-version`.')
+ return unless uses_swift?
+ spec_swift_version = spec.swift_version
+ unless spec_swift_version.nil?
+ message = nil
+ if !dot_swift_version.nil? && dot_swift_version != spec_swift_version
+ message = "Specification `#{spec.name}` specifies an inconsistent `swift_version` (`#{spec_swift_version}`) compared to the one present in your `.swift-version` file (`#{dot_swift_version}`). " \
+ 'Please update your `.swift-version` file or remove it and replace with the `swift_version` attribute within your podspec.'
+ elsif !@swift_version.nil? && @swift_version != spec_swift_version
+ message = "Specification `#{spec.name}` specifies an inconsistent `swift_version` (`#{spec_swift_version}`) compared to the one passed during lint (`#{@swift_version}`)."
+ end
+ unless message.nil?
+ error('swift', message)
+ return
+ end
+ end
+ if spec_swift_version.nil? && @swift_version.nil? && dot_swift_version.nil?
+ warning('swift',
+ 'The validator used ' \
+ "Swift #{DEFAULT_SWIFT_VERSION} by default because no Swift version was specified. " \
+ 'If you want to use a different version of Swift during validation, then either specify a `swift_version` attribute in your podspec, ' \
+ 'use the `--swift-version` parameter during lint ' \
+ 'or use a `.swift-version` file to set the version of Swift to use for ' \
+ 'your Pod. For example to use Swift 4.0, run: `echo "4.0" > .swift-version`.')
+
end
end
diff --git a/spec/unit/target/pod_target_spec.rb b/spec/unit/target/pod_target_spec.rb
index 531e2ce..dd4ec2f 100644
--- a/spec/unit/target/pod_target_spec.rb
+++ b/spec/unit/target/pod_target_spec.rb
@@ -144,6 +144,20 @@
end
end
+ describe 'swift version' do
+ it 'uses the swift version defined by the specification if one is specified in the spec' do
+ @pod_target.root_spec.stubs(:swift_version).returns('3.0')
+ @target_definition.stubs(:swift_version).returns('2.3')
+ @pod_target.swift_version.should == '3.0'
+ end
+
+ it 'uses the swift version defined by the target definitions if no swift version is specifed in the spec' do
+ @pod_target.root_spec.stubs(:swift_version).returns(nil)
+ @target_definition.stubs(:swift_version).returns('2.3')
+ @pod_target.swift_version.should == '2.3'
+ end
+ end
+
describe 'Support files' do
it 'returns the absolute path of the xcconfig file' do
@pod_target.xcconfig_path('Release').to_s.should.include?(
diff --git a/spec/unit/validator_spec.rb b/spec/unit/validator_spec.rb
index 8c73b90..77cefc8 100644
--- a/spec/unit/validator_spec.rb
+++ b/spec/unit/validator_spec.rb
@@ -887,11 +887,59 @@
result.type.should == :warning
result.message.should == 'The validator used ' \
'Swift 3.2 by default because no Swift version was specified. ' \
- 'If you want to use a different version of Swift during validation, then either use the `--swift-version` parameter ' \
+ 'If you want to use a different version of Swift during validation, then either specify a `swift_version` attribute in your podspec, ' \
+ 'use the `--swift-version` parameter during lint ' \
'or use a `.swift-version` file to set the version of Swift to use for ' \
'your Pod. For example to use Swift 4.0, run: `echo "4.0" > .swift-version`.'
end
+ it 'errors when swift version spec attribute does not match dot swift version' do
+ Specification.any_instance.stubs(:deployment_target).returns('9.0')
+ Specification.any_instance.stubs(:swift_version).returns('4.0')
+
+ validator = test_swiftpod_with_dot_swift_version('3.2')
+ validator.validate
+ validator.results.count.should == 1
+
+ result = validator.results.first
+ result.type.should == :error
+ result.message.should == 'Specification `JSONKit` specifies an inconsistent `swift_version` (`4.0`) compared to the one present in your `.swift-version` file (`3.2`). ' \
+ 'Please update your `.swift-version` file or remove it and replace with the `swift_version` attribute within your podspec.'
+ end
+
+ it 'does not error when swift version spec attribute matches dot swift version' do
+ Specification.any_instance.stubs(:deployment_target).returns('9.0')
+ Specification.any_instance.stubs(:swift_version).returns('4.0')
+
+ validator = test_swiftpod_with_dot_swift_version('4.0')
+ validator.validate
+ validator.results.count.should == 0
+ end
+
+ it 'errors when swift version spec attribute does not match parameter based swift version' do
+ Specification.any_instance.stubs(:deployment_target).returns('9.0')
+ Specification.any_instance.stubs(:swift_version).returns('4.0')
+
+ validator = test_swiftpod
+ validator.swift_version = '3.2'
+ validator.validate
+ validator.results.count.should == 1
+
+ result = validator.results.first
+ result.type.should == :error
+ result.message.should == 'Specification `JSONKit` specifies an inconsistent `swift_version` (`4.0`) compared to the one passed during lint (`3.2`).'
+ end
+
+ it 'does not error when swift version spec attribute matches parameter based swift version' do
+ Specification.any_instance.stubs(:deployment_target).returns('9.0')
+ Specification.any_instance.stubs(:swift_version).returns('4.0')
+
+ validator = test_swiftpod
+ validator.swift_version = '4.0'
+ validator.validate
+ validator.results.count.should == 0
+ end
+
it 'does not warn for Swift if version was set by a dot swift version file' do
Specification.any_instance.stubs(:deployment_target).returns('9.0')