cocoapods 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +18 -1
- data/lib/cocoapods.rb +1 -1
- data/lib/cocoapods/command.rb +5 -1
- data/lib/cocoapods/command/error_report.rb +6 -6
- data/lib/cocoapods/command/linter.rb +292 -0
- data/lib/cocoapods/command/push.rb +4 -3
- data/lib/cocoapods/command/repo.rb +69 -2
- data/lib/cocoapods/command/spec.rb +70 -335
- data/lib/cocoapods/config.rb +0 -10
- data/lib/cocoapods/dependency.rb +3 -2
- data/lib/cocoapods/downloader/subversion.rb +8 -2
- data/lib/cocoapods/file_list.rb +1 -1
- data/lib/cocoapods/installer/target_installer.rb +10 -6
- data/lib/cocoapods/installer/user_project_integrator.rb +4 -1
- data/lib/cocoapods/local_pod.rb +42 -2
- data/lib/cocoapods/sandbox.rb +51 -35
- data/lib/cocoapods/specification.rb +3 -0
- metadata +7 -3
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,21 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.11.0
|
2
|
+
|
3
|
+
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.10.0...master)
|
4
|
+
|
5
|
+
###### Enhancements
|
6
|
+
|
7
|
+
- Added support for public headers. [#440]
|
8
|
+
- Added `pod repo lint`. [#423]
|
9
|
+
- Improved support for `:head` option and svn repositories.
|
10
|
+
- When integrating Pods with a project without "Frameworks" group in root of the project, raise an informative message. [#431](https://github.com/CocoaPods/CocoaPods/pull/431)
|
11
|
+
- Dropped support for legacy `config.ios?` and `config.osx?`
|
12
|
+
|
13
|
+
###### Bug fixes
|
14
|
+
|
15
|
+
- Version message now correctly terminates with a 0 exit status.
|
16
|
+
- Resolved an issue that lead to git error messages in the error report.
|
17
|
+
|
18
|
+
## 0.10.0
|
2
19
|
|
3
20
|
[CocoaPods](http://git.io/4i75YA)
|
4
21
|
|
data/lib/cocoapods.rb
CHANGED
data/lib/cocoapods/command.rb
CHANGED
@@ -5,6 +5,7 @@ module Pod
|
|
5
5
|
autoload :ErrorReport, 'cocoapods/command/error_report'
|
6
6
|
autoload :Install, 'cocoapods/command/install'
|
7
7
|
autoload :List, 'cocoapods/command/list'
|
8
|
+
autoload :Linter, 'cocoapods/command/linter'
|
8
9
|
autoload :Presenter, 'cocoapods/command/presenter'
|
9
10
|
autoload :Push, 'cocoapods/command/push'
|
10
11
|
autoload :Repo, 'cocoapods/command/repo'
|
@@ -86,7 +87,10 @@ module Pod
|
|
86
87
|
|
87
88
|
def self.parse(*argv)
|
88
89
|
argv = ARGV.new(argv)
|
89
|
-
|
90
|
+
if argv.option('--version')
|
91
|
+
puts VERSION
|
92
|
+
exit!(0)
|
93
|
+
end
|
90
94
|
|
91
95
|
show_help = argv.option('--help')
|
92
96
|
Config.instance.silent = argv.option('--silent')
|
@@ -10,7 +10,7 @@ module Pod
|
|
10
10
|
def report(error)
|
11
11
|
return <<-EOS
|
12
12
|
|
13
|
-
#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
13
|
+
#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
14
14
|
|
15
15
|
### Report
|
16
16
|
|
@@ -59,14 +59,14 @@ EOS
|
|
59
59
|
|
60
60
|
def markdown_podfile
|
61
61
|
return '' unless Config.instance.project_podfile && Config.instance.project_podfile.exist?
|
62
|
-
<<-EOS
|
62
|
+
<<-EOS
|
63
63
|
|
64
64
|
### Podfile
|
65
65
|
|
66
66
|
```ruby
|
67
|
-
#{Config.instance.project_podfile.read.strip}
|
67
|
+
#{Config.instance.project_podfile.read.strip}
|
68
68
|
```
|
69
|
-
EOS
|
69
|
+
EOS
|
70
70
|
end
|
71
71
|
|
72
72
|
def error_from_podfile(error)
|
@@ -89,8 +89,8 @@ EOS
|
|
89
89
|
Pod::Source.all.map do |source|
|
90
90
|
repo = source.repo
|
91
91
|
Dir.chdir(repo) do
|
92
|
-
url = `git config --get remote.origin.url`.strip
|
93
|
-
sha = `git rev-parse HEAD`.strip
|
92
|
+
url = `git config --get remote.origin.url 2>&1`.strip
|
93
|
+
sha = `git rev-parse HEAD 2>&1`.strip
|
94
94
|
"#{repo.basename} - #{url} @ #{sha}"
|
95
95
|
end
|
96
96
|
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
module Pod
|
2
|
+
class Command
|
3
|
+
class Linter
|
4
|
+
include Config::Mixin
|
5
|
+
|
6
|
+
# TODO: Add check to ensure that attributes inherited by subspecs are not duplicated ?
|
7
|
+
|
8
|
+
attr_accessor :quick, :no_clean, :repo_path
|
9
|
+
attr_reader :spec, :file
|
10
|
+
attr_reader :errors, :warnings, :notes
|
11
|
+
|
12
|
+
def initialize(podspec)
|
13
|
+
@file = podspec
|
14
|
+
end
|
15
|
+
|
16
|
+
def spec_name
|
17
|
+
name = file.basename('.*').to_s
|
18
|
+
if @spec
|
19
|
+
name << " (#{spec.version})"
|
20
|
+
elsif @repo_path
|
21
|
+
name << " (#{file.dirname.basename})"
|
22
|
+
end
|
23
|
+
name
|
24
|
+
end
|
25
|
+
|
26
|
+
# Takes an array of podspec files and lints them all
|
27
|
+
#
|
28
|
+
# It returns true if the spec passed validation
|
29
|
+
#
|
30
|
+
def lint
|
31
|
+
@errors, @warnings, @notes = [], [], []
|
32
|
+
@platform_errors, @platform_warnings, @platform_notes = {}, {}, {}
|
33
|
+
|
34
|
+
if !deprecation_errors.empty?
|
35
|
+
@errors = deprecation_errors
|
36
|
+
@errors << "#{spec_name} [!] Fatal errors found skipping the rest of the validation"
|
37
|
+
else
|
38
|
+
@spec = Specification.from_file(file)
|
39
|
+
platforms = spec.available_platforms
|
40
|
+
|
41
|
+
if @repo_path
|
42
|
+
expected_path = "#{@spec.name}/#{@spec.version}/#{@spec.name}.podspec"
|
43
|
+
path = file.relative_path_from(@repo_path).to_s
|
44
|
+
@errors << "Incorrect path, the path is `#{file}` and should be `#{expected_path}`" unless path.end_with?(expected_path)
|
45
|
+
end
|
46
|
+
|
47
|
+
platforms.each do |platform|
|
48
|
+
@platform_errors[platform], @platform_warnings[platform], @platform_notes[platform] = [], [], []
|
49
|
+
|
50
|
+
spec.activate_platform(platform)
|
51
|
+
@platform = platform
|
52
|
+
puts "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed if config.verbose? && !@quick
|
53
|
+
|
54
|
+
# Skip validation if there are errors in the podspec as it would result in a crash
|
55
|
+
if !podspec_errors.empty?
|
56
|
+
@platform_errors[platform] += podspec_errors
|
57
|
+
@platform_notes[platform] << "#{platform.name} [!] Fatal errors found skipping the rest of the validation"
|
58
|
+
else
|
59
|
+
@platform_warnings[platform] += podspec_warnings
|
60
|
+
peform_extensive_analysis unless quick
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get common messages
|
65
|
+
@errors += @platform_errors.values.reduce(:&)
|
66
|
+
@warnings += @platform_warnings.values.reduce(:&)
|
67
|
+
@notes += @platform_notes.values.reduce(:&)
|
68
|
+
|
69
|
+
platforms.each do |platform|
|
70
|
+
# Mark platform specific messages
|
71
|
+
@errors += (@platform_errors[platform] - @errors).map {|m| "[#{platform}] #{m}"}
|
72
|
+
@warnings += (@platform_warnings[platform] - @warnings).map {|m| "[#{platform}] #{m}"}
|
73
|
+
@notes += (@platform_notes[platform] - @notes).map {|m| "[#{platform}] #{m}"}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def result_type
|
79
|
+
return :error unless errors.empty?
|
80
|
+
return :warning unless warnings.empty?
|
81
|
+
return :note unless notes.empty?
|
82
|
+
:success
|
83
|
+
end
|
84
|
+
|
85
|
+
# Performs platform specific analysis.
|
86
|
+
# It requires to download the source at each iteration
|
87
|
+
#
|
88
|
+
def peform_extensive_analysis
|
89
|
+
set_up_lint_environment
|
90
|
+
install_pod
|
91
|
+
if `which xcodebuild`.strip.empty?
|
92
|
+
puts "Skipping compilation with `xcodebuild' because it can't be found.\n".yellow if config.verbose?
|
93
|
+
else
|
94
|
+
puts "Building with xcodebuild.\n".yellow if config.verbose?
|
95
|
+
# treat xcodebuild warnings as notes because the spec maintainer might not be the author of the library
|
96
|
+
xcodebuild_output.each { |msg| ( msg.include?('error: ') ? @platform_errors[@platform] : @platform_notes[@platform] ) << msg }
|
97
|
+
end
|
98
|
+
@platform_errors[@platform] += file_patterns_errors
|
99
|
+
@platform_warnings[@platform] += file_patterns_warnings
|
100
|
+
tear_down_lint_environment
|
101
|
+
end
|
102
|
+
|
103
|
+
def install_pod
|
104
|
+
podfile = podfile_from_spec
|
105
|
+
config.verbose
|
106
|
+
installer = Installer.new(podfile)
|
107
|
+
installer.install!
|
108
|
+
@pod = installer.pods.find { |pod| pod.top_specification == spec }
|
109
|
+
config.silent
|
110
|
+
end
|
111
|
+
|
112
|
+
def podfile_from_spec
|
113
|
+
name = spec.name
|
114
|
+
podspec = file.realpath.to_s
|
115
|
+
platform = @platform
|
116
|
+
podfile = Pod::Podfile.new do
|
117
|
+
platform(platform.to_sym, platform.deployment_target)
|
118
|
+
pod name, :podspec => podspec
|
119
|
+
end
|
120
|
+
podfile
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_up_lint_environment
|
124
|
+
tmp_dir.rmtree if tmp_dir.exist?
|
125
|
+
tmp_dir.mkpath
|
126
|
+
@original_config = Config.instance.clone
|
127
|
+
config.project_root = tmp_dir
|
128
|
+
config.project_pods_root = tmp_dir + 'Pods'
|
129
|
+
config.silent = !config.verbose
|
130
|
+
config.integrate_targets = false
|
131
|
+
config.generate_docs = false
|
132
|
+
end
|
133
|
+
|
134
|
+
def tear_down_lint_environment
|
135
|
+
tmp_dir.rmtree unless no_clean
|
136
|
+
Config.instance = @original_config
|
137
|
+
end
|
138
|
+
|
139
|
+
def tmp_dir
|
140
|
+
Pathname.new('/tmp/CocoaPods/Lint')
|
141
|
+
end
|
142
|
+
|
143
|
+
def pod_dir
|
144
|
+
tmp_dir + 'Pods' + spec.name
|
145
|
+
end
|
146
|
+
|
147
|
+
# It reads a podspec file and checks for strings corresponding
|
148
|
+
# to features that are or will be deprecated
|
149
|
+
#
|
150
|
+
# @return [Array<String>]
|
151
|
+
#
|
152
|
+
def deprecation_errors
|
153
|
+
text = @file.read
|
154
|
+
deprecations = []
|
155
|
+
deprecations << "`config.ios?' and `config.osx?' are deprecated" if text. =~ /config\..?os.?/
|
156
|
+
deprecations << "clean_paths are deprecated and ignored (use preserve_paths)" if text. =~ /clean_paths/
|
157
|
+
deprecations
|
158
|
+
end
|
159
|
+
|
160
|
+
# @return [Array<String>] List of the fatal defects detected in a podspec
|
161
|
+
def podspec_errors
|
162
|
+
messages = []
|
163
|
+
messages << "The name of the spec should match the name of the file" unless names_match?
|
164
|
+
messages << "Unrecognized platfrom" unless platform_valid?
|
165
|
+
messages << "Missing name" unless spec.name
|
166
|
+
messages << "Missing version" unless spec.version
|
167
|
+
messages << "Missing summary" unless spec.summary
|
168
|
+
messages << "Missing homepage" unless spec.homepage
|
169
|
+
messages << "Missing author(s)" unless spec.authors
|
170
|
+
messages << "Missing or invalid source: #{spec.source}" unless source_valid?
|
171
|
+
|
172
|
+
# attributes with multiplatform values
|
173
|
+
return messages unless platform_valid?
|
174
|
+
messages << "The spec appears to be empty (no source files, resources, or preserve paths)" if spec.source_files.empty? && spec.subspecs.empty? && spec.resources.empty? && spec.preserve_paths.empty?
|
175
|
+
messages += paths_starting_with_a_slash_errors
|
176
|
+
messages += deprecation_errors
|
177
|
+
messages
|
178
|
+
end
|
179
|
+
|
180
|
+
def names_match?
|
181
|
+
return true unless spec.name
|
182
|
+
root_name = spec.name.match(/[^\/]*/)[0]
|
183
|
+
file.basename.to_s == root_name + '.podspec'
|
184
|
+
end
|
185
|
+
|
186
|
+
def platform_valid?
|
187
|
+
!spec.platform || [:ios, :osx].include?(spec.platform.name)
|
188
|
+
end
|
189
|
+
|
190
|
+
def source_valid?
|
191
|
+
spec.source && !(spec.source =~ /http:\/\/EXAMPLE/)
|
192
|
+
end
|
193
|
+
|
194
|
+
def paths_starting_with_a_slash_errors
|
195
|
+
messages = []
|
196
|
+
%w[source_files public_header_files resources clean_paths].each do |accessor|
|
197
|
+
patterns = spec.send(accessor.to_sym)
|
198
|
+
# Some values are multiplaform
|
199
|
+
patterns = patterns.is_a?(Hash) ? patterns.values.flatten(1) : patterns
|
200
|
+
patterns = patterns.compact # some patterns may be nil (public_header_files, for instance)
|
201
|
+
patterns.each do |pattern|
|
202
|
+
# Skip FileList that would otherwise be resolved from the working directory resulting
|
203
|
+
# in a potentially very expensi operation
|
204
|
+
next if pattern.is_a?(FileList)
|
205
|
+
invalid = pattern.is_a?(Array) ? pattern.any? { |path| path.start_with?('/') } : pattern.start_with?('/')
|
206
|
+
if invalid
|
207
|
+
messages << "Paths cannot start with a slash (#{accessor})"
|
208
|
+
break
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
messages
|
213
|
+
end
|
214
|
+
|
215
|
+
# @return [Array<String>] List of the **non** fatal defects detected in a podspec
|
216
|
+
def podspec_warnings
|
217
|
+
license = spec.license || {}
|
218
|
+
source = spec.source || {}
|
219
|
+
text = @file.read
|
220
|
+
messages = []
|
221
|
+
messages << "Missing license type" unless license[:type]
|
222
|
+
messages << "Sample license type" if license[:type] && license[:type] =~ /\(example\)/
|
223
|
+
messages << "Invalid license type" if license[:type] && license[:type] =~ /\n/
|
224
|
+
messages << "The summary is not meaningful" if spec.summary =~ /A short description of/
|
225
|
+
messages << "The description is not meaningful" if spec.description && spec.description =~ /An optional longer description of/
|
226
|
+
messages << "The summary should end with a dot" if spec.summary !~ /.*\./
|
227
|
+
messages << "The description should end with a dot" if spec.description !~ /.*\./ && spec.description != spec.summary
|
228
|
+
messages << "Git sources should specify either a tag or a commit" if source[:git] && !source[:commit] && !source[:tag]
|
229
|
+
messages << "Github repositories should end in `.git'" if github_source? && source[:git] !~ /.*\.git/
|
230
|
+
messages << "Github repositories should use `https' link" if github_source? && source[:git] !~ /https:\/\/github.com/
|
231
|
+
messages << "Comments must be deleted" if text.scan(/^\s*#/).length > 24
|
232
|
+
messages
|
233
|
+
end
|
234
|
+
|
235
|
+
def github_source?
|
236
|
+
spec.source && spec.source[:git] =~ /github.com/
|
237
|
+
end
|
238
|
+
|
239
|
+
# It creates a podfile in memory and builds a library containing
|
240
|
+
# the pod for all available platfroms with xcodebuild.
|
241
|
+
#
|
242
|
+
# @return [Array<String>]
|
243
|
+
#
|
244
|
+
def xcodebuild_output
|
245
|
+
return [] if `which xcodebuild`.strip.empty?
|
246
|
+
messages = []
|
247
|
+
output = Dir.chdir(config.project_pods_root) { `xcodebuild clean build 2>&1` }
|
248
|
+
clean_output = process_xcode_build_output(output)
|
249
|
+
messages += clean_output
|
250
|
+
puts(output) if config.verbose?
|
251
|
+
messages
|
252
|
+
end
|
253
|
+
|
254
|
+
def process_xcode_build_output(output)
|
255
|
+
output_by_line = output.split("\n")
|
256
|
+
selected_lines = output_by_line.select do |l|
|
257
|
+
l.include?('error: ') && (l !~ /errors? generated\./) && (l !~ /error: \(null\)/)\
|
258
|
+
|| l.include?('warning: ') && (l !~ /warnings? generated\./)\
|
259
|
+
|| l.include?('note: ') && (l !~ /expanded from macro/)
|
260
|
+
end
|
261
|
+
selected_lines.map do |l|
|
262
|
+
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'') # Remove the unnecessary tmp path
|
263
|
+
new.gsub!(/^ */,' ') # Remove indentation
|
264
|
+
"XCODEBUILD > " << new # Mark
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# It checks that every file pattern specified in a spec yields
|
269
|
+
# at least one file. It requires the pods to be alredy present
|
270
|
+
# in the current working directory under Pods/spec.name.
|
271
|
+
#
|
272
|
+
# @return [Array<String>]
|
273
|
+
#
|
274
|
+
def file_patterns_errors
|
275
|
+
messages = []
|
276
|
+
messages << "The sources did not match any file" if !spec.source_files.empty? && @pod.source_files.empty?
|
277
|
+
messages << "The resources did not match any file" if !spec.resources.empty? && @pod.resource_files.empty?
|
278
|
+
messages << "The preserve_paths did not match any file" if !spec.preserve_paths.empty? && @pod.preserve_files.empty?
|
279
|
+
messages << "The exclude_header_search_paths did not match any file" if !spec.exclude_header_search_paths.empty? && @pod.headers_excluded_from_search_paths.empty?
|
280
|
+
messages
|
281
|
+
end
|
282
|
+
|
283
|
+
def file_patterns_warnings
|
284
|
+
messages = []
|
285
|
+
unless @pod.license_file || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
|
286
|
+
messages << "Unable to find a license file"
|
287
|
+
end
|
288
|
+
messages
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
@@ -8,9 +8,10 @@ module Pod
|
|
8
8
|
|
9
9
|
$ pod push REPO [NAME.podspec]
|
10
10
|
|
11
|
-
Validates NAME.podspec or `*.podspec' in the current working dir,
|
12
|
-
|
13
|
-
|
11
|
+
Validates NAME.podspec or `*.podspec' in the current working dir, creates
|
12
|
+
a directory and version folder for the pod in the local copy of
|
13
|
+
REPO (~/.cocoapods/[REPO]), copies the podspec file into the version directory,
|
14
|
+
and finally it pushes REPO to its remote.}
|
14
15
|
end
|
15
16
|
|
16
17
|
def self.options
|
@@ -11,10 +11,20 @@ module Pod
|
|
11
11
|
Clones `URL' in the local spec-repos directory at `~/.cocoapods'. The
|
12
12
|
remote can later be referred to by `NAME'.
|
13
13
|
|
14
|
-
$ pod repo update NAME
|
14
|
+
$ pod repo update [NAME]
|
15
15
|
|
16
16
|
Updates the local clone of the spec-repo `NAME'. If `NAME' is omitted
|
17
|
-
this will update all spec-repos in `~/.cocoapods'.
|
17
|
+
this will update all spec-repos in `~/.cocoapods'.
|
18
|
+
|
19
|
+
$ pod repo update [NAME | DIRECTORY]
|
20
|
+
|
21
|
+
Lints the spec-repo `NAME'. If a directory is provided it is assumed
|
22
|
+
to be the root of a repo. Finally, if NAME is not provided this will
|
23
|
+
lint all the spec-repos known to CocoaPods.}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.options
|
27
|
+
[["--only-errors", "Lint presents only the errors"]].concat(super)
|
18
28
|
end
|
19
29
|
|
20
30
|
extend Executable
|
@@ -29,6 +39,9 @@ module Pod
|
|
29
39
|
@branch = argv.arguments[3]
|
30
40
|
when 'update'
|
31
41
|
@name = argv.arguments[1]
|
42
|
+
when 'lint'
|
43
|
+
@name = argv.arguments[1]
|
44
|
+
@only_errors = argv.option('--only-errors')
|
32
45
|
else
|
33
46
|
super
|
34
47
|
end
|
@@ -66,6 +79,60 @@ module Pod
|
|
66
79
|
end
|
67
80
|
end
|
68
81
|
|
82
|
+
def lint
|
83
|
+
if @name
|
84
|
+
dirs = File.exists?(@name) ? [ Pathname.new(@name) ] : [ dir ]
|
85
|
+
else
|
86
|
+
dirs = config.repos_dir.children.select {|c| c.directory?}
|
87
|
+
end
|
88
|
+
dirs.each do |dir|
|
89
|
+
check_versions(dir)
|
90
|
+
puts "\nLinting spec repo `#{dir.realpath.basename}'\n".yellow
|
91
|
+
podspecs = dir.glob('**/*.podspec')
|
92
|
+
invalid_count = 0
|
93
|
+
|
94
|
+
podspecs.each do |podspec|
|
95
|
+
linter = Linter.new(podspec)
|
96
|
+
linter.quick = true
|
97
|
+
linter.repo_path = dir
|
98
|
+
|
99
|
+
linter.lint
|
100
|
+
|
101
|
+
case linter.result_type
|
102
|
+
when :error
|
103
|
+
invalid_count += 1
|
104
|
+
color = :red
|
105
|
+
should_display = true
|
106
|
+
when :warning
|
107
|
+
color = :yellow
|
108
|
+
should_display = !@only_errors
|
109
|
+
end
|
110
|
+
|
111
|
+
if should_display
|
112
|
+
puts " -> ".send(color) << linter.spec_name
|
113
|
+
print_messages('ERROR', linter.errors)
|
114
|
+
unless @only_errors
|
115
|
+
print_messages('WARN', linter.warnings)
|
116
|
+
print_messages('NOTE', linter.notes)
|
117
|
+
end
|
118
|
+
puts unless config.silent?
|
119
|
+
end
|
120
|
+
end
|
121
|
+
puts "Analyzed #{podspecs.count} podspecs files.\n\n" unless config.silent?
|
122
|
+
|
123
|
+
if invalid_count == 0
|
124
|
+
puts "All the specs passed validation.".green << "\n\n" unless config.silent?
|
125
|
+
else
|
126
|
+
raise Informative, "#{invalid_count} podspecs failed validation."
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def print_messages(type, messages)
|
132
|
+
return if config.silent?
|
133
|
+
messages.each {|msg| puts " - #{type.ljust(5)} | #{msg}"}
|
134
|
+
end
|
135
|
+
|
69
136
|
def check_versions(dir)
|
70
137
|
versions = versions(dir)
|
71
138
|
unless is_compatilbe(versions)
|