Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation of subspecs #1588

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ To install or update CocoaPods see this [guide](http://docs.cocoapods.org/guides
[kra Larivain/OpenTable](https://github.com/opentable)
[#1635](https://github.com/CocoaPods/CocoaPods/pull/1635)

* Validation of all subspecs
The validation done by `pod spec lint` and `pod lib lint` commands
now checks that all subspecs build independently.
This new behavior can be disabled with `--no-subspecs`.
The validation of a single subspec can be done with `--subspec=NAME`.
[Marc C](https://github.com/yalp)
[#1588](https://github.com/CocoaPods/CocoaPods/pull/1588)

###### Bug Fixes

* Fixed a bug which resulted in `pod lib lint` not being able to find the
Expand Down
12 changes: 9 additions & 3 deletions lib/cocoapods/command/lib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,17 @@ class Lint < Lib
def self.options
[ ["--quick", "Lint skips checks that would require to download and build the spec"],
["--only-errors", "Lint validates even if warnings are present"],
["--subspec=NAME","Lint validates only the given subspec"],
["--no-subspecs", "Lint skips validation of subspecs"],
["--no-clean", "Lint leaves the build directory intact for inspection"] ].concat(super)
end

def initialize(argv)
@quick = argv.flag?('quick')
@only_errors = argv.flag?('only-errors')
@clean = argv.flag?('clean', true)
@quick = argv.flag?('quick')
@only_errors = argv.flag?('only-errors')
@clean = argv.flag?('clean', true)
@subspecs = argv.flag?('subspecs', true)
@only_subspec = argv.option('subspec')
@podspecs_paths = argv.arguments!
super
end
Expand All @@ -114,6 +118,8 @@ def run
validator.quick = @quick
validator.no_clean = !@clean
validator.only_errors = @only_errors
validator.no_subspecs = !@subspecs || @only_subspec
validator.only_subspec = @only_subspec
validator.validate

unless @clean
Expand Down
12 changes: 9 additions & 3 deletions lib/cocoapods/command/spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,17 @@ class Lint < Spec
def self.options
[ ["--quick", "Lint skips checks that would require to download and build the spec"],
["--only-errors", "Lint validates even if warnings are present"],
["--subspec=NAME","Lint validates only the given subspec"],
["--no-subspecs", "Lint skips validation of subspecs"],
["--no-clean", "Lint leaves the build directory intact for inspection"] ].concat(super)
end

def initialize(argv)
@quick = argv.flag?('quick')
@only_errors = argv.flag?('only-errors')
@clean = argv.flag?('clean', true)
@quick = argv.flag?('quick')
@only_errors = argv.flag?('only-errors')
@clean = argv.flag?('clean', true)
@subspecs = argv.flag?('subspecs', true)
@only_subspec = argv.option('subspec')
@podspecs_paths = argv.arguments!
super
end
Expand All @@ -80,6 +84,8 @@ def run
validator.quick = @quick
validator.no_clean = !@clean
validator.only_errors = @only_errors
validator.no_subspecs = !@subspecs || @only_subspec
validator.only_subspec = @only_subspec
validator.validate
invalid_count += 1 unless validator.validated?

Expand Down
69 changes: 60 additions & 9 deletions lib/cocoapods/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def file

#-------------------------------------------------------------------------#

# Lints the specification adding a {Specification::Linter::Result} for any
# Lints the specification adding a {Result} for any
# failed check to the {#results} list.
#
# @note This method shows immediately which pod is being processed and
Expand All @@ -56,13 +56,21 @@ def file
#
def validate
@results = []
UI.print " -> #{spec ? spec.name : file.basename}\r" unless config.silent?

# Replace default spec with a subspec if asked for
a_spec = spec
if spec && @only_subspec
a_spec = spec.subspec_by_name(@only_subspec)
@subspec_name = a_spec.name
end

UI.print " -> #{a_spec ? a_spec.name : file.basename}\r" unless config.silent?
$stdout.flush

perform_linting
perform_extensive_analysis if spec && !quick
perform_extensive_analysis(a_spec) if a_spec && !quick

UI.puts " -> ".send(result_color) << (spec ? spec.to_s : file.basename.to_s)
UI.puts " -> ".send(result_color) << (a_spec ? a_spec.to_s : file.basename.to_s)
print_results
validated?
end
Expand All @@ -79,12 +87,22 @@ def print_results
platform_message = "[OSX] "
end

subspecs_message = ""
if result.is_a?(Result)
subspecs = result.subspecs.uniq
if subspecs.count > 2
subspecs_message = "[" + subspecs[0..2].join(', ') + ", and more...] "
elsif subspecs.count > 0
subspecs_message = "[" + subspecs.join(',') + "] "
end
end

case result.type
when :error then type = "ERROR"
when :warning then type = "WARN"
when :note then type = "NOTE"
else raise "#{result.type}" end
UI.puts " - #{type.ljust(5)} | #{platform_message}#{result.message}"
UI.puts " - #{type.ljust(5)} | #{platform_message}#{subspecs_message}#{result.message}"
end
UI.puts
end
Expand Down Expand Up @@ -116,6 +134,14 @@ def local?; @local; end
#
attr_accessor :only_errors

# @return [String] name of the subspec to check, if nil all subspecs are checked.
#
attr_accessor :only_subspec

# @return [Bool] Whether the validator should validate all subspecs
#
attr_accessor :no_subspecs

#-------------------------------------------------------------------------#

# !@group Lint results
Expand Down Expand Up @@ -167,9 +193,9 @@ def perform_linting
@results.concat(linter.results)
end

# Perform analysis for a given spec (or subspec)
#
#
def perform_extensive_analysis
def perform_extensive_analysis(spec)
spec.available_platforms.each do |platform|
UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
@consumer = spec.consumer(platform)
Expand All @@ -179,9 +205,20 @@ def perform_extensive_analysis
check_file_patterns
tear_down_validation_environment
end
perform_extensive_subspec_analysis(spec) unless @no_subspecs
end

# Recurively perform the extensive analysis on all subspecs
#
def perform_extensive_subspec_analysis(spec)
spec.subspecs.each do |subspec|
@subspec_name = subspec.name
perform_extensive_analysis(subspec)
end
end

attr_accessor :consumer
attr_accessor :subspec_name

def setup_validation_environment
validation_dir.rmtree if validation_dir.exist?
Expand Down Expand Up @@ -283,10 +320,24 @@ def note(message)
def add_result(type, message)
result = results.find { |r| r.type == type && r.message == message }
unless result
result = Specification::Linter::Result.new(type, message)
result = Result.new(type, message)
results << result
end
result.platforms << consumer.platform_name if consumer
result.subspecs << subspec_name if subspec_name && !result.subspecs.include?(subspec_name)
end

# Specialized Result to support subspecs aggregation
#
class Result < Specification::Linter::Result

def initialize(type, message)
super(type, message)
@subspecs = []
end

attr_reader :subspecs

end

#-------------------------------------------------------------------------#
Expand All @@ -302,7 +353,7 @@ def add_result(type, message)
# in local mode.
#
def podfile_from_spec(platform_name, deployment_target)
name = spec.name
name = subspec_name ? subspec_name : spec.name
podspec = file.realpath
local = local?
podfile = Pod::Podfile.new do
Expand Down