Commit 0de9eca7 authored by Samuel E. Giddins's avatar Samuel E. Giddins

Merge pull request #2749 from CocoaPods/seg-linter-private-mode

[Validator] Add private mode
parents 22ff2516 573310b5
...@@ -9,7 +9,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -9,7 +9,7 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Bug Fixes ##### Bug Fixes
* Build settings specified in `pod_target_xcconfig` of a spec are also for * Build settings specified in `pod_target_xcconfig` of a spec are also for
library targets only applied to the pod target. library targets only applied to the pod target.
[Marius Rackwitz](https://github.com/mrackwitz) [Marius Rackwitz](https://github.com/mrackwitz)
[#3906](https://github.com/CocoaPods/CocoaPods/issues/3906) [#3906](https://github.com/CocoaPods/CocoaPods/issues/3906)
...@@ -51,6 +51,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -51,6 +51,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[#3905](https://github.com/CocoaPods/CocoaPods/issues/3905) [#3905](https://github.com/CocoaPods/CocoaPods/issues/3905)
[#4028](https://github.com/CocoaPods/CocoaPods/pull/4028) [#4028](https://github.com/CocoaPods/CocoaPods/pull/4028)
* Add a `--private` option to `pod spec lint`, `pod lib lint`, and
`pod repo push` that will ignore warnings that only apply to public
specifications and sources.
[Samuel Giddins](https://github.com/segiddins)
[Core#190](https://github.com/CocoaPods/Core/issues/190)
[#2682](https://github.com/CocoaPods/CocoaPods/issues/2682)
## 0.38.2 ## 0.38.2
......
...@@ -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: f2d6aeccba25972c44094572e3906ca4c886c568 revision: fd41ee938a5687a39711b0f3d1f9e76dd506dd5d
branch: master branch: master
specs: specs:
cocoapods-core (0.38.2) cocoapods-core (0.38.2)
......
...@@ -115,16 +115,19 @@ module Pod ...@@ -115,16 +115,19 @@ module Pod
DESC DESC
def self.options def self.options
[['--quick', 'Lint skips checks that would require to download and build the spec'], [
['--allow-warnings', 'Lint validates even if warnings are present'], ['--quick', 'Lint skips checks that would require to download and build the spec'],
['--subspec=NAME', 'Lint validates only the given subspec'], ['--allow-warnings', 'Lint validates even if warnings are present'],
['--no-subspecs', 'Lint skips validation of subspecs'], ['--subspec=NAME', 'Lint validates only the given subspec'],
['--no-clean', 'Lint leaves the build directory intact for inspection'], ['--no-subspecs', 'Lint skips validation of subspecs'],
['--fail-fast', 'Lint stops on the first failing platform or subspec'], ['--no-clean', 'Lint leaves the build directory intact for inspection'],
['--use-libraries', 'Lint uses static libraries to install the spec'], ['--fail-fast', 'Lint stops on the first failing platform or subspec'],
['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \ ['--use-libraries', 'Lint uses static libraries to install the spec'],
'(defaults to https://github.com/CocoaPods/Specs.git). '\ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \
'Multiple sources must be comma-delimited.']].concat(super) '(defaults to https://github.com/CocoaPods/Specs.git). ' \
'Multiple sources must be comma-delimited.'],
['--private', 'Lint skips checks that apply only to public specs'],
].concat(super)
end end
def initialize(argv) def initialize(argv)
...@@ -136,6 +139,7 @@ module Pod ...@@ -136,6 +139,7 @@ module Pod
@only_subspec = argv.option('subspec') @only_subspec = argv.option('subspec')
@use_frameworks = !argv.flag?('use-libraries') @use_frameworks = !argv.flag?('use-libraries')
@source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',') @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
@private = argv.flag?('private', false)
@podspecs_paths = argv.arguments! @podspecs_paths = argv.arguments!
super super
end end
...@@ -156,6 +160,7 @@ module Pod ...@@ -156,6 +160,7 @@ module Pod
validator.no_subspecs = !@subspecs || @only_subspec validator.no_subspecs = !@subspecs || @only_subspec
validator.only_subspec = @only_subspec validator.only_subspec = @only_subspec
validator.use_frameworks = @use_frameworks validator.use_frameworks = @use_frameworks
validator.ignore_public_only_results = @private
validator.validate validator.validate
unless @clean unless @clean
......
...@@ -15,7 +15,9 @@ module Pod ...@@ -15,7 +15,9 @@ module Pod
] ]
def self.options def self.options
[['--only-errors', 'Lint presents only the errors']].concat(super) [
['--only-errors', 'Lint presents only the errors'],
].concat(super)
end end
def initialize(argv) def initialize(argv)
......
...@@ -20,12 +20,15 @@ module Pod ...@@ -20,12 +20,15 @@ module Pod
] ]
def self.options def self.options
[['--allow-warnings', 'Allows pushing even if there are warnings'], [
['--use-libraries', 'Linter uses static libraries to install the spec'], ['--allow-warnings', 'Allows pushing even if there are warnings'],
['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \ ['--use-libraries', 'Linter uses static libraries to install the spec'],
'(defaults to all available repos). '\ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \
'Multiple sources must be comma-delimited.'], '(defaults to all available repos). ' \
['--local-only', 'Does not perform the step of pushing REPO to its remote']].concat(super) 'Multiple sources must be comma-delimited.'],
['--local-only', 'Does not perform the step of pushing REPO to its remote'],
['--no-private', 'Lint includes checks that apply only to public repos'],
].concat(super)
end end
def initialize(argv) def initialize(argv)
...@@ -35,6 +38,7 @@ module Pod ...@@ -35,6 +38,7 @@ module Pod
@source_urls = argv.option('sources', SourcesManager.all.map(&:url).join(',')).split(',') @source_urls = argv.option('sources', SourcesManager.all.map(&:url).join(',')).split(',')
@podspec = argv.shift_argument @podspec = argv.shift_argument
@use_frameworks = !argv.flag?('use-libraries') @use_frameworks = !argv.flag?('use-libraries')
@private = argv.flag?('private', true)
super super
end end
...@@ -91,6 +95,7 @@ module Pod ...@@ -91,6 +95,7 @@ module Pod
validator = Validator.new(podspec, @source_urls) validator = Validator.new(podspec, @source_urls)
validator.allow_warnings = @allow_warnings validator.allow_warnings = @allow_warnings
validator.use_frameworks = @use_frameworks validator.use_frameworks = @use_frameworks
validator.ignore_public_only_results = @private
begin begin
validator.validate validator.validate
rescue => e rescue => e
......
...@@ -15,16 +15,19 @@ module Pod ...@@ -15,16 +15,19 @@ module Pod
] ]
def self.options def self.options
[['--quick', 'Lint skips checks that would require to download and build the spec'], [
['--allow-warnings', 'Lint validates even if warnings are present'], ['--quick', 'Lint skips checks that would require to download and build the spec'],
['--subspec=NAME', 'Lint validates only the given subspec'], ['--allow-warnings', 'Lint validates even if warnings are present'],
['--no-subspecs', 'Lint skips validation of subspecs'], ['--subspec=NAME', 'Lint validates only the given subspec'],
['--no-clean', 'Lint leaves the build directory intact for inspection'], ['--no-subspecs', 'Lint skips validation of subspecs'],
['--fail-fast', 'Lint stops on the first failing platform or subspec'], ['--no-clean', 'Lint leaves the build directory intact for inspection'],
['--use-libraries', 'Lint uses static libraries to install the spec'], ['--fail-fast', 'Lint stops on the first failing platform or subspec'],
['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \ ['--use-libraries', 'Lint uses static libraries to install the spec'],
'(defaults to https://github.com/CocoaPods/Specs.git). '\ ['--sources=https://github.com/artsy/Specs,master', 'The sources from which to pull dependant pods ' \
'Multiple sources must be comma-delimited.']].concat(super) '(defaults to https://github.com/CocoaPods/Specs.git). ' \
'Multiple sources must be comma-delimited.'],
['--private', 'Lint skips checks that apply only to public specs'],
].concat(super)
end end
def initialize(argv) def initialize(argv)
...@@ -36,6 +39,7 @@ module Pod ...@@ -36,6 +39,7 @@ module Pod
@only_subspec = argv.option('subspec') @only_subspec = argv.option('subspec')
@use_frameworks = !argv.flag?('use-libraries') @use_frameworks = !argv.flag?('use-libraries')
@source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',') @source_urls = argv.option('sources', 'https://github.com/CocoaPods/Specs.git').split(',')
@private = argv.flag?('private', false)
@podspecs_paths = argv.arguments! @podspecs_paths = argv.arguments!
super super
end end
...@@ -52,6 +56,7 @@ module Pod ...@@ -52,6 +56,7 @@ module Pod
validator.no_subspecs = !@subspecs || @only_subspec validator.no_subspecs = !@subspecs || @only_subspec
validator.only_subspec = @only_subspec validator.only_subspec = @only_subspec
validator.use_frameworks = @use_frameworks validator.use_frameworks = @use_frameworks
validator.ignore_public_only_results = @private
validator.validate validator.validate
failure_reasons << validator.failure_reason failure_reasons << validator.failure_reason
......
...@@ -62,7 +62,7 @@ module Pod ...@@ -62,7 +62,7 @@ module Pod
# @return [Bool] whether the specification passed validation. # @return [Bool] whether the specification passed validation.
# #
def validate def validate
@results = [] @results = []
# Replace default spec with a subspec if asked for # Replace default spec with a subspec if asked for
a_spec = spec a_spec = spec
...@@ -127,9 +127,13 @@ module Pod ...@@ -127,9 +127,13 @@ module Pod
if !allow_warnings && (size = results_by_type[:warning].size) && size > 0 if !allow_warnings && (size = results_by_type[:warning].size) && size > 0
reason = "#{size} #{'warning'.pluralize(size)}" reason = "#{size} #{'warning'.pluralize(size)}"
pronoun = size == 1 ? 'it' : 'them' pronoun = size == 1 ? 'it' : 'them'
reason << " (but you can use `--allow-warnings` to ignore #{pronoun})" if reasons.empty? reason << " (but you can use `--allow-warnings` to ignore #{pronoun})" if reasons.empty?
reasons << reason reasons << reason
end end
if results.all?(&:public_only)
reasons << 'All results apply only to public specs, but you can use ' \
'`--private` to ignore them if linting the specification for a private pod.'
end
reasons.to_sentence reasons.to_sentence
end end
...@@ -177,6 +181,11 @@ module Pod ...@@ -177,6 +181,11 @@ module Pod
# #
attr_accessor :use_frameworks attr_accessor :use_frameworks
# @return [Boolean] Whether attributes that affect only public sources
# Bool be skipped.
#
attr_accessor :ignore_public_only_results
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# !@group Lint results # !@group Lint results
...@@ -195,7 +204,9 @@ module Pod ...@@ -195,7 +204,9 @@ module Pod
# One of: `:error`, `:warning`, `:note`. # One of: `:error`, `:warning`, `:note`.
# #
def result_type def result_type
types = results.map(&:type).uniq applicable_results = results
applicable_results = applicable_results.reject(&:public_only?) if ignore_public_only_results
types = applicable_results.map(&:type).uniq
if types.include?(:error) then :error if types.include?(:error) then :error
elsif types.include?(:warning) then :warning elsif types.include?(:warning) then :warning
else :note else :note
...@@ -277,9 +288,9 @@ module Pod ...@@ -277,9 +288,9 @@ module Pod
resp = Pod::HTTP.validate_url(url) resp = Pod::HTTP.validate_url(url)
if !resp if !resp
warning('url', "There was a problem validating the URL #{url}.") warning('url', "There was a problem validating the URL #{url}.", true)
elsif !resp.success? elsif !resp.success?
warning('url', "The URL (#{url}) is not reachable.") warning('url', "The URL (#{url}) is not reachable.", true)
end end
resp resp
...@@ -297,8 +308,8 @@ module Pod ...@@ -297,8 +308,8 @@ module Pod
# #
def validate_screenshots(spec) def validate_screenshots(spec)
spec.screenshots.compact.each do |screenshot| spec.screenshots.compact.each do |screenshot|
request = validate_url(screenshot) response = validate_url(screenshot)
if request && !(request.headers['content-type'] && request.headers['content-type'].first =~ /image\/.*/i) if response && !(response.headers['content-type'] && response.headers['content-type'].first =~ /image\/.*/i)
warning('screenshot', "The screenshot #{screenshot} is not a valid image.") warning('screenshot', "The screenshot #{screenshot} is not a valid image.")
end end
end end
...@@ -395,7 +406,7 @@ module Pod ...@@ -395,7 +406,7 @@ module Pod
UI.message "\nBuilding with xcodebuild.\n".yellow do UI.message "\nBuilding with xcodebuild.\n".yellow do
output = Dir.chdir(config.sandbox_root) { xcodebuild } output = Dir.chdir(config.sandbox_root) { xcodebuild }
UI.puts output UI.puts output
parsed_output = parse_xcodebuild_output(output) parsed_output = parse_xcodebuild_output(output)
parsed_output.each do |message| parsed_output.each do |message|
# Checking the error for `InputFile` is to work around an Xcode # Checking the error for `InputFile` is to work around an Xcode
# issue where linting would fail even though `xcodebuild` actually # issue where linting would fail even though `xcodebuild` actually
...@@ -490,24 +501,24 @@ module Pod ...@@ -490,24 +501,24 @@ module Pod
# !@group Result Helpers # !@group Result Helpers
def error(attribute_name, message) def error(*args)
add_result(:error, attribute_name, message) add_result(:error, *args)
end end
def warning(attribute_name, message) def warning(*args)
add_result(:warning, attribute_name, message) add_result(:warning, *args)
end end
def note(attribute_name, message) def note(*args)
add_result(:note, attribute_name, message) add_result(:note, *args)
end end
def add_result(type, attribute_name, message) def add_result(type, attribute_name, message, public_only = false)
result = results.find do |r| result = results.find do |r|
r.type == type && r.attribute_name && r.message == message r.type == type && r.attribute_name && r.message == message && r.public_only? == public_only
end end
unless result unless result
result = Result.new(type, attribute_name, message) result = Result.new(type, attribute_name, message, public_only)
results << result results << result
end end
result.platforms << consumer.platform_name if consumer result.platforms << consumer.platform_name if consumer
...@@ -517,8 +528,8 @@ module Pod ...@@ -517,8 +528,8 @@ module Pod
# Specialized Result to support subspecs aggregation # Specialized Result to support subspecs aggregation
# #
class Result < Specification::Linter::Results::Result class Result < Specification::Linter::Results::Result
def initialize(type, attribute_name, message) def initialize(type, attribute_name, message, public_only = false)
super(type, attribute_name, message) super(type, attribute_name, message, public_only)
@subspecs = [] @subspecs = []
end end
...@@ -583,7 +594,7 @@ module Pod ...@@ -583,7 +594,7 @@ module Pod
def parse_xcodebuild_output(output) def parse_xcodebuild_output(output)
lines = output.split("\n") lines = output.split("\n")
selected_lines = lines.select do |l| selected_lines = lines.select do |l|
l.include?('error: ') && (l !~ /errors? generated\./) && (l !~ /error: \(null\)/) || l.include?('error: ') && (l !~ /errors? generated\./) && (l !~ /error: \(null\)/) ||
l.include?('warning: ') && (l !~ /warnings? generated\./) && (l !~ /frameworks only run on iOS 8/) || l.include?('warning: ') && (l !~ /warnings? generated\./) && (l !~ /frameworks only run on iOS 8/) ||
l.include?('note: ') && (l !~ /expanded from macro/) l.include?('note: ') && (l !~ /expanded from macro/)
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