Commit 956d569e authored by Hugo Tunius's avatar Hugo Tunius

[Podfile] Add validations in an attempt to catch issues common issue when…

[Podfile] Add validations in an attempt to catch issues common issue when specifying the dependencies for a project
parent 78c6f0e6
......@@ -54,6 +54,11 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
* Cache globbing in `PathList` to speed up `pod install`.
[Vincent Isambart](https://github.com/vincentisambart)
* CocoaPods will validate your podfile and try to identify problems
and conflicts in how you've specified the dependencies
[Hugo Tunius](https://github.com/k0nserv)
[#995](https://github.com/CocoaPods/CocoaPods/issues/995)
##### Bug Fixes
* Added recursive support to the public headers of vendored frameworks
......
......@@ -34,6 +34,7 @@ module Pod
autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context'
autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
autoload :Migrator, 'cocoapods/installer/migrator'
autoload :PodfileValidator, 'cocoapods/installer/podfile_validator'
autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
autoload :PodSourcePreparer, 'cocoapods/installer/pod_source_preparer'
autoload :PodTargetInstaller, 'cocoapods/installer/target_installer/pod_target_installer'
......
......@@ -52,6 +52,7 @@ module Pod
# @return [AnalysisResult]
#
def analyze(allow_fetches = true)
validate_podfile!
validate_lockfile_version!
@result = AnalysisResult.new
compute_target_platforms
......@@ -143,6 +144,15 @@ module Pod
private
def validate_podfile!
validator = Installer::PodfileValidator.new(podfile)
validator.validate
unless validator.valid?
raise Informative, validator.message
end
end
# @!group Analysis steps
# @note The warning about the version of the Lockfile doesn't use the
......
module Pod
class Installer
# Validate the podfile before installing to catch errors and
# problems
#
class PodfileValidator
# @return [Podfile] The podfile being validated
#
attr_reader :podfile
# @return [Array<String>] any errors that have occured during the validation
#
attr_reader :errors
# Initialize a new instance
# @param [Podfile] podfile
# The podfile to validate
#
def initialize(podfile)
@podfile = podfile
@errors = []
@validated = false
end
# Validate the podfile
# Errors are added to the errors array
#
def validate
validate_pod_directives
@validated = true
end
# Wether the podfile is valid is not
# NOTE: Will execute `validate` if the podfile
# has not yet been validated
#
def valid?
validate unless @validated
@validated && errors.size == 0
end
# A message describing any errors in the
# validation
#
def message
errors.join("\n")
end
private
def add_error(error)
errors << error
end
def validate_pod_directives
dependencies = podfile.target_definitions.flat_map do |_, target|
target.dependencies
end.uniq
dependencies.each do |dependency|
validate_conflicting_external_sources!(dependency)
end
end
def validate_conflicting_external_sources!(dependency)
external_source = dependency.external_source
return false if external_source.nil?
available_downloaders = Downloader.downloader_class_by_key.keys
specified_downloaders = external_source.select { |key| available_downloaders.include?(key) }
if specified_downloaders.size > 1
add_error "The dependency `#{dependency.name}` specifies more than one download strategy(#{specified_downloaders.keys.join(',')})." \
'Only one is allowed'
end
pod_spec_or_path = external_source[:podspec].present? || external_source[:path].present?
if pod_spec_or_path && specified_downloaders.size > 0
add_error "The dependency `#{dependency.name}` specifies `podspec` or `path` in combination with other" \
' download strategies. This is not allowed'
end
end
end
end
end
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Installer::PodfileValidator do
describe 'podspec/path in combination with other download strategies' do
it 'validates that podspec is not used in combination with other download strategies' do
podfile = Pod::Podfile.new do
pod 'JSONKit', :podspec => 'https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git'
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.valid?.should.be.false
validator.errors.size.should == 1
validator.errors[0].should.match /The dependency `JSONKit` specifies `podspec` or `path`/
end
it 'validates that path is not used in combination with other download strategies' do
podfile = Pod::Podfile.new do
pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git'
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.valid?.should.be.false
validator.errors.size.should == 1
validator.errors[0].should.match /The dependency `JSONKit` specifies `podspec` or `path`/
end
it 'validates when calling `valid?` before calling `validate`' do
podfile = Pod::Podfile.new do
pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git'
end
validator = Installer::PodfileValidator.new(podfile)
validator.valid?
validator.valid?.should.be.false
end
end
describe 'multiple download strategies' do
it 'validates that only one download strategy is specified' do
podfile = Pod::Podfile.new do
pod 'JSONKit', :svn => 'svn.example.com/JSONKit',
:git => 'git@github.com:johnezang/JSONKit.git'
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.valid?.should.be.false
validator.errors.size.should == 1
validator.errors[0].should.match /The dependency `JSONKit` specifies more than one/
end
end
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