cocoapods-core 0.34.4 → 0.35.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cocoapods-core/dependency.rb +15 -0
- data/lib/cocoapods-core/gem_version.rb +1 -1
- data/lib/cocoapods-core/source.rb +6 -1
- data/lib/cocoapods-core/source/aggregate.rb +1 -1
- data/lib/cocoapods-core/specification.rb +14 -4
- data/lib/cocoapods-core/specification/dsl.rb +5 -5
- data/lib/cocoapods-core/specification/linter.rb +65 -51
- data/lib/cocoapods-core/specification/linter/analyzer.rb +29 -23
- data/lib/cocoapods-core/specification/linter/result.rb +55 -53
- data/lib/cocoapods-core/specification/set.rb +5 -81
- data/lib/cocoapods-core/specification/set/presenter.rb +1 -9
- data/lib/cocoapods-core/yaml_helper.rb +2 -0
- metadata +3 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acbdd73d6fbc58893650122dcf22d2f2c23218bc
|
4
|
+
data.tar.gz: da6b9b4be28ca16ea5a3fb2be80642e9493de0ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dca18284145229944534fd07db387e8afdc190eeff2fb61048bee9b4de1233f0d218270b28ea8fa418396f94f7247da5f12cb8fc6a64fe312005be4791473055
|
7
|
+
data.tar.gz: d1db51ab71bf788eb2dc08b1128cd98e6351d8a14aa796162ea046a3f53b4fc207673b4c4d9df8adf997f2db22e88b55b4ca5ca10e518f0639d292fdc49f1502
|
@@ -26,6 +26,12 @@ module Pod
|
|
26
26
|
attr_accessor :head
|
27
27
|
alias_method :head?, :head
|
28
28
|
|
29
|
+
# @return [Bool] whether the dependency came from an invocation of
|
30
|
+
# {Specification#subspec_dependencies} or not.
|
31
|
+
#
|
32
|
+
attr_accessor :from_subspec_dependency
|
33
|
+
alias_method :from_subspec_dependency?, :from_subspec_dependency
|
34
|
+
|
29
35
|
# @overload initialize(name, requirements)
|
30
36
|
#
|
31
37
|
# @param [String] name
|
@@ -247,6 +253,15 @@ module Pod
|
|
247
253
|
dep
|
248
254
|
end
|
249
255
|
|
256
|
+
# Whether the dependency has any pre-release requirements
|
257
|
+
#
|
258
|
+
# @return [Bool] Whether the dependency has any pre-release requirements
|
259
|
+
#
|
260
|
+
def prerelease?
|
261
|
+
@prerelease ||= requirement.requirements.
|
262
|
+
any? { |r| Version.new(r[1].version).prerelease? }
|
263
|
+
end
|
264
|
+
|
250
265
|
# Checks whether the dependency would be satisfied by the specification
|
251
266
|
# with the given name and version.
|
252
267
|
#
|
@@ -32,9 +32,14 @@ module Pod
|
|
32
32
|
|
33
33
|
# @return [String] The URL of the source.
|
34
34
|
#
|
35
|
+
# @note In the past we had used `git ls-remote --get-url`, but this could
|
36
|
+
# lead to an issue when finding a source based on its URL when `git`
|
37
|
+
# is configured to rewrite URLs with the `url.<base>.insteadOf`
|
38
|
+
# option. See https://github.com/CocoaPods/CocoaPods/issues/2724.
|
39
|
+
#
|
35
40
|
def url
|
36
41
|
Dir.chdir(repo) do
|
37
|
-
remote = `git
|
42
|
+
remote = `git config --get remote.origin.url`.chomp
|
38
43
|
|
39
44
|
if $?.success?
|
40
45
|
remote
|
@@ -165,7 +165,7 @@ module Pod
|
|
165
165
|
has_data = set_data && set_data['version']
|
166
166
|
if has_data
|
167
167
|
stored_version = Version.new(set_data['version'])
|
168
|
-
if stored_version < set.
|
168
|
+
if stored_version < set.highest_version
|
169
169
|
search_data[set.name] = search_data_from_set(set)
|
170
170
|
end
|
171
171
|
else
|
@@ -191,13 +191,17 @@ module Pod
|
|
191
191
|
# the relative name of the subspecs starting from the receiver
|
192
192
|
# including the name of the receiver.
|
193
193
|
#
|
194
|
+
# @param [Boolean] raise_if_missing
|
195
|
+
# whether an exception should be raised if no specification named
|
196
|
+
# `relative_name` is found.
|
197
|
+
#
|
194
198
|
# @example Retrieving a subspec
|
195
199
|
#
|
196
200
|
# s.subspec_by_name('Pod/subspec').name #=> 'subspec'
|
197
201
|
#
|
198
202
|
# @return [Specification] the subspec with the given name or self.
|
199
203
|
#
|
200
|
-
def subspec_by_name(relative_name)
|
204
|
+
def subspec_by_name(relative_name, raise_if_missing = true)
|
201
205
|
if relative_name.nil? || relative_name == base_name
|
202
206
|
self
|
203
207
|
else
|
@@ -205,8 +209,12 @@ module Pod
|
|
205
209
|
subspec_name = remainder.split('/').shift
|
206
210
|
subspec = subspecs.find { |s| s.base_name == subspec_name }
|
207
211
|
unless subspec
|
208
|
-
|
209
|
-
|
212
|
+
if raise_if_missing
|
213
|
+
raise Informative, 'Unable to find a specification named ' \
|
214
|
+
"`#{relative_name}` in `#{name} (#{version})`."
|
215
|
+
else
|
216
|
+
return nil
|
217
|
+
end
|
210
218
|
end
|
211
219
|
subspec.subspec_by_name(remainder)
|
212
220
|
end
|
@@ -238,7 +246,9 @@ module Pod
|
|
238
246
|
if platform
|
239
247
|
specs = specs.select { |s| s.supported_on_platform?(platform) }
|
240
248
|
end
|
241
|
-
specs.map
|
249
|
+
specs.map do |s|
|
250
|
+
Dependency.new(s.name, version).tap { |d| d.from_subspec_dependency = self }
|
251
|
+
end
|
242
252
|
end
|
243
253
|
|
244
254
|
# Returns the dependencies on other Pods or subspecs of other Pods.
|
@@ -232,10 +232,10 @@ module Pod
|
|
232
232
|
# The keys accepted by the hash of the source attribute.
|
233
233
|
#
|
234
234
|
SOURCE_KEYS = {
|
235
|
-
:git
|
236
|
-
:svn
|
237
|
-
:hg
|
238
|
-
:http => [:type, :sha256, :sha1],
|
235
|
+
:git => [:tag, :branch, :commit, :submodules].freeze,
|
236
|
+
:svn => [:folder, :tag, :revision].freeze,
|
237
|
+
:hg => [:revision].freeze,
|
238
|
+
:http => [:flatten, :type, :sha256, :sha1].freeze,
|
239
239
|
:path => nil,
|
240
240
|
}.freeze
|
241
241
|
|
@@ -1134,7 +1134,7 @@ module Pod
|
|
1134
1134
|
# pod 'ShareKit', '2.0'
|
1135
1135
|
#
|
1136
1136
|
# Installs ShareKit with all the sharers like `ShareKit/Evernote`,
|
1137
|
-
# `ShareKit/Facebook`, etc, as they are defined
|
1137
|
+
# `ShareKit/Facebook`, etc, as they are defined as subspecs.
|
1138
1138
|
#
|
1139
1139
|
# pod 'ShareKit/Twitter', '2.0'
|
1140
1140
|
# pod 'ShareKit/Pinboard', '2.0'
|
@@ -9,8 +9,6 @@ module Pod
|
|
9
9
|
# specification, but also to support the maintenance of sources.
|
10
10
|
#
|
11
11
|
class Linter
|
12
|
-
include ResultHelpers
|
13
|
-
|
14
12
|
# @return [Specification] the specification to lint.
|
15
13
|
#
|
16
14
|
attr_reader :spec
|
@@ -20,6 +18,8 @@ module Pod
|
|
20
18
|
#
|
21
19
|
attr_reader :file
|
22
20
|
|
21
|
+
attr_reader :results
|
22
|
+
|
23
23
|
# @param [Specification, Pathname, String] spec_or_path
|
24
24
|
# the Specification or the path of the `podspec` file to lint.
|
25
25
|
#
|
@@ -39,20 +39,19 @@ module Pod
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Lints the specification adding a {Result} for any failed check to the
|
42
|
-
# {#results}
|
42
|
+
# {#results} object.
|
43
43
|
#
|
44
44
|
# @return [Bool] whether the specification passed validation.
|
45
45
|
#
|
46
46
|
def lint
|
47
|
-
@results =
|
47
|
+
@results = Results.new
|
48
48
|
if spec
|
49
49
|
check_required_root_attributes
|
50
50
|
run_root_validation_hooks
|
51
51
|
perform_all_specs_analysis
|
52
52
|
else
|
53
|
-
|
54
|
-
|
55
|
-
"\n\n#{@raise_message}"
|
53
|
+
results.add_error "[spec] The specification defined in `#{file}` "\
|
54
|
+
"could not be loaded.\n\n#{@raise_message}"
|
56
55
|
end
|
57
56
|
results.empty?
|
58
57
|
end
|
@@ -92,9 +91,11 @@ module Pod
|
|
92
91
|
next unless attr.required?
|
93
92
|
unless value && (!value.respond_to?(:empty?) || !value.empty?)
|
94
93
|
if attr.name == :license
|
95
|
-
|
94
|
+
results.add_warning('[attributes] Missing required attribute' \
|
95
|
+
"`#{attr.name}`.")
|
96
96
|
else
|
97
|
-
|
97
|
+
results.add_error('[attributes] Missing required attribute' \
|
98
|
+
"`#{attr.name}`.")
|
98
99
|
end
|
99
100
|
end
|
100
101
|
end
|
@@ -118,11 +119,12 @@ module Pod
|
|
118
119
|
all_specs.each do |current_spec|
|
119
120
|
current_spec.available_platforms.each do |platform|
|
120
121
|
@consumer = Specification::Consumer.new(current_spec, platform)
|
122
|
+
results.consumer = @consumer
|
121
123
|
run_all_specs_validation_hooks
|
122
|
-
analyzer = Analyzer.new(@consumer)
|
123
|
-
analyzer.analyze
|
124
|
-
add_results(analyzer.results)
|
124
|
+
analyzer = Analyzer.new(@consumer, results)
|
125
|
+
results = analyzer.analyze
|
125
126
|
@consumer = nil
|
127
|
+
results.consumer = nil
|
126
128
|
end
|
127
129
|
end
|
128
130
|
end
|
@@ -174,25 +176,28 @@ module Pod
|
|
174
176
|
]
|
175
177
|
names_match = acceptable_names.include?(file.basename.to_s)
|
176
178
|
unless names_match
|
177
|
-
|
178
|
-
|
179
|
+
results.add_error '[name] The name of the spec should match the ' \
|
180
|
+
'name of the file.'
|
179
181
|
end
|
180
182
|
|
181
183
|
if spec.root.name =~ /\s/
|
182
|
-
|
184
|
+
results.add_error '[name] The name of a spec should not contain ' \
|
185
|
+
'whitespace.'
|
183
186
|
end
|
184
187
|
|
185
188
|
if spec.root.name[0, 1] == '.'
|
186
|
-
|
189
|
+
results.add_error '[name] The name of a spec should not begin' \
|
190
|
+
' with a period.'
|
187
191
|
end
|
188
192
|
end
|
189
193
|
end
|
190
194
|
|
191
195
|
def _validate_version(v)
|
192
196
|
if v.to_s.empty?
|
193
|
-
|
197
|
+
results.add_error '[version] A version is required.'
|
194
198
|
elsif v <= Version::ZERO
|
195
|
-
|
199
|
+
results.add_error '[version] The version of the spec should be' \
|
200
|
+
' higher than 0.'
|
196
201
|
end
|
197
202
|
end
|
198
203
|
|
@@ -200,11 +205,11 @@ module Pod
|
|
200
205
|
#
|
201
206
|
def _validate_summary(s)
|
202
207
|
if s.length > 140
|
203
|
-
|
204
|
-
|
208
|
+
results.add_warning '[summary] The summary should be a short ' \
|
209
|
+
'version of `description` (max 140 characters).'
|
205
210
|
end
|
206
211
|
if s =~ /A short description of/
|
207
|
-
|
212
|
+
results.add_warning '[summary] The summary is not meaningful.'
|
208
213
|
end
|
209
214
|
end
|
210
215
|
|
@@ -212,13 +217,15 @@ module Pod
|
|
212
217
|
#
|
213
218
|
def _validate_description(d)
|
214
219
|
if d =~ /An optional longer description of/
|
215
|
-
|
220
|
+
results.add_warning '[description] The description is not meaningful.'
|
216
221
|
end
|
217
222
|
if d == spec.summary
|
218
|
-
|
223
|
+
results.add_warning '[description] The description is equal to' \
|
224
|
+
' the summary.'
|
219
225
|
end
|
220
226
|
if d.length < spec.summary.length
|
221
|
-
|
227
|
+
results.add_warning '[description] The description is shorter ' \
|
228
|
+
'than the summary.'
|
222
229
|
end
|
223
230
|
end
|
224
231
|
|
@@ -226,7 +233,8 @@ module Pod
|
|
226
233
|
#
|
227
234
|
def _validate_homepage(h)
|
228
235
|
if h =~ %r{http://EXAMPLE}
|
229
|
-
|
236
|
+
results.add_warning '[homepage] The homepage has not been updated' \
|
237
|
+
' from default'
|
230
238
|
end
|
231
239
|
end
|
232
240
|
|
@@ -234,7 +242,8 @@ module Pod
|
|
234
242
|
#
|
235
243
|
def _validate_frameworks(frameworks)
|
236
244
|
if frameworks_invalid?(frameworks)
|
237
|
-
|
245
|
+
results.add_error '[frameworks] A framework should only be' \
|
246
|
+
' specified by its name'
|
238
247
|
end
|
239
248
|
end
|
240
249
|
|
@@ -242,8 +251,8 @@ module Pod
|
|
242
251
|
#
|
243
252
|
def _validate_weak_frameworks(frameworks)
|
244
253
|
if frameworks_invalid?(frameworks)
|
245
|
-
|
246
|
-
'by its name'
|
254
|
+
results.add_error '[weak_frameworks] A weak framework should only be' \
|
255
|
+
' specified by its name'
|
247
256
|
end
|
248
257
|
end
|
249
258
|
|
@@ -253,17 +262,19 @@ module Pod
|
|
253
262
|
libs.each do |lib|
|
254
263
|
lib = lib.downcase
|
255
264
|
if lib.end_with?('.a') || lib.end_with?('.dylib')
|
256
|
-
|
265
|
+
results.add_error '[libraries] Libraries should not include the' \
|
266
|
+
' extension ' \
|
257
267
|
"(`#{lib}`)"
|
258
268
|
end
|
259
269
|
|
260
270
|
if lib.start_with?('lib')
|
261
|
-
|
271
|
+
results.add_error '[libraries] Libraries should omit the `lib`' \
|
272
|
+
' prefix ' \
|
262
273
|
" (`#{lib}`)"
|
263
274
|
end
|
264
275
|
|
265
276
|
if lib.include?(',')
|
266
|
-
|
277
|
+
results.add_error '[libraries] Libraries should not include comas ' \
|
267
278
|
"(`#{lib}`)"
|
268
279
|
end
|
269
280
|
end
|
@@ -275,16 +286,16 @@ module Pod
|
|
275
286
|
type = l[:type]
|
276
287
|
file = l[:file]
|
277
288
|
if type.nil?
|
278
|
-
|
289
|
+
results.add_warning '[license] Missing license type.'
|
279
290
|
end
|
280
291
|
if type && type.gsub(' ', '').gsub("\n", '').empty?
|
281
|
-
|
292
|
+
results.add_warning '[license] Invalid license type.'
|
282
293
|
end
|
283
294
|
if type && type =~ /\(example\)/
|
284
|
-
|
295
|
+
results.add_error '[license] Sample license type.'
|
285
296
|
end
|
286
297
|
if file && Pathname.new(file).extname !~ /^(\.(txt|md|markdown|))?$/i
|
287
|
-
|
298
|
+
results.add_error '[license] Invalid file type'
|
288
299
|
end
|
289
300
|
end
|
290
301
|
|
@@ -296,16 +307,19 @@ module Pod
|
|
296
307
|
version = spec.version.to_s
|
297
308
|
|
298
309
|
if git =~ %r{http://EXAMPLE}
|
299
|
-
|
310
|
+
results.add_error '[source] The Git source still contains the ' \
|
311
|
+
'example URL.'
|
300
312
|
end
|
301
313
|
if commit && commit.downcase =~ /head/
|
302
|
-
|
314
|
+
results.add_error '[source] The commit of a Git source cannot be' \
|
315
|
+
' `HEAD`.'
|
303
316
|
end
|
304
317
|
if tag && !tag.to_s.include?(version)
|
305
|
-
|
318
|
+
results.add_warning '[source] The version should be included in' \
|
319
|
+
' the Git tag.'
|
306
320
|
end
|
307
321
|
if tag.nil?
|
308
|
-
|
322
|
+
results.add_warning '[source] Git sources should specify a tag.'
|
309
323
|
end
|
310
324
|
end
|
311
325
|
|
@@ -322,17 +336,17 @@ module Pod
|
|
322
336
|
return unless git =~ /^#{URI.regexp}$/
|
323
337
|
git_uri = URI.parse(git)
|
324
338
|
if git_uri.host == 'www.github.com'
|
325
|
-
|
326
|
-
|
339
|
+
results.add_warning '[github_sources] Github repositories should ' \
|
340
|
+
'not use `www` in their URL.'
|
327
341
|
end
|
328
342
|
if git_uri.host == 'github.com' || git_uri.host == 'gist.github.com'
|
329
343
|
unless git.end_with?('.git')
|
330
|
-
|
331
|
-
'`.git`.'
|
344
|
+
results.add_warning '[github_sources] Github repositories ' \
|
345
|
+
'should end in `.git`.'
|
332
346
|
end
|
333
347
|
unless git_uri.scheme == 'https'
|
334
|
-
|
335
|
-
|
348
|
+
results.add_warning '[github_sources] Github repositories ' \
|
349
|
+
'should use an `https` link.'
|
336
350
|
end
|
337
351
|
end
|
338
352
|
end
|
@@ -343,9 +357,9 @@ module Pod
|
|
343
357
|
def check_git_ssh_source(s)
|
344
358
|
if git = s[:git]
|
345
359
|
if git =~ /\w+\@(\w|\.)+\:(\/\w+)*/
|
346
|
-
|
347
|
-
'firewalls configured to only allow HTTP,
|
348
|
-
'preferred.'
|
360
|
+
results.add_warning '[source] Git SSH URLs will NOT work for ' \
|
361
|
+
'people behind firewalls configured to only allow HTTP, ' \
|
362
|
+
'therefore HTTPS is preferred.'
|
349
363
|
end
|
350
364
|
end
|
351
365
|
end
|
@@ -354,8 +368,8 @@ module Pod
|
|
354
368
|
#
|
355
369
|
def _validate_social_media_url(s)
|
356
370
|
if s =~ %r{https://twitter.com/EXAMPLE}
|
357
|
-
|
358
|
-
|
371
|
+
results.add_warning '[social_media_url] The social media URL has ' \
|
372
|
+
'not been updated from the default.'
|
359
373
|
end
|
360
374
|
end
|
361
375
|
|
@@ -369,7 +383,7 @@ module Pod
|
|
369
383
|
#
|
370
384
|
def _validate_compiler_flags(flags)
|
371
385
|
if flags.join(' ').split(' ').any? { |flag| flag.start_with?('-Wno') }
|
372
|
-
|
386
|
+
results.add_warning '[compiler_flags] Warnings must not be disabled' \
|
373
387
|
'(`-Wno compiler` flags).'
|
374
388
|
end
|
375
389
|
end
|
@@ -4,23 +4,30 @@ module Pod
|
|
4
4
|
class Specification
|
5
5
|
class Linter
|
6
6
|
class Analyzer
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(consumer)
|
7
|
+
def initialize(consumer, results)
|
10
8
|
@consumer = consumer
|
11
|
-
@results =
|
9
|
+
@results = results
|
10
|
+
@results.consumer = @consumer
|
12
11
|
end
|
13
12
|
|
13
|
+
# Analyzes the consumer adding a {Result} for any failed check to
|
14
|
+
# the {#results} object.
|
15
|
+
#
|
16
|
+
# @return [Results] the results of the analysis.
|
17
|
+
#
|
14
18
|
def analyze
|
15
19
|
check_attributes
|
16
20
|
validate_file_patterns
|
17
21
|
check_if_spec_is_empty
|
22
|
+
results
|
18
23
|
end
|
19
24
|
|
20
25
|
private
|
21
26
|
|
22
27
|
attr_reader :consumer
|
23
28
|
|
29
|
+
attr_reader :results
|
30
|
+
|
24
31
|
# Checks the attributes hash for any unknown key which might be the
|
25
32
|
# result of a misspelling in a JSON file.
|
26
33
|
#
|
@@ -46,7 +53,7 @@ module Pod
|
|
46
53
|
unknown_keys = keys - valid_keys
|
47
54
|
|
48
55
|
unknown_keys.each do |key|
|
49
|
-
|
56
|
+
results.add_warning "Unrecognized `#{key}` key"
|
50
57
|
end
|
51
58
|
|
52
59
|
Pod::Specification::DSL.attributes.each do |_key, attribute|
|
@@ -74,8 +81,8 @@ module Pod
|
|
74
81
|
end
|
75
82
|
patterns.each do |pattern|
|
76
83
|
if pattern.start_with?('/')
|
77
|
-
|
78
|
-
|
84
|
+
results.add_error '[File Patterns] File patterns must be ' \
|
85
|
+
"relative and cannot start with a slash (#{attrb.name})."
|
79
86
|
end
|
80
87
|
end
|
81
88
|
end
|
@@ -84,16 +91,15 @@ module Pod
|
|
84
91
|
# Check empty subspec attributes
|
85
92
|
#
|
86
93
|
def check_if_spec_is_empty
|
87
|
-
methods = %w( source_files resources resource_bundles preserve_paths
|
88
|
-
vendored_libraries vendored_frameworks )
|
94
|
+
methods = %w( source_files resources resource_bundles preserve_paths
|
95
|
+
dependencies vendored_libraries vendored_frameworks )
|
89
96
|
empty_patterns = methods.all? { |m| consumer.send(m).empty? }
|
90
97
|
empty = empty_patterns && consumer.spec.subspecs.empty?
|
91
98
|
if empty
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
'or subspecs).'
|
99
|
+
results.add_error "[File Patterns] The #{consumer.spec} spec is " \
|
100
|
+
'empty (no source files, resources, resource_bundles, ' \
|
101
|
+
'preserve paths, vendored_libraries, vendored_frameworks, ' \
|
102
|
+
'dependencies, nor subspecs).'
|
97
103
|
end
|
98
104
|
end
|
99
105
|
|
@@ -119,29 +125,29 @@ module Pod
|
|
119
125
|
def validate_attribute_array_keys(attribute, value)
|
120
126
|
unknown_keys = value.keys.map(&:to_s) - attribute.keys.map(&:to_s)
|
121
127
|
unknown_keys.each do |unknown_key|
|
122
|
-
|
123
|
-
"`#{attribute.name}` attribute"
|
128
|
+
results.add_warning "Unrecognized `#{unknown_key}` key for " \
|
129
|
+
"`#{attribute.name}` attribute."
|
124
130
|
end
|
125
131
|
end
|
126
132
|
|
127
133
|
def validate_attribute_hash_keys(attribute, value)
|
128
134
|
major_keys = value.keys & attribute.keys.keys
|
129
135
|
if major_keys.count.zero?
|
130
|
-
|
136
|
+
results.add_warning "Missing primary key for `#{attribute.name}` " \
|
131
137
|
'attribute. The acceptable ones are: ' \
|
132
|
-
"`#{attribute.keys.keys.map(&:to_s).sort.join(', ')}
|
138
|
+
"`#{attribute.keys.keys.map(&:to_s).sort.join(', ')}`."
|
133
139
|
elsif major_keys.count == 1
|
134
140
|
acceptable = attribute.keys[major_keys.first] || []
|
135
141
|
unknown = value.keys - major_keys - acceptable
|
136
142
|
unless unknown.empty?
|
137
|
-
|
138
|
-
"with `#{major_keys.first}` primary key for " \
|
139
|
-
"`#{attribute.name}` attribute"
|
143
|
+
results.add_warning "Incompatible `#{unknown.sort.join(', ')}` " \
|
144
|
+
"key(s) with `#{major_keys.first}` primary key for " \
|
145
|
+
"`#{attribute.name}` attribute."
|
140
146
|
end
|
141
147
|
else
|
142
148
|
sorted_keys = major_keys.map(&:to_s).sort
|
143
|
-
|
144
|
-
"`#{attribute.name}` attribute"
|
149
|
+
results.add_warning "Incompatible `#{sorted_keys.join(', ')}` " \
|
150
|
+
"keys for `#{attribute.name}` attribute."
|
145
151
|
end
|
146
152
|
end
|
147
153
|
end
|
@@ -1,51 +1,64 @@
|
|
1
1
|
module Pod
|
2
2
|
class Specification
|
3
3
|
class Linter
|
4
|
-
class
|
5
|
-
|
6
|
-
#
|
7
|
-
attr_reader :type
|
4
|
+
class Results
|
5
|
+
public
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
class Result
|
8
|
+
# @return [Symbol] the type of result.
|
9
|
+
#
|
10
|
+
attr_reader :type
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def initialize(type, message)
|
17
|
-
@type = type
|
18
|
-
@message = message
|
19
|
-
@platforms = []
|
20
|
-
end
|
12
|
+
# @return [String] the message associated with result.
|
13
|
+
#
|
14
|
+
attr_reader :message
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
# @param [Symbol] type @see type
|
17
|
+
# @param [String] message @see message
|
18
|
+
#
|
19
|
+
def initialize(type, message)
|
20
|
+
@type = type
|
21
|
+
@message = message
|
22
|
+
@platforms = []
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
# @return [Array<Platform>] the platforms where this result was
|
26
|
+
# generated.
|
27
|
+
#
|
28
|
+
attr_reader :platforms
|
29
|
+
|
30
|
+
# @return [String] a string representation suitable for UI output.
|
31
|
+
#
|
32
|
+
def to_s
|
33
|
+
r = "[#{type.to_s.upcase}] #{message}"
|
34
|
+
if platforms != Specification::PLATFORMS
|
35
|
+
platforms_names = platforms.uniq.map do |p|
|
36
|
+
Platform.string_name(p)
|
37
|
+
end
|
38
|
+
r << " [#{platforms_names * ' - '}]" unless platforms.empty?
|
34
39
|
end
|
35
|
-
r
|
40
|
+
r
|
36
41
|
end
|
37
|
-
r
|
38
42
|
end
|
39
|
-
end
|
40
43
|
|
41
|
-
|
42
|
-
|
44
|
+
def initialize
|
45
|
+
@results = []
|
46
|
+
@consumer = nil
|
47
|
+
end
|
43
48
|
|
44
|
-
|
45
|
-
#
|
46
|
-
attr_reader :results
|
49
|
+
include Enumerable
|
47
50
|
|
48
|
-
|
51
|
+
def each
|
52
|
+
results.each { |r| yield r }
|
53
|
+
end
|
54
|
+
|
55
|
+
def empty?
|
56
|
+
results.empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Specification::Consumer] the current consumer.
|
60
|
+
#
|
61
|
+
attr_accessor :consumer
|
49
62
|
|
50
63
|
# Adds an error result with the given message.
|
51
64
|
#
|
@@ -54,7 +67,7 @@ module Pod
|
|
54
67
|
#
|
55
68
|
# @return [void]
|
56
69
|
#
|
57
|
-
def
|
70
|
+
def add_error(message)
|
58
71
|
add_result(:error, message)
|
59
72
|
end
|
60
73
|
|
@@ -65,26 +78,15 @@ module Pod
|
|
65
78
|
#
|
66
79
|
# @return [void]
|
67
80
|
#
|
68
|
-
def
|
81
|
+
def add_warning(message)
|
69
82
|
add_result(:warning, message)
|
70
83
|
end
|
71
84
|
|
72
|
-
|
73
|
-
|
74
|
-
# @
|
75
|
-
# The results to be merged.
|
76
|
-
#
|
77
|
-
# @return [void]
|
85
|
+
private
|
86
|
+
|
87
|
+
# @return [Array<Result>] all of the generated results.
|
78
88
|
#
|
79
|
-
|
80
|
-
results.each do |result|
|
81
|
-
if result.type == :warning
|
82
|
-
warning(result.message)
|
83
|
-
else
|
84
|
-
error(result.message)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
89
|
+
attr_reader :results
|
88
90
|
|
89
91
|
# Adds a result of the given type with the given message. If there is a
|
90
92
|
# current platform it is added to the result. If a result with the same
|
@@ -105,7 +107,7 @@ module Pod
|
|
105
107
|
result = Result.new(type, message)
|
106
108
|
results << result
|
107
109
|
end
|
108
|
-
result.platforms << consumer.platform_name if consumer
|
110
|
+
result.platforms << @consumer.platform_name if @consumer
|
109
111
|
end
|
110
112
|
end
|
111
113
|
end
|
@@ -33,50 +33,6 @@ module Pod
|
|
33
33
|
def initialize(name, sources = [])
|
34
34
|
@name = name
|
35
35
|
@sources = Array(sources)
|
36
|
-
@dependencies_by_requirer_name = {}
|
37
|
-
@dependencies = []
|
38
|
-
end
|
39
|
-
|
40
|
-
# Stores a dependency on the Pod.
|
41
|
-
#
|
42
|
-
# @param [Dependency] dependency
|
43
|
-
# a dependency that requires the Pod.
|
44
|
-
#
|
45
|
-
# @param [String] dependent_name
|
46
|
-
# the name of the owner of the dependency. It is used only to
|
47
|
-
# display the Pod::Informative.
|
48
|
-
#
|
49
|
-
# @raise If the versions requirement of the dependency are not
|
50
|
-
# compatible with the previously stored dependencies.
|
51
|
-
#
|
52
|
-
# @todo This should simply return a boolean. Is CocoaPods that should
|
53
|
-
# raise.
|
54
|
-
#
|
55
|
-
# @return [void]
|
56
|
-
#
|
57
|
-
def required_by(dependency, dependent_name)
|
58
|
-
dependencies_by_requirer_name[dependent_name] ||= []
|
59
|
-
dependencies_by_requirer_name[dependent_name] << dependency
|
60
|
-
dependencies << dependency
|
61
|
-
|
62
|
-
if acceptable_versions.empty?
|
63
|
-
message = "Unable to satisfy the following requirements:\n\n"
|
64
|
-
dependencies_by_requirer_name.each do |name, dependencies|
|
65
|
-
dependencies.each do |dep|
|
66
|
-
message << "- `#{dep}` required by `#{name}`\n"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
raise Informative, message
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# @return [Dependency] A dependency that includes all the versions
|
74
|
-
# requirements of the stored dependencies.
|
75
|
-
#
|
76
|
-
def dependency
|
77
|
-
dependencies.reduce(Dependency.new(name)) do |previous, dependency|
|
78
|
-
previous.merge(dependency.to_root_dependency)
|
79
|
-
end
|
80
36
|
end
|
81
37
|
|
82
38
|
# @return [Specification] the top level specification of the Pod for the
|
@@ -87,37 +43,15 @@ module Pod
|
|
87
43
|
# is used to disambiguate.
|
88
44
|
#
|
89
45
|
def specification
|
90
|
-
|
91
|
-
Specification.from_file(path)
|
46
|
+
Specification.from_file(highest_version_spec_path)
|
92
47
|
end
|
93
48
|
|
94
49
|
# @return [Array<String>] the paths to specifications for the given
|
95
50
|
# version
|
96
51
|
#
|
97
|
-
def specification_paths_for_version(
|
98
|
-
sources = @sources.select { |source| versions_by_source[source].include?(
|
99
|
-
sources.map { |source| source.specification_path(name,
|
100
|
-
end
|
101
|
-
|
102
|
-
# @return [Version] the highest version that satisfies the stored
|
103
|
-
# dependencies.
|
104
|
-
#
|
105
|
-
# @todo This should simply return nil. CocoaPods should raise instead.
|
106
|
-
#
|
107
|
-
def required_version
|
108
|
-
version = versions.find { |v| dependency.match?(name, v) }
|
109
|
-
unless version
|
110
|
-
raise Informative, "Required version (#{dependency}) not found " \
|
111
|
-
"for `#{name}`.\nAvailable versions: #{versions.join(', ')}"
|
112
|
-
end
|
113
|
-
version
|
114
|
-
end
|
115
|
-
|
116
|
-
# @return [Array<Version>] All the versions which are acceptable given
|
117
|
-
# the requirements.
|
118
|
-
#
|
119
|
-
def acceptable_versions
|
120
|
-
versions.select { |v| dependency.match?(name, v) }
|
52
|
+
def specification_paths_for_version(version)
|
53
|
+
sources = @sources.select { |source| versions_by_source[source].include?(version) }
|
54
|
+
sources.map { |source| source.specification_path(name, version) }
|
121
55
|
end
|
122
56
|
|
123
57
|
# @return [Array<Version>] all the available versions for the Pod, sorted
|
@@ -161,8 +95,7 @@ module Pod
|
|
161
95
|
end
|
162
96
|
|
163
97
|
def to_s
|
164
|
-
"#<#{self.class.name} for `#{name}'
|
165
|
-
"`#{required_version}' available at `#{sources.map(&:name) * ', '}'>"
|
98
|
+
"#<#{self.class.name} for `#{name}' available at `#{sources.map(&:name).join(', ')}'>"
|
166
99
|
end
|
167
100
|
alias_method :inspect, :to_s
|
168
101
|
|
@@ -192,11 +125,6 @@ module Pod
|
|
192
125
|
|
193
126
|
#-----------------------------------------------------------------------#
|
194
127
|
|
195
|
-
attr_accessor :dependencies_by_requirer_name
|
196
|
-
attr_accessor :dependencies
|
197
|
-
|
198
|
-
#-----------------------------------------------------------------------#
|
199
|
-
|
200
128
|
# The Set::External class handles Pods from external sources. Pods from
|
201
129
|
# external sources don't use the {Source} and are initialized by a given
|
202
130
|
# specification.
|
@@ -215,10 +143,6 @@ module Pod
|
|
215
143
|
self.class == other.class && specification == other.specification
|
216
144
|
end
|
217
145
|
|
218
|
-
def specification_path
|
219
|
-
raise StandardError, 'specification_path'
|
220
|
-
end
|
221
|
-
|
222
146
|
def versions
|
223
147
|
[specification.version]
|
224
148
|
end
|
@@ -90,17 +90,9 @@ module Pod
|
|
90
90
|
#
|
91
91
|
# "Author 1, Author 2 and Author 3"
|
92
92
|
#
|
93
|
-
# @note In ruby 1.8.7 the authors are sorted by name because the
|
94
|
-
# hash doesn't preserve the order in which they are defined
|
95
|
-
# in the podspec.
|
96
|
-
#
|
97
93
|
def authors
|
98
94
|
return '' unless spec.authors
|
99
|
-
|
100
|
-
spec.authors.keys.sort.to_sentence
|
101
|
-
else
|
102
|
-
spec.authors.keys.to_sentence
|
103
|
-
end
|
95
|
+
spec.authors.keys.to_sentence
|
104
96
|
end
|
105
97
|
|
106
98
|
# @return [String] the homepage of the pod.
|
@@ -14,6 +14,8 @@ module Pod
|
|
14
14
|
# The missing features include:
|
15
15
|
# - Strings are never quoted even when ambiguous.
|
16
16
|
#
|
17
|
+
# @todo Remove any code required solely for Ruby 1.8.x.
|
18
|
+
#
|
17
19
|
class YAMLHelper
|
18
20
|
class << self
|
19
21
|
# Returns the YAML representation of the given object. If the given object
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocoapods-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.35.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eloy Duran
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-11-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -39,20 +39,6 @@ dependencies:
|
|
39
39
|
- - ~>
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 0.8.0
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: json_pure
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - ~>
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '1.8'
|
49
|
-
type: :runtime
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - ~>
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '1.8'
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: fuzzy_match
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
129
|
requirements:
|
144
130
|
- - '>='
|
145
131
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
132
|
+
version: 2.0.0
|
147
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
134
|
requirements:
|
149
135
|
- - '>='
|
@@ -156,4 +142,3 @@ signing_key:
|
|
156
142
|
specification_version: 3
|
157
143
|
summary: The models of CocoaPods
|
158
144
|
test_files: []
|
159
|
-
has_rdoc:
|