Commit 32735dc3 authored by Fabio Pelosin's avatar Fabio Pelosin

More specs fixes.

parent 88057d18
GIT
remote: git://github.com/CocoaPods/Core.git
revision: 55f2db7c1bd2a7311c47c6bd8de3132e9e8853d1
revision: 163c8f3d20aadb91b1987acb57e266ed839040ba
specs:
cocoapods-core (0.17.0.alpha)
activesupport (~> 3.2.6)
......@@ -69,7 +69,7 @@ GEM
metaclass (~> 0.0.1)
mocha-on-bacon (0.2.1)
mocha (>= 0.9.8)
multi_json (1.4.0)
multi_json (1.5.0)
multipart-post (1.1.5)
octokit (1.19.0)
addressable (~> 2.2)
......
......@@ -47,14 +47,14 @@ module Pod
private
def update_repo
UI.puts "Updating the `#{@repo}' repo\n".yellow unless config.silent
UI.puts "Updating the `#{@repo}' repo\n".yellow
# show the output of git even if not verbose
# TODO: use the `git!' and find a way to show the output in realtime.
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
end
def push_repo
UI.puts "\nPushing the `#{@repo}' repo\n".yellow unless config.silent
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git push 2>&1` }
end
......@@ -64,15 +64,16 @@ module Pod
dir
end
# @todo: add specs for staged and unstaged files
#
def check_repo_status
# TODO: add specs for staged and unstaged files (tested manually)
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "[!] `#{@repo}' repo not clean".red unless clean
raise Informative, "The repo `#{@repo}` is not clean" unless clean
end
def podspec_files
files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "[!] Couldn't find any .podspec file in current directory".red if files.empty?
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
files
end
......@@ -83,18 +84,16 @@ module Pod
end
def validate_podspec_files
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow unless config.silent
lint_argv = ["lint"]
lint_argv << "--only-errors" if @allow_warnings
lint_argv << "--silent" if config.silent
# all_valid = true
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
podspec_files.each do |podspec|
Spec.parse(lint_argv + [podspec.to_s]).run
validator = Validator.new(podspec)
validator.validate
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
end
end
def add_specs_to_repo
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow unless config.silent
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
......@@ -105,7 +104,7 @@ module Pod
else
message = "[Add] #{spec}"
end
UI.puts " - #{message}" unless config.silent
UI.puts " - #{message}"
FileUtils.mkdir_p(output_path)
FileUtils.cp(Pathname.new(spec.name+'.podspec'), output_path)
......
......@@ -40,6 +40,8 @@ module Pod
end
end
#-----------------------------------------------------------------------#
class Update < Repo
self.summary = 'Update a spec repo.'
......@@ -73,6 +75,8 @@ module Pod
end
end
#-----------------------------------------------------------------------#
class Lint < Repo
self.summary = 'Validates all specs in a repo.'
......@@ -106,33 +110,44 @@ module Pod
podspecs = Pathname.glob( dir + '**/*.podspec')
invalid_count = 0
messages_by_type = {}
podspecs.each do |podspec|
linter = Validator.new(podspec)
linter.quick = true
linter.repo_path = dir
linter.lint
case linter.result_type
when :error
invalid_count += 1
color = :red
should_display = true
when :warning
color = :yellow
should_display = !@only_errors
print "\033[K -> #{podspec.relative_path_from(dir)}\r"
validator = Validator.new(podspec)
validator.quick = true
validator.repo_path = dir
validator.only_errors = @only_errors
validator.disable_ui_output = true
validator.validate
invalid_count += 1 if validator.result_type == :error
unless validator.validated?
if @only_errors
results = validator.results.select { |r| r.type.to_s == "error" }
else
results = validator.results
end
results.each do |result|
messages_by_type[result.type] ||= {}
messages_by_type[result.type][result.message] ||= []
name = validator.spec ? validator.spec.to_s : podspec.relative_path_from(dir)
messages_by_type[result.type][result.message] << name
end
end
end
if should_display
UI.puts " -> ".send(color) << linter.spec_name
print_messages('ERROR', linter.errors)
unless @only_errors
print_messages('WARN', linter.warnings)
print_messages('NOTE', linter.notes)
end
UI.puts unless config.silent?
print "\033[K"
messages_by_type.each do |type, messages_by_type|
messages_by_type.each do |message, names|
color = type == :error ? :red : :yellow
UI.puts "[#{type}] #{message}".send(color)
names.each { |name| UI.puts " - #{name}" }
UI.puts
end
end
UI.puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
if invalid_count == 0
......
......@@ -86,20 +86,20 @@ module Pod
UI.puts
invalid_count = 0
podspecs_to_lint.each do |podspec|
validator = Validator.new(podspec)
validator.quick = @quick
validator.local = @local
validator.no_clean = @no_clean
validator = Validator.new(podspec)
validator.quick = @quick
validator.local = @local
validator.no_clean = @no_clean
validator.only_errors = @only_errors
validator.validate
invalid_count += 1 unless validator.validated?
end
count = podspecs_to_lint.count
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n" unless config.silent?
UI.puts "Analyzed #{count} #{'podspec'.pluralize(count)}.\n\n"
if invalid_count == 0
lint_passed_message = count == 1 ? "#{podspecs_to_lint.first.basename} passed validation." : "All the specs passed validation."
UI.puts lint_passed_message.green << "\n\n" unless config.silent?
UI.puts lint_passed_message.green << "\n\n"
else
raise Informative, count == 1 ? "The spec did not pass validation." : "#{invalid_count} out of #{count} specs failed validation."
end
......
......@@ -48,14 +48,26 @@ module Pod
#
def validate
@results = []
print " -> #{spec.name}\r" unless config.silent?
$stdout.flush
unless disable_ui_output
print " -> #{spec ? spec.name : file.basename}\r" unless config.silent?
$stdout.flush
end
perform_linting
check_repo_path if repo_path
perform_extensive_analysis unless quick
UI.puts " -> ".send(result_color) << spec.name
print_results
begin
if spec
check_repo_path if repo_path
perform_extensive_analysis unless quick
end
rescue Exception => e
error "The specification is malformed and crashed the linter."
end
unless disable_ui_output
UI.puts " -> ".send(result_color) << (spec ? spec.name : file.basename.to_s)
print_results
end
validated?
end
......@@ -83,10 +95,12 @@ module Pod
UI.puts
end
#-----------------------------------------------------------------------#
#-------------------------------------------------------------------------#
# @!group Configuration
attr_accessor :disable_ui_output
# @return [Pathname] whether the validation should be performed against a repo.
#
attr_accessor :repo_path
......@@ -112,7 +126,7 @@ module Pod
#
attr_accessor :only_errors
#-----------------------------------------------------------------------#
#-------------------------------------------------------------------------#
# !@group Lint results
......@@ -124,7 +138,7 @@ module Pod
#
def validated?
return false if result_type == :error
return false if result_type == :warnings && !only_errors
return false if result_type == :warning && !only_errors
return true
end
......@@ -157,7 +171,7 @@ module Pod
Pathname.new('/tmp/CocoaPods/Lint')
end
#-----------------------------------------------------------------------#
#-------------------------------------------------------------------------#
private
......@@ -244,9 +258,9 @@ module Pod
parsed_output = parse_xcodebuild_output(output)
parsed_output.each do |message|
if message.include?('error: ')
error "XCODEBUILD #{message}"
error "[xcodebuild] #{message}"
else
note "XCODEBUILD #{message}"
note "[xcodebuild] #{message}"
end
end
end
......@@ -260,7 +274,6 @@ module Pod
# @return [void]
#
def check_file_patterns
puts spec.preserve_paths
[:source_files, :resources, :preserve_paths].each do |attr_name|
attr = Specification::DSL.attributes.find{|attr| attr.name == attr_name }
if !attr.empty?(spec) && @pod.send(attr_name).empty?
......@@ -273,11 +286,11 @@ module Pod
end
end
#-----------------------------------------------------------------------#
#-------------------------------------------------------------------------#
private
# !@group Helpers
# !@group Result Helpers
def error(message)
add_result(:error, message)
......@@ -300,6 +313,12 @@ module Pod
result.platforms << current_platform.name if current_platform
end
#-------------------------------------------------------------------------#
private
# !@group Helpers
# @return [Podfile] a podfile that requires the specification on the
# current platform.
#
......@@ -321,17 +340,14 @@ module Pod
podfile
end
# @return [Pathname] the root of the installed pod.
#
def pod_dir
validation_dir + 'Pods' + spec.name
end
# Parse the xcode build output to identify the lines which are relevant
# to the linter. It also removes the indentation and the temporary path.
# to the linter.
#
# @param [String] output the output generated by the xcodebuild tool.
#
# @note The indentation and the temporary path is stripped form the
# lines.
#
# @return [Array<String>] the lines that are relevant to the linter.
#
def parse_xcodebuild_output(output)
......@@ -343,17 +359,9 @@ module Pod
l.include?('note: ') && (l !~ /expanded from macro/)
end
selected_lines.map do |l|
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'') # Remove the unnecessary tmp path
new.gsub!(/^ */,' ') # Remove indentation
"XCODEBUILD > " << new # Mark
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'')
new.gsub!(/^ */,' ')
end
end
#
#
def print_messages(type, messages)
return if config.silent?
messages.each {|msg| UI.puts " - #{type.ljust(5)} | #{msg}"}
end
end
end
Subproject commit 84ea24c2f3a5d463da1e7945c60fd3f33f73dee2
Subproject commit 7f3cc9e12b0a459582d606baa7fc906006965f54
......@@ -29,24 +29,33 @@ module Pod
e.message.should.match(/Couldn't find any .podspec/)
end
# TODO: the validation should not use the pod spec command
xit "it raises if the specification doesn't validates" do
it "it raises if the specification doesn't validate" do
repo_make('test_repo')
Dir.chdir(temporary_directory) do
spec = "Spec.new do |s|; s.name = 'Broken'; end"
spec = "Spec.new do |s|; s.name = 'Broken'; s.version = '1.0' end"
File.open('Broken.podspec', 'w') {|f| f.write(spec) }
cmd = command('push', 'test_repo')
cmd.expects(:validate_podspec_files).returns(true)
Validator.any_instance.stubs(:validated?).returns(false)
e = lambda { cmd.run }.should.raise Pod::Informative
e.message.should.match(/repo not clean/)
e.message.should.match(/Broken.podspec.*does not validate/)
end
end
#--------------------------------------#
before do
repo_make('upstream')
repo_clone('upstream', 'local_repo')
set_up_test_repo
config.repos_dir = SpecHelper.tmp_repos_path
@upstream = SpecHelper.temporary_directory + 'upstream'
FileUtils.cp_r(test_repo_path, @upstream)
Dir.chdir(test_repo_path) do
`git remote add origin #{@upstream}`
`git remote -v`
`git fetch -q`
`git branch --set-upstream master origin/master`
end
# prepare the spec
spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
......@@ -57,29 +66,26 @@ module Pod
end
it "refuses to push if the repo is not clean" do
repo_make_readme_change('local_repo', 'dirty')
Dir.chdir(temporary_directory) do
cmd = command('push', 'local_repo')
cmd.expects(:validate_podspec_files).returns(true)
e = lambda { cmd.run }.should.raise Pod::Informative
e.message.should.match(/repo not clean/)
Dir.chdir(test_repo_path) do
`touch DIRTY_FILE`
end
(repo_path('upstream') + 'PushTest/1.4/PushTest.podspec').should.not.exist?
cmd = command('push', 'master')
cmd.expects(:validate_podspec_files).returns(true)
e = lambda { cmd.run }.should.raise Pod::Informative
e.message.should.match(/repo.*not clean/)
(@upstream + 'PushTest/1.4/PushTest.podspec').should.not.exist?
end
it "sucessfully pushes a spec" do
cmd = command('push', 'local_repo')
Dir.chdir(repo_path 'upstream') { `git checkout -b tmp_for_push -q` }
it "successfully pushes a spec" do
cmd = command('push', 'master')
Dir.chdir(@upstream) { `git checkout -b tmp_for_push -q` }
cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { cmd.run }
Pod::UI.output.should.include('[Add] PushTest (1.4)')
Pod::UI.output.should.include('[Add] JSONKit (1.4)')
# TODO check the commit messages
# Pod::UI.output.should.include('[Fix] JSONKit (1.4)')
Dir.chdir(repo_path 'upstream') { `git checkout master -q` }
(repo_path('upstream') + 'PushTest/1.4/PushTest.podspec').read.should.include('PushTest')
Pod::UI.output.should.include('[Fix] JSONKit (1.4)')
Dir.chdir(@upstream) { `git checkout master -q` }
(@upstream + 'PushTest/1.4/PushTest.podspec').read.should.include('PushTest')
end
end
end
......@@ -25,7 +25,8 @@ module Pod
end
it "lints a repository" do
lambda { run_command('repo', 'lint', temporary_directory.to_s) }.should.not.raise
repo = fixture('spec-repos/test_repo').to_s
lambda { run_command('repo', 'lint', repo) }.should.not.raise
end
it "adds a spec-repo" do
......
......@@ -6,12 +6,13 @@ module Pod
extend SpecHelper::TemporaryRepos
before do
config.repos_dir = fixture('spec-repos')
set_up_test_repo
config.repos_dir = SpecHelper.tmp_repos_path
end
it "runs with correct parameters" do
lambda { run_command('search', 'table') }.should.not.raise
lambda { run_command('search', 'table', '--full') }.should.not.raise
lambda { run_command('search', 'JSON') }.should.not.raise
lambda { run_command('search', 'JSON', '--full') }.should.not.raise
end
it "complains for wrong parameters" do
......@@ -21,30 +22,14 @@ module Pod
lambda { run_command('search', '--wrong') }.should.raise CLAide::Help
end
it "presents the search results" do
output = run_command('search', 'table')
output.should.include 'EGOTableViewPullRefresh'
end
it "searches for a pod with name matching the given query ignoring case" do
[
[' s ', %w{ ASIHTTPRequest ASIWebPageRequest JSONKit SSZipArchive }],
['json', %w{ JSONKit SBJson }],
].each do |query, results|
output = run_command('search', query)
results.each { |pod| output.should.include? pod }
end
output = run_command('search', 'json')
output.should.include? 'JSONKit'
end
it "searches for a pod with name, summary, or description matching the given query ignoring case" do
[
['dROP', %w{ Reachability }],
['is', %w{ ASIHTTPRequest SSZipArchive }],
['luke redpath', %w{ Kiwi libPusher LRMocky LRResty LRTableModel}],
].each do |query, results|
output = run_command('search', query, '--full')
results.each { |pod| output.should.include? pod }
end
output = run_command('search', 'Engelhart', '--full')
output.should.include? 'JSONKit'
end
end
end
......@@ -118,7 +118,7 @@ module Pod
before do
text = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
text.gsub!(/.*license.*/, "")
text.gsub!(/.*license.*/, "s.license = { :file => 'some_file'}")
file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) }
@spec_path = file.to_s
......@@ -136,28 +136,28 @@ module Pod
UI.output.should.include "Missing license type"
end
end
describe "Command::Spec#cat" do
extend SpecHelper::TemporaryDirectory
extend SpecHelper::TemporaryRepos
it "complains it cant't find a spec to read" do
lambda { command('spec', 'cat', 'not-exissting-spec').run }.should.raise Informative
end
it "complains provided spec name is ambigious" do
e = lambda { command('spec', 'cat', 'AF').run }.should.raise Informative
e.message.should.match /More that one/
end
it "prints the spec on standard output" do
lambda { command('spec', 'cat', 'JRSwizzle').run }.should.not.raise
text = (fixture('spec-repos') + 'master/JRSwizzle/1.0/JRSwizzle.podspec').read
#output.gsub(/\n/,'').should.equsal text.gsub(/\n/,'')
UI.output.should.include text.gsub(/\n/,'')
end
end
end
......@@ -112,7 +112,7 @@ module Pod
it "includes all the subspecs of a specification node" do
@podfile = Podfile.new do
platform :ios
pod 'RestKit'
pod 'RestKit', '0.10.3'
end
resolver = Resolver.new(config.sandbox, @podfile)
resolver.resolve.values.flatten.map(&:name).sort.should == %w{
......
......@@ -63,7 +63,7 @@ module Pod
validator.stubs(:check_file_patterns)
validator.validate
first = validator.results.map(&:to_s).first
first.should.include "[NOTE] XCODEBUILD"
first.should.include "xcodebuild"
first.should.include "JSONKit/JSONKit.m:1640:27: warning: equality comparison"
first.should.include "[OS X - iOS]"
validator.result_type.should == :note
......
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