Commit 28c50294 authored by Fabio Pelosin's avatar Fabio Pelosin

[Linter] Extracted the Linter and added `pod repo lint`.

Closes #423.
parent f500613a
......@@ -5,6 +5,7 @@ module Pod
autoload :ErrorReport, 'cocoapods/command/error_report'
autoload :Install, 'cocoapods/command/install'
autoload :List, 'cocoapods/command/list'
autoload :Linter, 'cocoapods/command/linter'
autoload :Presenter, 'cocoapods/command/presenter'
autoload :Push, 'cocoapods/command/push'
autoload :Repo, 'cocoapods/command/repo'
......
This diff is collapsed.
......@@ -11,10 +11,16 @@ module Pod
Clones `URL' in the local spec-repos directory at `~/.cocoapods'. The
remote can later be referred to by `NAME'.
$ pod repo update NAME
$ pod repo update [NAME]
Updates the local clone of the spec-repo `NAME'. If `NAME' is omitted
this will update all spec-repos in `~/.cocoapods'.}
this will update all spec-repos in `~/.cocoapods'.
$ pod repo update [NAME | DIRECTORY]
Lints the spec-repo `NAME'. If a directory is provided it is assumed
to be the root of a repo. Finally, if NAME is not provided this will
lint all the spec-repos known to CocoaPods.}
end
extend Executable
......@@ -27,7 +33,7 @@ module Pod
raise Informative, "#{@action == 'add' ? 'Adding' : 'Updating the remote of'} a repo needs a `name' and a `url'."
end
@branch = argv.arguments[3]
when 'update'
when 'update', 'lint'
@name = argv.arguments[1]
else
super
......@@ -66,6 +72,50 @@ module Pod
end
end
def lint
if @name
dirs = File.exists?(@name) ? [ Pathname.new(@name) ] : [ dir ]
else
dirs = config.repos_dir.children.select {|c| c.directory?}
end
dirs.each do |dir|
check_versions(dir)
puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
podspecs = dir.glob('**/*.podspec')
invalid_count = 0
podspecs.each do |podspec|
linter = Linter.new(podspec)
linter.lenient = true
linter.quick = true
linter.lint
unless linter.result_type == :success
invalid_count += 1
case linter.result_type
when :error
color = :red
when :warning
color = :yellow
end
puts " -> ".send(color) << linter.spec_name
print_messages('ERROR', linter.errors)
print_messages('WARN', linter.warnings)
print_messages('NOTE', linter.notes)
puts unless config.silent?
end
end
puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
invalid_count
end
end
def print_messages(type, messages)
return if config.silent?
messages.each {|msg| puts " - #{type.ljust(5)} | #{msg}"}
end
def check_versions(dir)
versions = versions(dir)
unless is_compatilbe(versions)
......
This diff is collapsed.
......@@ -9,6 +9,7 @@ describe "Pod::Command::Repo" do
it "runs with correct parameters" do
lambda { run_command('repo', 'add', 'NAME', 'URL') }.should.not.raise
lambda { run_command('repo', 'update') }.should.not.raise
lambda { run_command('repo', 'lint', temporary_directory.to_s) }.should.not.raise
end
it "complains for wrong parameters" do
......@@ -49,6 +50,16 @@ describe "Pod::Command::Repo" do
(repo2.dir + 'README').read.should.include 'Added!'
(repo3.dir + 'README').read.should.include 'Added!'
end
before do
config.repos_dir = fixture('spec-repos')
end
it "lints a repo" do
cmd = command('repo', 'lint', 'master')
lambda { cmd.run }.should.not.raise Pod::Informative
cmd.output.should.include "Missing license type"
end
end
describe "Concerning a repo support" do
......
......@@ -97,17 +97,6 @@ describe "Pod::Command::Spec#lint" do
extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
before do
config.repos_dir = fixture('spec-repos')
end
it "lints a repo" do
# The fixture has warnings so it raises
cmd = command('spec', 'lint', "#{config.repos_dir}/master")
lambda { cmd.run }.should.raise Pod::Informative
cmd.output.should.include "WARN"
end
it "complains if it can't find any spec to lint" do
Dir.chdir(temporary_directory) do
lambda { command('spec', 'lint').run }.should.raise Pod::Informative
......
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Spec::Linter" do
describe "Pod::Command::Linter" do
extend SpecHelper::TemporaryDirectory
def write_podspec(text, name = 'JSONKit.podspec')
file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) }
spec = Pod::Specification.from_file(file)
[spec, file]
file
end
def stub_podspec(pattern = nil, replacement = nil)
......@@ -18,16 +17,16 @@ describe "Pod::Command::Spec::Linter" do
end
it "fails a specifications that does not contain the minimum required attributes" do
spec, file = write_podspec('Pod::Spec.new do |s| end')
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec('Pod::Spec.new do |s| end')
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.join(' | ') =~ /name.*version.*summary.*homepage.*authors.*(source.*part_of).*source_files/
end
it "fails specifications if the name does not match the name of the file" do
spec, file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKitAAA'"))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKitAAA'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
......@@ -35,8 +34,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "fails a specification if a path starts with a slash" do
spec, file = write_podspec(stub_podspec(/s.source_files = 'JSONKit\.\*'/, "s.source_files = '/JSONKit.*'"))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s.source_files = 'JSONKit\.\*'/, "s.source_files = '/JSONKit.*'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
......@@ -44,8 +43,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "fails a specification if the platform is unrecognized" do
spec, file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'\ns.platform = :iososx\n"))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'\ns.platform = :iososx\n"))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
......@@ -53,8 +52,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "fails validation if the specification contains warnings" do
spec, file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = false, true
linter.lint.should == false
linter.errors.should.be.empty
......@@ -62,8 +61,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "validates in lenient mode if there are no errors but there are warnings" do
spec, file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/.*license.*/, ""))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = true, true
linter.lint.should == true
linter.errors.should.be.empty
......@@ -71,8 +70,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "respects quick mode" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(file)
linter.expects(:peform_multiplatform_analysis).never
linter.expects(:install_pod).never
linter.expects(:xcodebuild_output_for_platfrom).never
......@@ -82,25 +81,25 @@ describe "Pod::Command::Spec::Linter" do
end
it "produces deprecation notices" do
spec, file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\n if config.ios?\nend"))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\n if config.ios?\nend"))
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = false, true
linter.lint.should == false
linter.errors.should.be.empty
linter.warnings.join(' | ').should =~ /`config.ios\?' and `config.osx\?' are deprecated/
linter.warnings.should.be.empty
linter.errors.join(' | ').should =~ /`config.ios\?' and `config.osx\?' are deprecated/
end
it "uses xcodebuild to generate notes and warnings" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(file)
linter.lenient, linter.quick = false, false
linter.lint.should == false
linter.notes.join(' | ').should.include "JSONKit/JSONKit.m:1640:27: warning: equality comparison with extraneous parentheses" unless `which xcodebuild`.strip.empty?
end
it "checks for file patterns" do
spec, file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\ns.resources = 'WRONG_FOLDER'"))
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\ns.resources = 'WRONG_FOLDER'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.stubs(:xcodebuild_output).returns([])
linter.lenient, linter.quick = false, false
linter.lint.should == false
......@@ -108,9 +107,8 @@ describe "Pod::Command::Spec::Linter" do
end
it "uses the deployment target of the specification" do
spec, file = write_podspec(stub_podspec)
spec.stubs(:available_platforms).returns([Pod::Platform.new(:ios, "5.0")])
linter = Pod::Command::Spec::Linter.new(spec)
file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'; s.platform = :ios, '5.0'"))
linter = Pod::Command::Spec::Linter.new(file)
linter.quick = true
linter.lint
podfile = linter.podfile_from_spec
......@@ -118,3 +116,4 @@ describe "Pod::Command::Spec::Linter" do
deployment_target.to_s.should == "5.0"
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