Commit c14c319a authored by Fabio Pelosin's avatar Fabio Pelosin

[Validator] Check the homepage of the spec

Thanks @dlackty
parent 47ccbc22
...@@ -18,8 +18,10 @@ To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides ...@@ -18,8 +18,10 @@ To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides
[Robert Zuber](https://github.com/z00b) [Robert Zuber](https://github.com/z00b)
[#1617](https://github.com/CocoaPods/CocoaPods/issues/1617) [#1617](https://github.com/CocoaPods/CocoaPods/issues/1617)
* The linter will now check the homepage of Podspecs. * The linter will now check the reachability of the homepage of Podspecs during
a full lint.
[Richard Lee](https://github.com/dlackty) [Richard Lee](https://github.com/dlackty)
[Fabio Pelosin](https://github.com/irrationalfab)
[#1704](https://github.com/CocoaPods/CocoaPods/issues/1704) [#1704](https://github.com/CocoaPods/CocoaPods/issues/1704)
[Core#70](https://github.com/CocoaPods/Core/pull/70) [Core#70](https://github.com/CocoaPods/Core/pull/70)
......
...@@ -14,11 +14,12 @@ group :development do ...@@ -14,11 +14,12 @@ group :development do
gem 'claide', :git => 'https://github.com/CocoaPods/CLAide.git', :branch => 'master' gem 'claide', :git => 'https://github.com/CocoaPods/CLAide.git', :branch => 'master'
gem 'cocoapods-try', :git => 'https://github.com/CocoaPods/cocoapods-try.git', :branch => 'master' gem 'cocoapods-try', :git => 'https://github.com/CocoaPods/cocoapods-try.git', :branch => 'master'
gem 'rake', '~> 10.1.0' # Ruby 1.8.7
gem "mocha" gem "mocha"
gem "bacon" gem "bacon"
gem "mocha-on-bacon" gem "mocha-on-bacon"
gem 'prettybacon', :git => 'https://github.com/irrationalfab/PrettyBacon.git', :branch => 'master' gem 'prettybacon', :git => 'https://github.com/irrationalfab/PrettyBacon.git', :branch => 'master'
gem 'rake', '~> 10.1.0' # Ruby 1.8.7 gem 'webmock', "< 1.16"
# For the integration tests # For the integration tests
gem "diffy" gem "diffy"
......
...@@ -7,7 +7,7 @@ GIT ...@@ -7,7 +7,7 @@ GIT
GIT GIT
remote: https://github.com/CocoaPods/Core.git remote: https://github.com/CocoaPods/Core.git
revision: 7af0d1097b00248e37576101f9330cb959fb5f9f revision: 893a329a2c5faeec17cb0b9b4f31ef255f48dbec
branch: master branch: master
specs: specs:
cocoapods-core (0.30.0) cocoapods-core (0.30.0)
...@@ -93,6 +93,7 @@ GEM ...@@ -93,6 +93,7 @@ GEM
activesupport (3.2.17) activesupport (3.2.17)
i18n (~> 0.6, >= 0.6.4) i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0) multi_json (~> 1.0)
addressable (2.3.6)
awesome_print (1.2.0) awesome_print (1.2.0)
bacon (1.2.0) bacon (1.2.0)
coderay (1.1.0) coderay (1.1.0)
...@@ -103,6 +104,8 @@ GEM ...@@ -103,6 +104,8 @@ GEM
simplecov (>= 0.7) simplecov (>= 0.7)
term-ansicolor term-ansicolor
thor thor
crack (0.4.2)
safe_yaml (~> 1.0.0)
diffy (3.0.3) diffy (3.0.3)
docile (1.1.3) docile (1.1.3)
escape (0.0.4) escape (0.0.4)
...@@ -145,6 +148,7 @@ GEM ...@@ -145,6 +148,7 @@ GEM
redcarpet (2.3.0) redcarpet (2.3.0)
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
safe_yaml (1.0.1)
simplecov (0.8.2) simplecov (0.8.2)
docile (~> 1.1.0) docile (~> 1.1.0)
multi_json multi_json
...@@ -155,6 +159,9 @@ GEM ...@@ -155,6 +159,9 @@ GEM
tins (~> 1.0) tins (~> 1.0)
thor (0.19.1) thor (0.19.1)
tins (1.0.1) tins (1.0.1)
webmock (1.15.2)
addressable (>= 2.2.7)
crack (>= 0.3.2)
yajl-ruby (1.1.0) yajl-ruby (1.1.0)
yard (0.8.7.4) yard (0.8.7.4)
...@@ -186,5 +193,6 @@ DEPENDENCIES ...@@ -186,5 +193,6 @@ DEPENDENCIES
redcarpet (< 3.0.0) redcarpet (< 3.0.0)
ruby-prof! ruby-prof!
simplecov simplecov
webmock (< 1.16)
xcodeproj! xcodeproj!
yard yard
...@@ -196,6 +196,8 @@ module Pod ...@@ -196,6 +196,8 @@ module Pod
# Perform analysis for a given spec (or subspec) # Perform analysis for a given spec (or subspec)
# #
def perform_extensive_analysis(spec) def perform_extensive_analysis(spec)
validate_homepage(spec)
spec.available_platforms.each do |platform| spec.available_platforms.each do |platform|
UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
@consumer = spec.consumer(platform) @consumer = spec.consumer(platform)
...@@ -208,18 +210,38 @@ module Pod ...@@ -208,18 +210,38 @@ module Pod
perform_extensive_subspec_analysis(spec) unless @no_subspecs perform_extensive_subspec_analysis(spec) unless @no_subspecs
end end
# Recurively perform the extensive analysis on all subspecs # Recursively perform the extensive analysis on all subspecs
# #
def perform_extensive_subspec_analysis(spec) def perform_extensive_subspec_analysis(spec)
spec.subspecs.each do |subspec| spec.subspecs.each do |subspec|
@subspec_name = subspec.name @subspec_name = subspec.name
perform_extensive_analysis(subspec) perform_extensive_analysis(subspec)
end end
end end
attr_accessor :consumer attr_accessor :consumer
attr_accessor :subspec_name attr_accessor :subspec_name
# Performs validations related to the `homepage` attribute.
#
def validate_homepage(spec)
require 'rest'
homepage = spec.homepage
return unless homepage
homepage += '/' unless homepage.end_with?('/')
begin
resp = ::REST.head(homepage)
rescue
warning "There was a problem validating the homepage."
resp = nil
end
if resp && !resp.success?
warning "The homepage is not reachable."
end
end
def setup_validation_environment def setup_validation_environment
validation_dir.rmtree if validation_dir.exist? validation_dir.rmtree if validation_dir.exist?
validation_dir.mkpath validation_dir.mkpath
......
...@@ -73,6 +73,8 @@ module Pod ...@@ -73,6 +73,8 @@ module Pod
it "handles symlinks" do it "handles symlinks" do
file = write_podspec(stub_podspec) file = write_podspec(stub_podspec)
validator = Validator.new(file) validator = Validator.new(file)
validator.quick = true
validator.stubs(:validate_homepage)
validator.validate validator.validate
validator.validation_dir.should.be == Pathname.new("/private/tmp/CocoaPods/Lint") validator.validation_dir.should.be == Pathname.new("/private/tmp/CocoaPods/Lint")
end end
...@@ -81,9 +83,44 @@ module Pod ...@@ -81,9 +83,44 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
describe "Extensive analysis" do describe "Extensive analysis" do
describe "Homepage validation" do
require 'webmock'
before do
@sut = Validator.new(podspec_path)
@sut.stubs(:install_pod)
@sut.stubs(:build_pod)
@sut.stubs(:check_file_patterns)
@sut.stubs(:tear_down_validation_environment)
end
it "checks if the homepage is valid" do
WebMock::API.stub_request(:head, /not-found/).to_return(:status => 404)
Specification.any_instance.stubs(:homepage).returns('http://banana-corp.local/not-found/')
@sut.validate
@sut.results.map(&:to_s).first.should.match /The homepage is not reachable/
end
it "checks if that the homepage validates without a trailing slash" do
WebMock::API.stub_request(:head, /banana-corp.local/).to_return(:status => 200)
Specification.any_instance.stubs(:homepage).returns('http://banana-corp.local')
@sut.validate
@sut.results.should.be.empty?
end
it "indicates if it was not able to validate the homepage" do
WebMock::API.stub_request(:head, 'banana-corp.local').to_raise(SocketError)
Specification.any_instance.stubs(:homepage).returns('http://banana-corp.local/')
@sut.validate
@sut.results.map(&:to_s).first.should.match /There was a problem validating the homepage/
end
end
it "respects the no clean option" do it "respects the no clean option" do
file = write_podspec(stub_podspec) file = write_podspec(stub_podspec)
sut = Validator.new(file) sut = Validator.new(file)
sut.stubs(:validate_homepage)
sut.no_clean = true sut.no_clean = true
sut.validate sut.validate
sut.validation_dir.should.exist sut.validation_dir.should.exist
...@@ -92,6 +129,7 @@ module Pod ...@@ -92,6 +129,7 @@ module Pod
it "builds the pod per platform" do it "builds the pod per platform" do
file = write_podspec(stub_podspec) file = write_podspec(stub_podspec)
sut = Validator.new(file) sut = Validator.new(file)
sut.stubs(:validate_homepage)
sut.expects(:install_pod).twice sut.expects(:install_pod).twice
sut.expects(:build_pod).twice sut.expects(:build_pod).twice
sut.expects(:check_file_patterns).twice sut.expects(:check_file_patterns).twice
...@@ -100,6 +138,7 @@ module Pod ...@@ -100,6 +138,7 @@ module Pod
it "uses the deployment target of the specification" do it "uses the deployment target of the specification" do
sut = Validator.new(podspec_path) sut = Validator.new(podspec_path)
sut.stubs(:validate_homepage)
podfile = sut.send(:podfile_from_spec, :ios, '5.0') podfile = sut.send(:podfile_from_spec, :ios, '5.0')
dependency = podfile.target_definitions['Pods'].dependencies.first dependency = podfile.target_definitions['Pods'].dependencies.first
dependency.external_source.has_key?(:podspec).should.be.true dependency.external_source.has_key?(:podspec).should.be.true
...@@ -107,6 +146,7 @@ module Pod ...@@ -107,6 +146,7 @@ module Pod
it "respects the local option" do it "respects the local option" do
sut = Validator.new(podspec_path) sut = Validator.new(podspec_path)
sut.stubs(:validate_homepage)
podfile = sut.send(:podfile_from_spec, :ios, '5.0') podfile = sut.send(:podfile_from_spec, :ios, '5.0')
deployment_target = podfile.target_definitions['Pods'].platform.deployment_target deployment_target = podfile.target_definitions['Pods'].platform.deployment_target
deployment_target.to_s.should == "5.0" deployment_target.to_s.should == "5.0"
...@@ -116,6 +156,7 @@ module Pod ...@@ -116,6 +156,7 @@ module Pod
sut = Validator.new(podspec_path) sut = Validator.new(podspec_path)
sut.stubs(:check_file_patterns) sut.stubs(:check_file_patterns)
sut.stubs(:xcodebuild).returns("file.m:1:1: warning: direct access to objective-c's isa is deprecated") sut.stubs(:xcodebuild).returns("file.m:1:1: warning: direct access to objective-c's isa is deprecated")
sut.stubs(:validate_homepage)
sut.validate sut.validate
first = sut.results.map(&:to_s).first first = sut.results.map(&:to_s).first
first.should.include "[xcodebuild]" first.should.include "[xcodebuild]"
...@@ -126,6 +167,7 @@ module Pod ...@@ -126,6 +167,7 @@ module Pod
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'wrong_paht.*'")) file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'wrong_paht.*'"))
sut = Validator.new(file) sut = Validator.new(file)
sut.stubs(:build_pod) sut.stubs(:build_pod)
sut.stubs(:validate_homepage)
sut.validate sut.validate
sut.results.map(&:to_s).first.should.match /source_files.*did not match/ sut.results.map(&:to_s).first.should.match /source_files.*did not match/
sut.result_type.should == :error sut.result_type.should == :error
...@@ -139,6 +181,8 @@ module Pod ...@@ -139,6 +181,8 @@ module Pod
spec = Specification.from_file(file) spec = Specification.from_file(file)
sut = Validator.new(spec) sut = Validator.new(spec)
sut.stubs(:validate_homepage)
sut.stubs(:build_pod)
sut.validate sut.validate
sut.validated?.should.be.true sut.validated?.should.be.true
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