Commit 13a07afe authored by Samuel E. Giddins's avatar Samuel E. Giddins

Validate that a specification's `public_header_files` and `private_header_files`…

Validate that a specification's `public_header_files` and `private_header_files` file patterns only match header files.
Also, validate that all file patterns, if given, match at least one file.
parent e588d2c2
...@@ -27,6 +27,12 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -27,6 +27,12 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Samuel Giddins](https://github.com/segiddins) [Samuel Giddins](https://github.com/segiddins)
[#2623](https://github.com/CocoaPods/CocoaPods/issues/2623) [#2623](https://github.com/CocoaPods/CocoaPods/issues/2623)
* Validate that a specification's `public_header_files` and
`private_header_files` file patterns only match header files.
Also, validate that all file patterns, if given, match at least one file.
[Samuel Giddins](https://github.com/segiddins)
[#2914](https://github.com/CocoaPods/CocoaPods/issues/2914)
##### Bug Fixes ##### Bug Fixes
* Fix updating a pod that has subspec dependencies. * Fix updating a pod that has subspec dependencies.
......
...@@ -113,8 +113,8 @@ module Pod ...@@ -113,8 +113,8 @@ module Pod
# @return [Array<Pathname>] the public headers of the specification. # @return [Array<Pathname>] the public headers of the specification.
# #
def public_headers(include_frameworks = false) def public_headers(include_frameworks = false)
public_headers = paths_for_attribute(:public_header_files) public_headers = public_header_files
private_headers = paths_for_attribute(:private_header_files) private_headers = private_header_files
if public_headers.nil? || public_headers.empty? if public_headers.nil? || public_headers.empty?
header_files = headers header_files = headers
else else
...@@ -210,6 +210,26 @@ module Pod ...@@ -210,6 +210,26 @@ module Pod
private private
# @!group Private paths
# @return [Array<Pathname>] The paths of the user-specified public header
# files.
#
def public_header_files
paths_for_attribute(:public_header_files)
end
# @return [Array<Pathname>] The paths of the user-specified public header
# files.
#
def private_header_files
paths_for_attribute(:private_header_files)
end
#-----------------------------------------------------------------------#
private
# @!group Private helpers # @!group Private helpers
# Returns the list of the paths founds in the file system for the # Returns the list of the paths founds in the file system for the
......
...@@ -350,6 +350,10 @@ module Pod ...@@ -350,6 +350,10 @@ module Pod
end end
end end
FILE_PATTERNS = %i(source_files resources preserve_paths vendored_libraries
vendored_frameworks public_header_files preserve_paths
private_header_files resource_bundles).freeze
# It checks that every file pattern specified in a spec yields # It checks that every file pattern specified in a spec yields
# at least one file. It requires the pods to be already present # at least one file. It requires the pods to be already present
# in the current working directory under Pods/spec.name. # in the current working directory under Pods/spec.name.
...@@ -357,8 +361,11 @@ module Pod ...@@ -357,8 +361,11 @@ module Pod
# @return [void] # @return [void]
# #
def check_file_patterns def check_file_patterns
[:source_files, :resources, :preserve_paths, :vendored_libraries, :vendored_frameworks].each do |attr_name| FILE_PATTERNS.each do |attr_name|
# file_attr = Specification::DSL.attributes.values.find{|attr| attr.name == attr_name } if respond_to?("_validate_#{attr_name}", true)
send("_validate_#{attr_name}")
end
if !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty? if !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty?
error('file patterns', "The `#{attr_name}` pattern did not match any file.") error('file patterns', "The `#{attr_name}` pattern did not match any file.")
end end
...@@ -371,6 +378,25 @@ module Pod ...@@ -371,6 +378,25 @@ module Pod
end end
end end
def _validate_private_header_files
_validate_header_files(:private_header_files)
end
def _validate_public_header_files
_validate_header_files(:public_header_files)
end
# Ensures that a list of header files only contains header files.
#
def _validate_header_files(attr_name)
non_header_files = file_accessor.send(attr_name).
select { |f| !Xcodeproj::Constants::HEADER_FILES_EXTENSIONS.include?(f.extname) }.
map { |f| f.relative_path_from file_accessor.root }
unless non_header_files.empty?
error(attr_name, "The pattern matches non-header files (#{non_header_files.join(', ')}).")
end
end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
private private
......
...@@ -337,14 +337,36 @@ module Pod ...@@ -337,14 +337,36 @@ module Pod
sut.results.count.should == 0 sut.results.count.should == 0
end end
it 'checks for file patterns' do describe 'file pattern validation' do
file = write_podspec(stub_podspec(/.*source_files.*/, '"source_files": "wrong_paht.*",')) it 'checks for file patterns' do
sut = Validator.new(file, SourcesManager.master.map(&:url)) file = write_podspec(stub_podspec(/.*source_files.*/, '"source_files": "wrong_paht.*",'))
sut.stubs(:build_pod) sut = Validator.new(file, SourcesManager.master.map(&:url))
sut.stubs(:validate_url) sut.stubs(:build_pod)
sut.validate sut.stubs(:validate_url)
sut.results.map(&:to_s).first.should.match /source_files.*did not match/ sut.validate
sut.result_type.should == :error sut.results.map(&:to_s).first.should.match /source_files.*did not match/
sut.result_type.should == :error
end
it 'checks private_header_files matches only headers' do
file = write_podspec(stub_podspec(/.*source_files.*/, '"source_files": "JSONKit.*", "private_header_files": "JSONKit.m",'))
sut = Validator.new(file, SourcesManager.master.map(&:url))
sut.stubs(:build_pod)
sut.stubs(:validate_url)
sut.validate
sut.results.map(&:to_s).first.should.match /matches non-header files \(JSONKit\.m\)/
sut.result_type.should == :error
end
it 'checks public_header_files matches only headers' do
file = write_podspec(stub_podspec(/.*source_files.*/, '"source_files": "JSONKit.*", "public_header_files": "JSONKit.m",'))
sut = Validator.new(file, SourcesManager.master.map(&:url))
sut.stubs(:build_pod)
sut.stubs(:validate_url)
sut.validate
sut.results.map(&:to_s).first.should.match /matches non-header files \(JSONKit\.m\)/
sut.result_type.should == :error
end
end end
it 'validates a podspec with dependencies' do it 'validates a podspec with 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