cocoapods-core 1.7.5 → 1.8.0.beta.1
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.
- checksums.yaml +4 -4
- data/lib/cocoapods-core.rb +1 -1
- data/lib/cocoapods-core/cdn_source.rb +80 -22
- data/lib/cocoapods-core/dependency.rb +2 -25
- data/lib/cocoapods-core/gem_version.rb +1 -1
- data/lib/cocoapods-core/http.rb +11 -9
- data/lib/cocoapods-core/lockfile.rb +1 -1
- data/lib/cocoapods-core/podfile/dsl.rb +33 -33
- data/lib/cocoapods-core/podfile/target_definition.rb +43 -0
- data/lib/cocoapods-core/source.rb +14 -3
- data/lib/cocoapods-core/source/manager.rb +46 -16
- data/lib/cocoapods-core/specification.rb +23 -9
- data/lib/cocoapods-core/specification/consumer.rb +38 -6
- data/lib/cocoapods-core/specification/dsl.rb +70 -3
- data/lib/cocoapods-core/specification/linter.rb +41 -11
- data/lib/cocoapods-core/specification/linter/analyzer.rb +4 -0
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +6 -6
- data/lib/cocoapods-core/trunk_source.rb +14 -0
- data/lib/cocoapods-core/version.rb +3 -4
- metadata +17 -3
- data/lib/cocoapods-core/master_source.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3b9cb102f03fac7ec166a52c1d0b47a4b0bcefec61664061dc1136b96db2d81
|
4
|
+
data.tar.gz: a568022e39121dae7ee044b60d58369e543698e6261f5bfc1dafb3469da18512
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4f4dad80c9d988f64f83235c53ebc0e532207cda1fb0a7704248d97a4ad733e26831c42f39e2a80fd2a46ceda271ce39fd2c7d76bbff1f0f42a2116ac364473
|
7
|
+
data.tar.gz: 73492f7437077ac6f9bfda2edae47a56868b3a3fefb3fc1f37cd6eb739593cd57accb2256a198950ffb3b912f9449807cceb354850c83e1f7c3c137a1db5d4ba
|
data/lib/cocoapods-core.rb
CHANGED
@@ -28,7 +28,7 @@ module Pod
|
|
28
28
|
autoload :Podfile, 'cocoapods-core/podfile'
|
29
29
|
autoload :Source, 'cocoapods-core/source'
|
30
30
|
autoload :CDNSource, 'cocoapods-core/cdn_source'
|
31
|
-
autoload :
|
31
|
+
autoload :TrunkSource, 'cocoapods-core/trunk_source'
|
32
32
|
autoload :Specification, 'cocoapods-core/specification'
|
33
33
|
autoload :StandardError, 'cocoapods-core/standard_error'
|
34
34
|
autoload :YAMLHelper, 'cocoapods-core/yaml_helper'
|
@@ -6,8 +6,8 @@ module Pod
|
|
6
6
|
# Subclass of Pod::Source to provide support for CDN-based Specs repositories
|
7
7
|
#
|
8
8
|
class CDNSource < Source
|
9
|
-
MAX_CDN_NETWORK_THREADS = 50
|
10
|
-
MAX_NUMBER_OF_RETRIES = 5
|
9
|
+
MAX_CDN_NETWORK_THREADS = (ENV['MAX_CDN_NETWORK_THREADS'] || 50).to_i
|
10
|
+
MAX_NUMBER_OF_RETRIES = (ENV['COCOAPODS_CDN_MAX_NUMBER_OF_RETRIES'] || 5).to_i
|
11
11
|
|
12
12
|
# @param [String] repo The name of the repository
|
13
13
|
#
|
@@ -20,7 +20,7 @@ module Pod
|
|
20
20
|
|
21
21
|
@executor = Concurrent::ThreadPoolExecutor.new(
|
22
22
|
:min_threads => 5,
|
23
|
-
:max_threads =>
|
23
|
+
:max_threads => MAX_CDN_NETWORK_THREADS,
|
24
24
|
:max_queue => 0 # unbounded work queue
|
25
25
|
)
|
26
26
|
|
@@ -32,7 +32,7 @@ module Pod
|
|
32
32
|
# @return [String] The URL of the source.
|
33
33
|
#
|
34
34
|
def url
|
35
|
-
@url ||= File.read(repo.join('.url'))
|
35
|
+
@url ||= File.read(repo.join('.url')).chomp.chomp('/') + '/'
|
36
36
|
end
|
37
37
|
|
38
38
|
# @return [String] The type of the source.
|
@@ -44,7 +44,8 @@ module Pod
|
|
44
44
|
def refresh_metadata
|
45
45
|
if metadata.nil?
|
46
46
|
unless repo.exist?
|
47
|
-
|
47
|
+
debug "CDN: Repo #{name} does not exist!"
|
48
|
+
return
|
48
49
|
end
|
49
50
|
|
50
51
|
specs_dir.mkpath
|
@@ -55,8 +56,9 @@ module Pod
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def preheat_existing_files
|
58
|
-
|
59
|
-
|
59
|
+
files_to_update = files_definitely_to_update + deprecated_local_podspecs - ['deprecated_podspecs.txt']
|
60
|
+
debug "CDN: #{name} Going to update #{files_to_update.count} files"
|
61
|
+
loaders = files_to_update.map do |file|
|
60
62
|
Concurrent::Promises.future_on(@executor) do
|
61
63
|
download_file(file)
|
62
64
|
end
|
@@ -67,6 +69,17 @@ module Pod
|
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
72
|
+
def files_definitely_to_update
|
73
|
+
Pathname.glob(repo.join('**/*.{txt,yml}')).map { |f| f.relative_path_from(repo).to_s }
|
74
|
+
end
|
75
|
+
|
76
|
+
def deprecated_local_podspecs
|
77
|
+
download_file('deprecated_podspecs.txt')
|
78
|
+
local_file('deprecated_podspecs.txt', &:to_a).
|
79
|
+
map { |f| Pathname.new(f.chomp) }.
|
80
|
+
select { |f| repo.join(f).exist? }
|
81
|
+
end
|
82
|
+
|
70
83
|
# @return [Pathname] The directory where the specs are stored.
|
71
84
|
#
|
72
85
|
def specs_dir
|
@@ -143,6 +156,10 @@ module Pod
|
|
143
156
|
def specification_path(name, version)
|
144
157
|
raise ArgumentError, 'No name' unless name
|
145
158
|
raise ArgumentError, 'No version' unless version
|
159
|
+
unless versions(name).include?(Version.new(version))
|
160
|
+
raise StandardError, "Unable to find the specification #{name} " \
|
161
|
+
"(#{version}) in the #{self.name} source."
|
162
|
+
end
|
146
163
|
|
147
164
|
podspec_version_path_relative = Pathname.new(version.to_s).join("#{name}.podspec.json")
|
148
165
|
relative_podspec = relative_pod_path(name).join(podspec_version_path_relative).to_s
|
@@ -202,14 +219,21 @@ module Pod
|
|
202
219
|
# the search term. Can be a regular expression.
|
203
220
|
#
|
204
221
|
# @param [Bool] full_text_search
|
205
|
-
#
|
222
|
+
# performed using Algolia
|
206
223
|
#
|
207
224
|
# @note full text search requires to load the specification for each pod,
|
208
225
|
# and therefore not supported.
|
209
226
|
#
|
210
227
|
def search_by_name(query, full_text_search = false)
|
211
228
|
if full_text_search
|
212
|
-
|
229
|
+
require 'algoliasearch'
|
230
|
+
begin
|
231
|
+
algolia_result = algolia_search_index.search(query, :attributesToRetrieve => 'name')
|
232
|
+
names = algolia_result['hits'].map { |r| r['name'] }
|
233
|
+
names.map { |n| set(n) }.reject { |s| s.versions.compact.empty? }
|
234
|
+
rescue Algolia::AlgoliaError => e
|
235
|
+
raise Informative, "CDN: #{name} - Cannot perform full-text search because Algolia returned an error: #{e}"
|
236
|
+
end
|
213
237
|
else
|
214
238
|
super(query)
|
215
239
|
end
|
@@ -233,14 +257,18 @@ module Pod
|
|
233
257
|
[]
|
234
258
|
end
|
235
259
|
|
236
|
-
def
|
237
|
-
# Long story here. This property is actually used solely by Source::Manager to determine
|
238
|
-
# which sources are updatable. Ideally, this would require a name change but @segiddins
|
239
|
-
# has pointed out that it is public and could break plugins.
|
240
|
-
# In any case, CDN-backed repos can be updated and therefore the value ought to be true.
|
260
|
+
def updateable?
|
241
261
|
true
|
242
262
|
end
|
243
263
|
|
264
|
+
def git?
|
265
|
+
false
|
266
|
+
end
|
267
|
+
|
268
|
+
def indexable?
|
269
|
+
false
|
270
|
+
end
|
271
|
+
|
244
272
|
private
|
245
273
|
|
246
274
|
def ensure_versions_file_loaded(fragment)
|
@@ -261,6 +289,18 @@ module Pod
|
|
261
289
|
end
|
262
290
|
end
|
263
291
|
|
292
|
+
def algolia_search_index
|
293
|
+
@index ||= begin
|
294
|
+
require 'algoliasearch'
|
295
|
+
|
296
|
+
raise Informative, "Cannot perform full-text search in repo #{name} because it's missing Algolia config" if download_file('AlgoliaSearch.yml').nil?
|
297
|
+
algolia_config = YAMLHelper.load_string(local_file('AlgoliaSearch.yml', &:read))
|
298
|
+
|
299
|
+
client = Algolia::Client.new(:application_id => algolia_config['application_id'], :api_key => algolia_config['api_key'])
|
300
|
+
Algolia::Index.new(algolia_config['index'], client)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
264
304
|
def index_file_name_for_fragment(fragment)
|
265
305
|
fragment_joined = fragment.join('_')
|
266
306
|
fragment_joined = '_' + fragment_joined unless fragment.empty?
|
@@ -305,18 +345,20 @@ module Pod
|
|
305
345
|
etag = File.read(etag_path) if File.exist?(etag_path)
|
306
346
|
debug "CDN: #{name} Relative path: #{partial_url}, has ETag? #{etag}" unless etag.nil?
|
307
347
|
|
308
|
-
|
348
|
+
download_retrying_retryable_errors(partial_url, file_remote_url, etag)
|
309
349
|
end
|
310
350
|
|
311
|
-
def
|
351
|
+
def download_retrying_retryable_errors(partial_url, file_remote_url, etag, retries = MAX_NUMBER_OF_RETRIES)
|
312
352
|
path = repo + partial_url
|
313
353
|
etag_path = path.sub_ext(path.extname + '.etag')
|
314
354
|
|
315
|
-
response = download_retrying_connection_errors(partial_url, file_remote_url, etag)
|
355
|
+
response = download_retrying_connection_errors(partial_url, file_remote_url, etag, retries)
|
316
356
|
|
317
357
|
case response.status_code
|
318
358
|
when 301
|
319
|
-
|
359
|
+
redirect_location = response.headers['location'].first
|
360
|
+
debug "CDN: #{name} Redirecting from #{file_remote_url} to #{redirect_location}"
|
361
|
+
download_retrying_retryable_errors(partial_url, redirect_location, etag)
|
320
362
|
when 304
|
321
363
|
debug "CDN: #{name} Relative path not modified: #{partial_url}"
|
322
364
|
# We need to update the file modification date, as it is later used for freshness
|
@@ -333,16 +375,32 @@ module Pod
|
|
333
375
|
when 404
|
334
376
|
debug "CDN: #{name} Relative path couldn't be downloaded: #{partial_url} Response: #{response.status_code}"
|
335
377
|
nil
|
378
|
+
when 502, 503, 504
|
379
|
+
if retries <= 1
|
380
|
+
raise Informative, "CDN: #{name} URL couldn't be downloaded: #{file_remote_url} Response: #{response.status_code}"
|
381
|
+
else
|
382
|
+
sleep_for(backoff_time(retries))
|
383
|
+
download_retrying_retryable_errors(partial_url, file_remote_url, etag, retries - 1)
|
384
|
+
end
|
336
385
|
else
|
337
|
-
raise Informative, "CDN: #{name}
|
386
|
+
raise Informative, "CDN: #{name} URL couldn't be downloaded: #{file_remote_url} Response: #{response.status_code}"
|
338
387
|
end
|
339
388
|
end
|
340
389
|
|
341
|
-
def
|
390
|
+
def backoff_time(retries)
|
391
|
+
current_retry = MAX_NUMBER_OF_RETRIES - retries
|
392
|
+
4 * 2**current_retry
|
393
|
+
end
|
394
|
+
|
395
|
+
def sleep_for(seconds)
|
396
|
+
sleep(seconds)
|
397
|
+
end
|
398
|
+
|
399
|
+
def download_retrying_connection_errors(partial_url, file_remote_url, etag, retries)
|
342
400
|
etag.nil? ? REST.get(file_remote_url) : REST.get(file_remote_url, 'If-None-Match' => etag)
|
343
401
|
rescue REST::Error => e
|
344
|
-
if retries <=
|
345
|
-
raise Informative, "CDN: #{name}
|
402
|
+
if retries <= 1
|
403
|
+
raise Informative, "CDN: #{name} URL couldn't be downloaded: #{file_remote_url}, error: #{e}"
|
346
404
|
else
|
347
405
|
debug "CDN: #{name} Relative path: #{partial_url} error: #{e} - retrying"
|
348
406
|
download_retrying_connection_errors(partial_url, file_remote_url, etag, retries - 1)
|
@@ -69,20 +69,6 @@ module Pod
|
|
69
69
|
#
|
70
70
|
# Dependency.new('Artsy+UILabels', '~> 1.0', :source => 'https://github.com/Artsy/Specs.git')
|
71
71
|
#
|
72
|
-
# @overload initialize(name, is_head)
|
73
|
-
#
|
74
|
-
# @param [String] name
|
75
|
-
# the name of the Pod.
|
76
|
-
#
|
77
|
-
# @param [Symbol] is_head
|
78
|
-
# a symbol that can be `:head` or nil.
|
79
|
-
#
|
80
|
-
# @todo Remove `:head` code once everyone has migrated past CocoaPods 1.0.
|
81
|
-
#
|
82
|
-
# @example Initialization with the head option
|
83
|
-
#
|
84
|
-
# Dependency.new('RestKit', :head)
|
85
|
-
#
|
86
72
|
def initialize(name = nil, *requirements)
|
87
73
|
if requirements.last.is_a?(Hash)
|
88
74
|
additional_params = requirements.pop.select { |_, v| !v.nil? }
|
@@ -122,10 +108,6 @@ module Pod
|
|
122
108
|
# @return [Requirement] the requirement of this dependency (a set of
|
123
109
|
# one or more version restrictions).
|
124
110
|
#
|
125
|
-
# @todo The specific version is stripped from head information because
|
126
|
-
# because its string representation would not parse. It would
|
127
|
-
# be better to add something like Version#display_string.
|
128
|
-
#
|
129
111
|
def requirement
|
130
112
|
if specific_version
|
131
113
|
Requirement.new(Version.new(specific_version.version))
|
@@ -291,8 +273,8 @@ module Pod
|
|
291
273
|
# @return [Bool] Whether the dependency has any pre-release requirements
|
292
274
|
#
|
293
275
|
def prerelease?
|
294
|
-
@prerelease
|
295
|
-
|
276
|
+
return @prerelease if defined?(@prerelease)
|
277
|
+
@prerelease = requirement.requirements.any? { |_op, version| version.prerelease? }
|
296
278
|
end
|
297
279
|
|
298
280
|
# Checks whether the dependency would be satisfied by the specification
|
@@ -357,8 +339,6 @@ module Pod
|
|
357
339
|
# part by clients that need to create a dependency equal to the
|
358
340
|
# original one.
|
359
341
|
#
|
360
|
-
# @todo Remove the `HEAD` code once everyone has migrated past 1.0.
|
361
|
-
#
|
362
342
|
# @return [Dependency] the dependency described by the string.
|
363
343
|
#
|
364
344
|
def self.from_string(string)
|
@@ -367,9 +347,6 @@ module Pod
|
|
367
347
|
version = match_data[2]
|
368
348
|
version = version.gsub(/[()]/, '') if version
|
369
349
|
case version
|
370
|
-
when / HEAD( \(based on #{Pod::Version::VERSION_PATTERN}\))?/
|
371
|
-
CoreUI.warn "Ignoring obsolete `HEAD` specifier in `#{string}`"
|
372
|
-
Dependency.new(name)
|
373
350
|
when nil, /from `(.*)(`|')/
|
374
351
|
Dependency.new(name)
|
375
352
|
else
|
data/lib/cocoapods-core/http.rb
CHANGED
@@ -8,11 +8,11 @@ module Pod
|
|
8
8
|
#
|
9
9
|
# @return [string]
|
10
10
|
#
|
11
|
-
def self.get_actual_url(url)
|
11
|
+
def self.get_actual_url(url, user_agent = nil)
|
12
12
|
redirects = 0
|
13
13
|
|
14
14
|
loop do
|
15
|
-
response = perform_head_request(url)
|
15
|
+
response = perform_head_request(url, user_agent)
|
16
16
|
|
17
17
|
if [301, 302, 303, 307, 308].include? response.status_code
|
18
18
|
location = response.headers['location'].first
|
@@ -38,12 +38,12 @@ module Pod
|
|
38
38
|
#
|
39
39
|
# @return [REST::response]
|
40
40
|
#
|
41
|
-
def self.validate_url(url)
|
41
|
+
def self.validate_url(url, user_agent = nil)
|
42
42
|
return nil unless url =~ /^#{URI.regexp}$/
|
43
43
|
|
44
44
|
begin
|
45
|
-
url = get_actual_url(url)
|
46
|
-
resp = perform_head_request(url)
|
45
|
+
url = get_actual_url(url, user_agent)
|
46
|
+
resp = perform_head_request(url, user_agent)
|
47
47
|
rescue SocketError, URI::InvalidURIError, REST::Error, REST::Error::Connection
|
48
48
|
resp = nil
|
49
49
|
end
|
@@ -59,17 +59,19 @@ module Pod
|
|
59
59
|
#
|
60
60
|
# @return [REST::response]
|
61
61
|
#
|
62
|
-
def self.perform_head_request(url)
|
62
|
+
def self.perform_head_request(url, user_agent)
|
63
63
|
require 'rest'
|
64
64
|
|
65
|
-
|
65
|
+
user_agent ||= USER_AGENT
|
66
|
+
|
67
|
+
resp = ::REST.head(url, 'User-Agent' => user_agent)
|
66
68
|
|
67
69
|
if resp.status_code >= 400
|
68
|
-
resp = ::REST.get(url, 'User-Agent' =>
|
70
|
+
resp = ::REST.get(url, 'User-Agent' => user_agent,
|
69
71
|
'Range' => 'bytes=0-0')
|
70
72
|
|
71
73
|
if resp.status_code >= 400
|
72
|
-
resp = ::REST.get(url, 'User-Agent' =>
|
74
|
+
resp = ::REST.get(url, 'User-Agent' => user_agent)
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
@@ -489,7 +489,7 @@ module Pod
|
|
489
489
|
next unless source
|
490
490
|
next if specs.empty?
|
491
491
|
key = source.url || source.name
|
492
|
-
key =
|
492
|
+
key = Pod::TrunkSource::TRUNK_REPO_NAME if source.name == Pod::TrunkSource::TRUNK_REPO_NAME
|
493
493
|
value = specs.map { |s| s.root.name }.uniq
|
494
494
|
[key, YAMLHelper.sorted_array(value)]
|
495
495
|
end.compact]
|
@@ -687,6 +687,39 @@ module Pod
|
|
687
687
|
current_target_definition.use_frameworks!(flag)
|
688
688
|
end
|
689
689
|
|
690
|
+
# Specifies the Swift version requirements this target definition supports.
|
691
|
+
#
|
692
|
+
# **Note** These requirements are inherited from the parent, if specified and if none
|
693
|
+
# are specified at the root level then all versions are considered to be supported.
|
694
|
+
#
|
695
|
+
# @param [String, Version, Array<String>, Array<Version>] requirements
|
696
|
+
# The set of requirements this target supports.
|
697
|
+
#
|
698
|
+
# @example
|
699
|
+
#
|
700
|
+
# target 'MyApp' do
|
701
|
+
# supports_swift_versions '>= 3.0', '< 4.0'
|
702
|
+
# pod 'AFNetworking', '~> 1.0'
|
703
|
+
# end
|
704
|
+
#
|
705
|
+
# @example
|
706
|
+
#
|
707
|
+
# supports_swift_versions '>= 3.0', '< 4.0'
|
708
|
+
#
|
709
|
+
# target 'MyApp' do
|
710
|
+
# pod 'AFNetworking', '~> 1.0'
|
711
|
+
# end
|
712
|
+
#
|
713
|
+
# target 'ZipApp' do
|
714
|
+
# pod 'SSZipArchive'
|
715
|
+
# end
|
716
|
+
#
|
717
|
+
# @return [void]
|
718
|
+
#
|
719
|
+
def supports_swift_versions(*requirements)
|
720
|
+
current_target_definition.store_swift_version_requirements(*requirements)
|
721
|
+
end
|
722
|
+
|
690
723
|
#-----------------------------------------------------------------------#
|
691
724
|
|
692
725
|
# @!group Workspace
|
@@ -869,39 +902,6 @@ module Pod
|
|
869
902
|
raise Informative, 'Specifying multiple `post_install` hooks is unsupported.' if @post_install_callback
|
870
903
|
@post_install_callback = block
|
871
904
|
end
|
872
|
-
|
873
|
-
# Specifies the Swift version requirements this target definition supports.
|
874
|
-
#
|
875
|
-
# **Note** These requirements are inherited from the parent, if specified and if none
|
876
|
-
# are specified at the root level then all versions are considered to be supported.
|
877
|
-
#
|
878
|
-
# @param [String, Version, Array<String>, Array<Version>] requirements
|
879
|
-
# The set of requirements this target supports.
|
880
|
-
#
|
881
|
-
# @example
|
882
|
-
#
|
883
|
-
# target 'MyApp' do
|
884
|
-
# supports_swift_versions '>= 3.0', '< 4.0'
|
885
|
-
# pod 'AFNetworking', '~> 1.0'
|
886
|
-
# end
|
887
|
-
#
|
888
|
-
# @example
|
889
|
-
#
|
890
|
-
# supports_swift_versions '>= 3.0', '< 4.0'
|
891
|
-
#
|
892
|
-
# target 'MyApp' do
|
893
|
-
# pod 'AFNetworking', '~> 1.0'
|
894
|
-
# end
|
895
|
-
#
|
896
|
-
# target 'ZipApp' do
|
897
|
-
# pod 'SSZipArchive'
|
898
|
-
# end
|
899
|
-
#
|
900
|
-
# @return [void]
|
901
|
-
#
|
902
|
-
def supports_swift_versions(*requirements)
|
903
|
-
current_target_definition.store_swift_version_requirements(*requirements)
|
904
|
-
end
|
905
905
|
end
|
906
906
|
end
|
907
907
|
end
|
@@ -296,6 +296,20 @@ module Pod
|
|
296
296
|
|
297
297
|
#--------------------------------------#
|
298
298
|
|
299
|
+
# @return [String] The project name to use for the given pod name or `nil` if none specified.
|
300
|
+
#
|
301
|
+
# @note When querying for a subspec then use the root pod spec name instead as this is what's stored.
|
302
|
+
#
|
303
|
+
def project_name_for_pod(pod_name)
|
304
|
+
if root?
|
305
|
+
raw_project_names_hash[pod_name]
|
306
|
+
else
|
307
|
+
raw_project_names_hash[pod_name] || parent.project_name_for_pod(pod_name)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
#--------------------------------------#
|
312
|
+
#
|
299
313
|
# @return [Bool] whether the target definition should inhibit warnings
|
300
314
|
# for a single pod. If inhibit_all_warnings is true, it will
|
301
315
|
# return true for any asked pod.
|
@@ -666,6 +680,7 @@ module Pod
|
|
666
680
|
parse_inhibit_warnings(name, requirements)
|
667
681
|
parse_modular_headers(name, requirements)
|
668
682
|
parse_configuration_whitelist(name, requirements)
|
683
|
+
parse_project_name(name, requirements)
|
669
684
|
|
670
685
|
if requirements && !requirements.empty?
|
671
686
|
pod = { name => requirements }
|
@@ -769,6 +784,7 @@ module Pod
|
|
769
784
|
use_modular_headers
|
770
785
|
user_project_path
|
771
786
|
build_configurations
|
787
|
+
project_names
|
772
788
|
dependencies
|
773
789
|
script_phases
|
774
790
|
children
|
@@ -1041,6 +1057,33 @@ module Pod
|
|
1041
1057
|
requirements.pop if options.empty?
|
1042
1058
|
end
|
1043
1059
|
|
1060
|
+
# Removes :project_name from the requirements list, and adds
|
1061
|
+
# the pods name into internal hash.
|
1062
|
+
#
|
1063
|
+
# @param [String] name The name of the pod
|
1064
|
+
#
|
1065
|
+
# @param [Array] requirements
|
1066
|
+
# If :project_name is the only key in the hash, the hash
|
1067
|
+
# should be destroyed because it confuses Gem::Dependency.
|
1068
|
+
#
|
1069
|
+
# @return [void]
|
1070
|
+
#
|
1071
|
+
def parse_project_name(name, requirements)
|
1072
|
+
options = requirements.last
|
1073
|
+
return requirements unless options.is_a?(Hash)
|
1074
|
+
|
1075
|
+
project_name = options.delete(:project_name)
|
1076
|
+
pod_name = Specification.root_name(name)
|
1077
|
+
raw_project_names_hash[pod_name] = project_name if project_name
|
1078
|
+
|
1079
|
+
requirements.pop if options.empty?
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
def raw_project_names_hash
|
1083
|
+
get_hash_value('project_names', {})
|
1084
|
+
end
|
1085
|
+
private :raw_project_names_hash
|
1086
|
+
|
1044
1087
|
# Removes :configurations or :configuration from the requirements list,
|
1045
1088
|
# and adds the pod's name into the internal hash for which pods should be
|
1046
1089
|
# linked in which configuration only.
|
@@ -16,6 +16,9 @@ module Pod
|
|
16
16
|
# "#{SPEC_NAME}/#{VERSION}/#{SPEC_NAME}.podspec"
|
17
17
|
#
|
18
18
|
class Source
|
19
|
+
# The default branch in which the specs are stored
|
20
|
+
DEFAULT_SPECS_BRANCH = 'master'.freeze
|
21
|
+
|
19
22
|
# @return [Pod::Source::Metadata] The metadata for this source.
|
20
23
|
#
|
21
24
|
attr_reader :metadata
|
@@ -55,7 +58,7 @@ module Pod
|
|
55
58
|
# @return [String] The type of the source.
|
56
59
|
#
|
57
60
|
def type
|
58
|
-
'file system'
|
61
|
+
git? ? 'git' : 'file system'
|
59
62
|
end
|
60
63
|
|
61
64
|
alias_method :to_s, :name
|
@@ -353,8 +356,16 @@ module Pod
|
|
353
356
|
diff_until_commit_hash(prev_commit_hash)
|
354
357
|
end
|
355
358
|
|
359
|
+
def updateable?
|
360
|
+
git?
|
361
|
+
end
|
362
|
+
|
356
363
|
def git?
|
357
|
-
!repo_git(%w(rev-parse HEAD)).empty?
|
364
|
+
repo.join('.git').exist? && !repo_git(%w(rev-parse HEAD)).empty?
|
365
|
+
end
|
366
|
+
|
367
|
+
def indexable?
|
368
|
+
true
|
358
369
|
end
|
359
370
|
|
360
371
|
def verify_compatibility!
|
@@ -435,7 +446,7 @@ module Pod
|
|
435
446
|
|
436
447
|
def git_tracking_branch
|
437
448
|
path = repo.join('.git', 'cocoapods_branch')
|
438
|
-
path.file? ? path.read.strip :
|
449
|
+
path.file? ? path.read.strip : DEFAULT_SPECS_BRANCH
|
439
450
|
end
|
440
451
|
|
441
452
|
def diff_until_commit_hash(commit_hash)
|
@@ -58,10 +58,17 @@ module Pod
|
|
58
58
|
aggregate.sources
|
59
59
|
end
|
60
60
|
|
61
|
+
# @return [Array<Source>] The list of all the non-indexable sources known to this
|
62
|
+
# installation of CocoaPods.
|
63
|
+
#
|
64
|
+
def all_non_indexable
|
65
|
+
aggregate.sources.reject(&:indexable?)
|
66
|
+
end
|
67
|
+
|
61
68
|
# @return [Array<Source>] The CocoaPods Master Repo source.
|
62
69
|
#
|
63
70
|
def master
|
64
|
-
sources([Pod::
|
71
|
+
sources([Pod::TrunkSource::TRUNK_REPO_NAME]).select { |s| s.repo.directory? }
|
65
72
|
end
|
66
73
|
|
67
74
|
# @!group Master repo
|
@@ -69,7 +76,7 @@ module Pod
|
|
69
76
|
# @return [Pathname] The path of the master repo.
|
70
77
|
#
|
71
78
|
def master_repo_dir
|
72
|
-
source_dir(Pod::
|
79
|
+
source_dir(Pod::TrunkSource::TRUNK_REPO_NAME)
|
73
80
|
end
|
74
81
|
|
75
82
|
# @return [Bool] Checks if the master repo is usable.
|
@@ -122,9 +129,15 @@ module Pod
|
|
122
129
|
end
|
123
130
|
found_set_names = query_word_results_hash.values.reduce(:&)
|
124
131
|
found_set_names ||= []
|
132
|
+
|
133
|
+
sets_from_non_indexable = all_non_indexable.map { |s| s.search_by_name(query, true) }.flatten
|
134
|
+
|
135
|
+
found_set_names += sets_from_non_indexable.map(&:name).flatten.uniq
|
136
|
+
|
125
137
|
sets = found_set_names.map do |name|
|
126
138
|
aggregate.representative_set(name)
|
127
139
|
end
|
140
|
+
|
128
141
|
# Remove nil values because representative_set return nil if no pod is found in any of the sources.
|
129
142
|
sets.compact!
|
130
143
|
else
|
@@ -182,7 +195,7 @@ module Pod
|
|
182
195
|
#
|
183
196
|
def updated_search_index
|
184
197
|
index = stored_search_index || {}
|
185
|
-
|
198
|
+
indexable_sources.each do |source|
|
186
199
|
source_name = source.name
|
187
200
|
unless index[source_name]
|
188
201
|
CoreUI.print "Creating search index for spec repo '#{source_name}'.."
|
@@ -203,6 +216,7 @@ module Pod
|
|
203
216
|
search_index = stored_search_index
|
204
217
|
return unless search_index
|
205
218
|
changed_spec_paths.each_pair do |source, spec_paths|
|
219
|
+
next unless source.indexable?
|
206
220
|
index_for_source = search_index[source.name]
|
207
221
|
next unless index_for_source && !spec_paths.empty?
|
208
222
|
updated_pods = source.pods_for_specification_paths(spec_paths)
|
@@ -290,10 +304,10 @@ module Pod
|
|
290
304
|
def source_from_path(path)
|
291
305
|
@sources_by_path ||= Hash.new do |hash, key|
|
292
306
|
hash[key] = case
|
307
|
+
when key.basename.to_s == Pod::TrunkSource::TRUNK_REPO_NAME
|
308
|
+
TrunkSource.new(key)
|
293
309
|
when (key + '.url').exist?
|
294
310
|
CDNSource.new(key)
|
295
|
-
when key.basename.to_s == Pod::MasterSource::MASTER_REPO_NAME
|
296
|
-
MasterSource.new(key)
|
297
311
|
else
|
298
312
|
Source.new(key)
|
299
313
|
end
|
@@ -312,27 +326,33 @@ module Pod
|
|
312
326
|
@aggregates_by_repos[repos] ||= Source::Aggregate.new(sources)
|
313
327
|
end
|
314
328
|
|
315
|
-
# @return [Source] The
|
329
|
+
# @return [Source] The updateable source with the given name. If no updateable source
|
316
330
|
# with given name is found it raises.
|
317
331
|
#
|
318
332
|
# @param [String] name
|
319
333
|
# The name of the source.
|
320
334
|
#
|
321
|
-
def
|
335
|
+
def updateable_source_named(name)
|
322
336
|
specified_source = sources([name]).first
|
323
337
|
unless specified_source
|
324
338
|
raise Informative, "Unable to find the `#{name}` repo."
|
325
339
|
end
|
326
|
-
unless specified_source.
|
327
|
-
raise Informative, "The `#{name}` repo is not a
|
340
|
+
unless specified_source.updateable?
|
341
|
+
raise Informative, "The `#{name}` repo is not a updateable repo."
|
328
342
|
end
|
329
343
|
specified_source
|
330
344
|
end
|
331
345
|
|
332
|
-
# @return [Source] The list of the
|
346
|
+
# @return [Source] The list of the updateable sources.
|
333
347
|
#
|
334
|
-
def
|
335
|
-
all.select(&:
|
348
|
+
def updateable_sources
|
349
|
+
all.select(&:updateable?)
|
350
|
+
end
|
351
|
+
|
352
|
+
# @return [Source] The list of the indexable sources.
|
353
|
+
#
|
354
|
+
def indexable_sources
|
355
|
+
all.select(&:indexable?)
|
336
356
|
end
|
337
357
|
|
338
358
|
# @return [Pathname] The path of the source with the given name.
|
@@ -350,13 +370,17 @@ module Pod
|
|
350
370
|
# The URL of the source.
|
351
371
|
#
|
352
372
|
def source_with_url(url)
|
353
|
-
url = url
|
373
|
+
url = canonic_url(url)
|
354
374
|
url = 'https://github.com/cocoapods/specs' if url =~ %r{github.com[:/]+cocoapods/specs}
|
355
375
|
all.find do |source|
|
356
|
-
source.url && source.url
|
376
|
+
source.url && canonic_url(source.url) == url
|
357
377
|
end
|
358
378
|
end
|
359
379
|
|
380
|
+
def canonic_url(url)
|
381
|
+
url.downcase.gsub(/\.git$/, '').gsub(%r{\/$}, '')
|
382
|
+
end
|
383
|
+
|
360
384
|
# Returns a suitable repository name for `url`.
|
361
385
|
#
|
362
386
|
# @example A GitHub.com URL
|
@@ -394,8 +418,8 @@ module Pod
|
|
394
418
|
end
|
395
419
|
|
396
420
|
case url.to_s.downcase
|
397
|
-
when %r{
|
398
|
-
base = Pod::
|
421
|
+
when %r{https://#{Regexp.quote(trunk_repo_hostname)}}i
|
422
|
+
base = Pod::TrunkSource::TRUNK_REPO_NAME
|
399
423
|
when %r{github.com[:/]+(.+)/(.+)}
|
400
424
|
base = Regexp.last_match[1]
|
401
425
|
when %r{^\S+@(\S+)[:/]+(.+)$}
|
@@ -416,6 +440,12 @@ module Pod
|
|
416
440
|
end
|
417
441
|
name
|
418
442
|
end
|
443
|
+
|
444
|
+
# Returns hostname for for `trunk` URL.
|
445
|
+
#
|
446
|
+
def trunk_repo_hostname
|
447
|
+
URI.parse(TrunkSource::TRUNK_REPO_URL).host.downcase.freeze
|
448
|
+
end
|
419
449
|
end
|
420
450
|
end
|
421
451
|
end
|
@@ -125,8 +125,9 @@ module Pod
|
|
125
125
|
# clients.
|
126
126
|
#
|
127
127
|
def to_s
|
128
|
-
|
129
|
-
|
128
|
+
specified_version = raw_version || ''
|
129
|
+
if name && !specified_version.empty?
|
130
|
+
"#{name} (#{specified_version})"
|
130
131
|
elsif name
|
131
132
|
name
|
132
133
|
else
|
@@ -203,6 +204,13 @@ module Pod
|
|
203
204
|
gsub(/[^a-zA-Z0-9_]/, '_').gsub(/_+/, '_')
|
204
205
|
end
|
205
206
|
|
207
|
+
# @return [Object, Nil]
|
208
|
+
# the raw value specified for the version attribute, or nil
|
209
|
+
#
|
210
|
+
def raw_version
|
211
|
+
root.attributes_hash['version']
|
212
|
+
end
|
213
|
+
|
206
214
|
#-------------------------------------------------------------------------#
|
207
215
|
|
208
216
|
public
|
@@ -435,6 +443,12 @@ module Pod
|
|
435
443
|
Specification.convert_keys_to_symbol(value, :recursive => false)
|
436
444
|
end
|
437
445
|
|
446
|
+
# @return [Hash] The Info.plist value.
|
447
|
+
#
|
448
|
+
def info_plist
|
449
|
+
attributes_hash['info_plist'] || {}
|
450
|
+
end
|
451
|
+
|
438
452
|
#-------------------------------------------------------------------------#
|
439
453
|
|
440
454
|
public
|
@@ -689,18 +703,18 @@ module Pod
|
|
689
703
|
def self.from_string(spec_contents, path, subspec_name = nil)
|
690
704
|
path = Pathname.new(path).expand_path
|
691
705
|
spec = nil
|
692
|
-
|
693
|
-
|
694
|
-
|
706
|
+
case path.extname
|
707
|
+
when '.podspec'
|
708
|
+
Dir.chdir(path.parent.directory? ? path.parent : Dir.pwd) do
|
695
709
|
spec = ::Pod._eval_podspec(spec_contents, path)
|
696
710
|
unless spec.is_a?(Specification)
|
697
711
|
raise Informative, "Invalid podspec file at path `#{path}`."
|
698
712
|
end
|
699
|
-
when '.json'
|
700
|
-
spec = Specification.from_json(spec_contents)
|
701
|
-
else
|
702
|
-
raise Informative, "Unsupported specification format `#{path.extname}` for spec at `#{path}`."
|
703
713
|
end
|
714
|
+
when '.json'
|
715
|
+
spec = Specification.from_json(spec_contents)
|
716
|
+
else
|
717
|
+
raise Informative, "Unsupported specification format `#{path.extname}` for spec at `#{path}`."
|
704
718
|
end
|
705
719
|
|
706
720
|
spec.defined_in_file = path
|
@@ -110,6 +110,10 @@ module Pod
|
|
110
110
|
merge_values(attr, value_for_attribute(:xcconfig), value_for_attribute(:user_target_xcconfig))
|
111
111
|
end
|
112
112
|
|
113
|
+
# @return [Hash{String => String}] the Info.plist values for the current specification
|
114
|
+
#
|
115
|
+
spec_attr_accessor :info_plist
|
116
|
+
|
113
117
|
# @return [String] The contents of the prefix header.
|
114
118
|
#
|
115
119
|
spec_attr_accessor :prefix_header_contents
|
@@ -144,6 +148,10 @@ module Pod
|
|
144
148
|
spec_attr_accessor :requires_app_host
|
145
149
|
alias_method :requires_app_host?, :requires_app_host
|
146
150
|
|
151
|
+
# @return [String] Name of the app host this spec requires
|
152
|
+
#
|
153
|
+
spec_attr_accessor :app_host_name
|
154
|
+
|
147
155
|
# @return [Symbol] the test type supported by this specification.
|
148
156
|
#
|
149
157
|
spec_attr_accessor :test_type
|
@@ -309,12 +317,7 @@ module Pod
|
|
309
317
|
r.compact
|
310
318
|
elsif attr.container == Hash
|
311
319
|
existing_value.merge(new_value) do |_, old, new|
|
312
|
-
|
313
|
-
r = [*old] + [*new]
|
314
|
-
r.compact
|
315
|
-
else
|
316
|
-
old + ' ' + new
|
317
|
-
end
|
320
|
+
merge_hash_value(attr, old, new)
|
318
321
|
end
|
319
322
|
else
|
320
323
|
new_value
|
@@ -349,6 +352,35 @@ module Pod
|
|
349
352
|
end
|
350
353
|
end
|
351
354
|
|
355
|
+
private
|
356
|
+
|
357
|
+
# Merges two values in a hash together based on the needs of the attribute
|
358
|
+
#
|
359
|
+
# @param [Specification::DSL::Attribute] attr
|
360
|
+
# the attribute for which that value is needed.
|
361
|
+
#
|
362
|
+
# @param [Object] old the value from the original hash
|
363
|
+
#
|
364
|
+
# @param [Object] new the value from the new hash
|
365
|
+
#
|
366
|
+
# @return [Object] the merged value
|
367
|
+
#
|
368
|
+
def merge_hash_value(attr, old, new)
|
369
|
+
case attr.name
|
370
|
+
when :info_plist
|
371
|
+
new
|
372
|
+
when ->(name) { spec.non_library_specification? && [:pod_target_xcconfig, :user_target_xcconfig, :xcconfig].include?(name) }
|
373
|
+
new
|
374
|
+
else
|
375
|
+
if new.is_a?(Array) || old.is_a?(Array)
|
376
|
+
r = Array(old) + Array(new)
|
377
|
+
r.compact
|
378
|
+
else
|
379
|
+
old + ' ' + new
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
352
384
|
# @!group Preparing Values
|
353
385
|
#-----------------------------------------------------------------------#
|
354
386
|
|
@@ -305,7 +305,7 @@ module Pod
|
|
305
305
|
:git => [:tag, :branch, :commit, :submodules].freeze,
|
306
306
|
:svn => [:folder, :tag, :revision].freeze,
|
307
307
|
:hg => [:revision].freeze,
|
308
|
-
:http => [:flatten, :type, :sha256, :sha1].freeze,
|
308
|
+
:http => [:flatten, :type, :sha256, :sha1, :headers].freeze,
|
309
309
|
}.freeze
|
310
310
|
|
311
311
|
# @!method source=(source)
|
@@ -704,6 +704,39 @@ module Pod
|
|
704
704
|
|
705
705
|
#------------------#
|
706
706
|
|
707
|
+
# @!method info_plist=(info_plist)
|
708
|
+
#
|
709
|
+
# Key-Value pairs to add to the generated `Info.plist`.
|
710
|
+
#
|
711
|
+
# The values will be merged with the default values that
|
712
|
+
# CocoaPods generates, overriding any duplicates.
|
713
|
+
#
|
714
|
+
# For library specs, the values will be merged into the generated Info.plist
|
715
|
+
# for libraries that are integrated using frameworks. It will have no effect
|
716
|
+
# for static libraries.
|
717
|
+
#
|
718
|
+
# Subspecs (other than app and test specs) are not supported.
|
719
|
+
#
|
720
|
+
# For app specs, the values will be merged into the application host's `Info.plist`.
|
721
|
+
#
|
722
|
+
# For test specs, the values will be merged into the test bundle's `Info.plist`.
|
723
|
+
#
|
724
|
+
# @example
|
725
|
+
#
|
726
|
+
# spec.info_plist = {
|
727
|
+
# 'CFBundleIdentifier' => 'com.myorg.MyLib',
|
728
|
+
# 'MY_VAR' => 'SOME_VALUE'
|
729
|
+
# }
|
730
|
+
#
|
731
|
+
# @param [Hash] info_plist
|
732
|
+
# The Info.plist values for the Pod.
|
733
|
+
#
|
734
|
+
attribute :info_plist,
|
735
|
+
:container => Hash,
|
736
|
+
:inherited => false
|
737
|
+
|
738
|
+
#------------------#
|
739
|
+
|
707
740
|
# @!method requires_arc=(flag)
|
708
741
|
#
|
709
742
|
# `requires_arc` allows you to specify which source_files use ARC.
|
@@ -1155,7 +1188,8 @@ module Pod
|
|
1155
1188
|
#
|
1156
1189
|
# ---
|
1157
1190
|
#
|
1158
|
-
# These are
|
1191
|
+
# These patterns are matched against the source files to include headers
|
1192
|
+
# that will be exposed to the user’s project and
|
1159
1193
|
# from which documentation will be generated. When the library is built,
|
1160
1194
|
# these headers will appear in the build directory. If no public headers
|
1161
1195
|
# are specified then **all** the headers in source_files are considered
|
@@ -1470,7 +1504,7 @@ module Pod
|
|
1470
1504
|
|
1471
1505
|
# The list of the test types currently supported.
|
1472
1506
|
#
|
1473
|
-
SUPPORTED_TEST_TYPES = [:unit].freeze
|
1507
|
+
SUPPORTED_TEST_TYPES = [:unit, :ui].freeze
|
1474
1508
|
|
1475
1509
|
# The test type this specification supports. This only applies to test specifications.
|
1476
1510
|
#
|
@@ -1508,6 +1542,39 @@ module Pod
|
|
1508
1542
|
:default_value => false,
|
1509
1543
|
:spec_types => [:test]
|
1510
1544
|
|
1545
|
+
# @!method app_host_name=(name)
|
1546
|
+
#
|
1547
|
+
# The app specification to use as an app host, if necessary.
|
1548
|
+
#
|
1549
|
+
# @note
|
1550
|
+
#
|
1551
|
+
# You must depend on that app spec using `test_spec.dependency 'PodName'`.
|
1552
|
+
#
|
1553
|
+
# @example
|
1554
|
+
#
|
1555
|
+
# Pod::Spec.new do |spec|
|
1556
|
+
# spec.name = 'NSAttributedString+CCLFormat'
|
1557
|
+
#
|
1558
|
+
# spec.test_spec do |test_spec|
|
1559
|
+
# test_spec.source_files = 'NSAttributedString+CCLFormatTests.m'
|
1560
|
+
# test_spec.requires_app_host = true
|
1561
|
+
# test_spec.app_host_name = 'NSAttributedString+CCLFormat/App'
|
1562
|
+
# test_spec.dependency 'NSAttributedString+CCLFormat/App'
|
1563
|
+
# end
|
1564
|
+
#
|
1565
|
+
# spec.app_spec 'App' do |app_spec|
|
1566
|
+
# app_spec.source_files = 'NSAttributedString+CCLFormat.m'
|
1567
|
+
# app_spec.dependency 'AFNetworking'
|
1568
|
+
# end
|
1569
|
+
# end
|
1570
|
+
#
|
1571
|
+
# @param [String] name
|
1572
|
+
# The app specification to use as an app host, if necessary.
|
1573
|
+
#
|
1574
|
+
attribute :app_host_name,
|
1575
|
+
:types => [String],
|
1576
|
+
:spec_types => [:test]
|
1577
|
+
|
1511
1578
|
SCHEME_KEYS = [:launch_arguments, :environment_variables].freeze
|
1512
1579
|
|
1513
1580
|
# @!method scheme=(flag)
|
@@ -121,15 +121,19 @@ module Pod
|
|
121
121
|
def check_required_attributes
|
122
122
|
attributes = DSL.attributes.values.select(&:required?)
|
123
123
|
attributes.each do |attr|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
124
|
+
begin
|
125
|
+
value = spec.send(attr.name)
|
126
|
+
unless value && (!value.respond_to?(:empty?) || !value.empty?)
|
127
|
+
if attr.name == :license
|
128
|
+
results.add_warning('attributes', 'Missing required attribute ' \
|
129
|
+
"`#{attr.name}`.")
|
130
|
+
else
|
131
|
+
results.add_error('attributes', 'Missing required attribute ' \
|
132
|
+
"`#{attr.name}`.")
|
133
|
+
end
|
132
134
|
end
|
135
|
+
rescue => exception
|
136
|
+
results.add_error('attributes', "Unable to parse attribute `#{attr.name}` due to error: #{exception}")
|
133
137
|
end
|
134
138
|
end
|
135
139
|
end
|
@@ -187,9 +191,13 @@ module Pod
|
|
187
191
|
attributes.each do |attr|
|
188
192
|
validation_hook = "_validate_#{attr.name}"
|
189
193
|
next unless respond_to?(validation_hook, true)
|
190
|
-
|
191
|
-
|
192
|
-
|
194
|
+
begin
|
195
|
+
value = target.send(attr.name)
|
196
|
+
next unless value
|
197
|
+
send(validation_hook, value)
|
198
|
+
rescue => e
|
199
|
+
results.add_error(attr.name, "Unable to validate due to exception: #{e}")
|
200
|
+
end
|
193
201
|
end
|
194
202
|
end
|
195
203
|
|
@@ -350,6 +358,7 @@ module Pod
|
|
350
358
|
# Performs validations related to the `source` attribute.
|
351
359
|
#
|
352
360
|
def _validate_source(s)
|
361
|
+
return unless s.is_a?(Hash)
|
353
362
|
if git = s[:git]
|
354
363
|
tag, commit = s.values_at(:tag, :commit)
|
355
364
|
version = spec.version.to_s
|
@@ -394,6 +403,18 @@ module Pod
|
|
394
403
|
end
|
395
404
|
end
|
396
405
|
|
406
|
+
def _validate_app_host_name(n)
|
407
|
+
unless consumer.requires_app_host?
|
408
|
+
results.add_error('app_host_name', '`requires_app_host` must be set to ' \
|
409
|
+
'`true` when `app_host_name` is specified.')
|
410
|
+
end
|
411
|
+
|
412
|
+
unless consumer.dependencies.map(&:name).include?(n)
|
413
|
+
results.add_error('app_host_name', "The app host name (#{n}) specified by `#{consumer.spec.name}` could " \
|
414
|
+
'not be found. You must explicitly declare a dependency on that app spec.')
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
397
418
|
# Performs validations related to the `script_phases` attribute.
|
398
419
|
#
|
399
420
|
def _validate_script_phases(s)
|
@@ -482,6 +503,15 @@ module Pod
|
|
482
503
|
end
|
483
504
|
end
|
484
505
|
|
506
|
+
# @param [Hash,Object] value
|
507
|
+
#
|
508
|
+
def _validate_info_plist(value)
|
509
|
+
return if value.empty?
|
510
|
+
if consumer.spec.subspec? && consumer.spec.library_specification?
|
511
|
+
results.add_error('info_plist', 'Info.plist configuration is not currently supported for subspecs.')
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
485
515
|
#-----------------------------------------------------------------------#
|
486
516
|
|
487
517
|
# @!group All specs validation helpers
|
@@ -181,6 +181,10 @@ module Pod
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def validate_attribute_hash_keys(attribute, value)
|
184
|
+
unless value.is_a?(Hash)
|
185
|
+
results.add_error(attribute.name, "Unsupported type `#{value.class}`, expected `Hash`")
|
186
|
+
return
|
187
|
+
end
|
184
188
|
major_keys = value.keys & attribute.keys.keys
|
185
189
|
if major_keys.count.zero?
|
186
190
|
results.add_warning('keys', "Missing primary key for `#{attribute.name}` " \
|
@@ -27,11 +27,6 @@ module Pod
|
|
27
27
|
|
28
28
|
# @return [Version] The version of the Pod.
|
29
29
|
#
|
30
|
-
# @todo The version is memoized because the Resolvers sets the head
|
31
|
-
# state on it. This information should be stored in the
|
32
|
-
# specification instance and the lockfile should have a more
|
33
|
-
# robust handling of head versions (like a dedicated section).
|
34
|
-
#
|
35
30
|
def version
|
36
31
|
if root?
|
37
32
|
@version ||= Version.new(attributes_hash['version'])
|
@@ -131,7 +126,12 @@ module Pod
|
|
131
126
|
# should be retrieved.
|
132
127
|
#
|
133
128
|
def source
|
134
|
-
|
129
|
+
value = attributes_hash['source']
|
130
|
+
if value && value.is_a?(Hash)
|
131
|
+
Specification.convert_keys_to_symbol(value)
|
132
|
+
else
|
133
|
+
value
|
134
|
+
end
|
135
135
|
end
|
136
136
|
|
137
137
|
# @return [String] A short description of the Pod.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Pod
|
2
|
+
class TrunkSource < CDNSource
|
3
|
+
# On-disk master repo name
|
4
|
+
TRUNK_REPO_NAME = 'trunk'.freeze
|
5
|
+
|
6
|
+
# Remote CDN repo URL
|
7
|
+
TRUNK_REPO_URL = 'https://cdn.cocoapods.org/'.freeze
|
8
|
+
|
9
|
+
def url
|
10
|
+
@url ||= TRUNK_REPO_URL
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -68,7 +68,8 @@ module Pod
|
|
68
68
|
# For more info, see: http://semver.org
|
69
69
|
#
|
70
70
|
def prerelease?
|
71
|
-
@prerelease
|
71
|
+
return @prerelease if defined?(@prerelease)
|
72
|
+
@prerelease = @version =~ /[a-zA-Z\-]/
|
72
73
|
end
|
73
74
|
|
74
75
|
# @return [Bool] Whether a string representation is correct.
|
@@ -205,7 +206,7 @@ module Pod
|
|
205
206
|
compare = proc do |segments, other_segments, is_pre_release|
|
206
207
|
limit = [segments.size, other_segments.size].max
|
207
208
|
|
208
|
-
(
|
209
|
+
0.upto(limit) do |i|
|
209
210
|
lhs = segments[i]
|
210
211
|
rhs = other_segments[i]
|
211
212
|
|
@@ -224,8 +225,6 @@ module Pod
|
|
224
225
|
if comparison = lhs <=> rhs
|
225
226
|
return comparison
|
226
227
|
end
|
227
|
-
return 1 if lhs.is_a?(String) && rhs.is_a?(Numeric)
|
228
|
-
return -1 if lhs.is_a?(Numeric) && rhs.is_a?(String)
|
229
228
|
end
|
230
229
|
end
|
231
230
|
|
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: 1.
|
4
|
+
version: 1.8.0.beta.1
|
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: 2019-
|
12
|
+
date: 2019-08-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -59,6 +59,20 @@ dependencies:
|
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 2.0.4
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: algoliasearch
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
type: :runtime
|
70
|
+
prerelease: false
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
62
76
|
- !ruby/object:Gem::Dependency
|
63
77
|
name: bacon
|
64
78
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,7 +108,6 @@ files:
|
|
94
108
|
- lib/cocoapods-core/github.rb
|
95
109
|
- lib/cocoapods-core/http.rb
|
96
110
|
- lib/cocoapods-core/lockfile.rb
|
97
|
-
- lib/cocoapods-core/master_source.rb
|
98
111
|
- lib/cocoapods-core/metrics.rb
|
99
112
|
- lib/cocoapods-core/platform.rb
|
100
113
|
- lib/cocoapods-core/podfile.rb
|
@@ -122,6 +135,7 @@ files:
|
|
122
135
|
- lib/cocoapods-core/specification/set.rb
|
123
136
|
- lib/cocoapods-core/specification/set/presenter.rb
|
124
137
|
- lib/cocoapods-core/standard_error.rb
|
138
|
+
- lib/cocoapods-core/trunk_source.rb
|
125
139
|
- lib/cocoapods-core/vendor.rb
|
126
140
|
- lib/cocoapods-core/vendor/requirement.rb
|
127
141
|
- lib/cocoapods-core/vendor/version.rb
|
@@ -1,8 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
class MasterSource < Source
|
3
|
-
# For now, the MasterSource behaves exactly the same as any other Source.
|
4
|
-
# In the future we may apply separate logic to the MasterSource that doesn't
|
5
|
-
# depend on the file system.
|
6
|
-
MASTER_REPO_NAME = 'master'.freeze
|
7
|
-
end
|
8
|
-
end
|