cocoapods-core 0.30.0 → 1.15.2
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 +5 -5
- data/README.md +7 -10
- data/lib/cocoapods-core/build_type.rb +121 -0
- data/lib/cocoapods-core/cdn_source.rb +501 -0
- data/lib/cocoapods-core/core_ui.rb +4 -3
- data/lib/cocoapods-core/dependency.rb +100 -73
- data/lib/cocoapods-core/gem_version.rb +1 -2
- data/lib/cocoapods-core/github.rb +32 -5
- data/lib/cocoapods-core/http.rb +86 -0
- data/lib/cocoapods-core/lockfile.rb +161 -56
- data/lib/cocoapods-core/metrics.rb +47 -0
- data/lib/cocoapods-core/platform.rb +99 -11
- data/lib/cocoapods-core/podfile/dsl.rb +623 -124
- data/lib/cocoapods-core/podfile/target_definition.rb +662 -109
- data/lib/cocoapods-core/podfile.rb +138 -65
- data/lib/cocoapods-core/requirement.rb +37 -8
- data/lib/cocoapods-core/source/acceptor.rb +16 -13
- data/lib/cocoapods-core/source/aggregate.rb +79 -103
- data/lib/cocoapods-core/source/health_reporter.rb +9 -18
- data/lib/cocoapods-core/source/manager.rb +488 -0
- data/lib/cocoapods-core/source/metadata.rb +79 -0
- data/lib/cocoapods-core/source.rb +241 -70
- data/lib/cocoapods-core/specification/consumer.rb +187 -47
- data/lib/cocoapods-core/specification/dsl/attribute.rb +49 -85
- data/lib/cocoapods-core/specification/dsl/attribute_support.rb +6 -8
- data/lib/cocoapods-core/specification/dsl/deprecations.rb +9 -126
- data/lib/cocoapods-core/specification/dsl/platform_proxy.rb +30 -20
- data/lib/cocoapods-core/specification/dsl.rb +943 -296
- data/lib/cocoapods-core/specification/json.rb +64 -23
- data/lib/cocoapods-core/specification/linter/analyzer.rb +218 -0
- data/lib/cocoapods-core/specification/linter/result.rb +128 -0
- data/lib/cocoapods-core/specification/linter.rb +310 -309
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +90 -39
- data/lib/cocoapods-core/specification/set/presenter.rb +35 -71
- data/lib/cocoapods-core/specification/set.rb +42 -96
- data/lib/cocoapods-core/specification.rb +368 -130
- data/lib/cocoapods-core/standard_error.rb +45 -24
- data/lib/cocoapods-core/trunk_source.rb +14 -0
- data/lib/cocoapods-core/vendor/requirement.rb +133 -53
- data/lib/cocoapods-core/vendor/version.rb +197 -156
- data/lib/cocoapods-core/vendor.rb +1 -5
- data/lib/cocoapods-core/version.rb +137 -42
- data/lib/cocoapods-core/yaml_helper.rb +334 -0
- data/lib/cocoapods-core.rb +10 -4
- metadata +100 -27
- data/lib/cocoapods-core/source/abstract_data_provider.rb +0 -71
- data/lib/cocoapods-core/source/file_system_data_provider.rb +0 -150
- data/lib/cocoapods-core/source/github_data_provider.rb +0 -143
- data/lib/cocoapods-core/specification/set/statistics.rb +0 -266
- data/lib/cocoapods-core/yaml_converter.rb +0 -192
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'cocoapods-core/source/acceptor'
|
2
2
|
require 'cocoapods-core/source/aggregate'
|
3
3
|
require 'cocoapods-core/source/health_reporter'
|
4
|
-
require 'cocoapods-core/source/
|
5
|
-
require 'cocoapods-core/source/
|
6
|
-
require 'cocoapods-core/source/github_data_provider'
|
4
|
+
require 'cocoapods-core/source/manager'
|
5
|
+
require 'cocoapods-core/source/metadata'
|
7
6
|
|
8
7
|
module Pod
|
9
|
-
|
10
8
|
# The Source class is responsible to manage a collection of podspecs.
|
11
9
|
#
|
12
10
|
# The backing store of the podspecs collection is an implementation detail
|
@@ -18,32 +16,49 @@ module Pod
|
|
18
16
|
# "#{SPEC_NAME}/#{VERSION}/#{SPEC_NAME}.podspec"
|
19
17
|
#
|
20
18
|
class Source
|
19
|
+
# The default branch in which the specs are stored
|
20
|
+
DEFAULT_SPECS_BRANCH = 'master'.freeze
|
21
21
|
|
22
|
-
# @return [
|
22
|
+
# @return [Pod::Source::Metadata] The metadata for this source.
|
23
23
|
#
|
24
|
-
|
24
|
+
attr_reader :metadata
|
25
25
|
|
26
26
|
# @param [Pathname, String] repo @see #repo.
|
27
27
|
#
|
28
|
-
def initialize(repo
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
else
|
33
|
-
@data_provider = repo
|
34
|
-
end
|
28
|
+
def initialize(repo)
|
29
|
+
@repo = Pathname(repo).expand_path
|
30
|
+
@versions_by_name = {}
|
31
|
+
refresh_metadata
|
35
32
|
end
|
36
33
|
|
37
34
|
# @return [String] The name of the source.
|
38
35
|
#
|
39
36
|
def name
|
40
|
-
|
37
|
+
repo.basename.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String] The URL of the source.
|
41
|
+
#
|
42
|
+
# @note In the past we had used `git ls-remote --get-url`, but this could
|
43
|
+
# lead to an issue when finding a source based on its URL when `git`
|
44
|
+
# is configured to rewrite URLs with the `url.<base>.insteadOf`
|
45
|
+
# option. See https://github.com/CocoaPods/CocoaPods/issues/2724.
|
46
|
+
#
|
47
|
+
def url
|
48
|
+
@url ||= begin
|
49
|
+
remote = repo_git(%w(config --get remote.origin.url))
|
50
|
+
if !remote.empty?
|
51
|
+
remote
|
52
|
+
elsif (repo + '.git').exist?
|
53
|
+
"file://#{repo}/.git"
|
54
|
+
end
|
55
|
+
end
|
41
56
|
end
|
42
57
|
|
43
58
|
# @return [String] The type of the source.
|
44
59
|
#
|
45
60
|
def type
|
46
|
-
|
61
|
+
git? ? 'git' : 'file system'
|
47
62
|
end
|
48
63
|
|
49
64
|
alias_method :to_s, :name
|
@@ -65,21 +80,79 @@ module Pod
|
|
65
80
|
"#<#{self.class} name:#{name} type:#{type}>"
|
66
81
|
end
|
67
82
|
|
83
|
+
# @!group Paths
|
84
|
+
#-------------------------------------------------------------------------#
|
85
|
+
|
86
|
+
# @return [Pathname] The path where the source is stored.
|
87
|
+
#
|
88
|
+
attr_reader :repo
|
89
|
+
|
90
|
+
# @return [Pathname] The directory where the specs are stored.
|
91
|
+
#
|
92
|
+
# @note In previous versions of CocoaPods they used to be stored in
|
93
|
+
# the root of the repo. This lead to issues, especially with
|
94
|
+
# the GitHub interface and now they are stored in a dedicated
|
95
|
+
# folder.
|
96
|
+
#
|
97
|
+
def specs_dir
|
98
|
+
@specs_dir ||= begin
|
99
|
+
specs_sub_dir = repo + 'Specs'
|
100
|
+
if specs_sub_dir.exist?
|
101
|
+
specs_sub_dir
|
102
|
+
elsif repo.exist?
|
103
|
+
repo
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param [String] name The name of the pod.
|
109
|
+
#
|
110
|
+
# @return [Pathname] The path at which the specs for the given pod are
|
111
|
+
# stored.
|
112
|
+
#
|
113
|
+
def pod_path(name)
|
114
|
+
specs_dir.join(*metadata.path_fragment(name))
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [Pathname] The path at which source metadata is stored.
|
118
|
+
#
|
119
|
+
def metadata_path
|
120
|
+
repo + 'CocoaPods-version.yml'
|
121
|
+
end
|
122
|
+
|
68
123
|
public
|
69
124
|
|
70
|
-
# @!group
|
125
|
+
# @!group Querying the source
|
71
126
|
#-------------------------------------------------------------------------#
|
72
127
|
|
73
128
|
# @return [Array<String>] the list of the name of all the Pods.
|
74
129
|
#
|
75
130
|
#
|
76
131
|
def pods
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
132
|
+
unless specs_dir
|
133
|
+
raise Informative, "Unable to find a source named: `#{name}`"
|
134
|
+
end
|
135
|
+
glob = specs_dir.join('*/' * metadata.prefix_lengths.size, '*')
|
136
|
+
Pathname.glob(glob).reduce([]) do |pods, entry|
|
137
|
+
pods << entry.basename.to_s if entry.directory?
|
138
|
+
pods
|
139
|
+
end.sort
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns pod names for given array of specification paths.
|
143
|
+
#
|
144
|
+
# @param [Array<String>] spec_paths
|
145
|
+
# Array of file path names for specifications. Path strings should be relative to the source path.
|
146
|
+
#
|
147
|
+
# @return [Array<String>] the list of the name of Pods corresponding to specification paths.
|
148
|
+
#
|
149
|
+
def pods_for_specification_paths(spec_paths)
|
150
|
+
spec_paths.map do |path|
|
151
|
+
absolute_path = repo + path
|
152
|
+
relative_path = absolute_path.relative_path_from(specs_dir)
|
153
|
+
# The first file name returned by 'each_filename' is the pod name
|
154
|
+
relative_path.each_filename.first
|
81
155
|
end
|
82
|
-
pods
|
83
156
|
end
|
84
157
|
|
85
158
|
# @return [Array<Version>] all the available versions for the Pod, sorted
|
@@ -89,8 +162,22 @@ module Pod
|
|
89
162
|
# the name of the Pod.
|
90
163
|
#
|
91
164
|
def versions(name)
|
92
|
-
|
93
|
-
|
165
|
+
return nil unless specs_dir
|
166
|
+
raise ArgumentError, 'No name' unless name
|
167
|
+
pod_dir = pod_path(name)
|
168
|
+
return unless pod_dir.exist?
|
169
|
+
@versions_by_name[name] ||= pod_dir.children.map do |v|
|
170
|
+
next nil unless v.directory?
|
171
|
+
basename = v.basename.to_s
|
172
|
+
next unless basename[0, 1] != '.'
|
173
|
+
begin
|
174
|
+
Version.new(basename)
|
175
|
+
rescue ArgumentError
|
176
|
+
raise Informative, 'An unexpected version directory ' \
|
177
|
+
"`#{basename}` was encountered for the " \
|
178
|
+
"`#{pod_dir}` Pod in the `#{name}` repository."
|
179
|
+
end
|
180
|
+
end.compact.sort.reverse
|
94
181
|
end
|
95
182
|
|
96
183
|
# @return [Specification] the specification for a given version of Pod.
|
@@ -112,31 +199,35 @@ module Pod
|
|
112
199
|
# @return [Pathname] The path of the specification.
|
113
200
|
#
|
114
201
|
def specification_path(name, version)
|
115
|
-
|
202
|
+
raise ArgumentError, 'No name' unless name
|
203
|
+
raise ArgumentError, 'No version' unless version
|
204
|
+
path = pod_path(name) + version.to_s
|
116
205
|
specification_path = path + "#{name}.podspec.json"
|
117
206
|
unless specification_path.exist?
|
118
207
|
specification_path = path + "#{name}.podspec"
|
119
208
|
end
|
120
209
|
unless specification_path.exist?
|
121
210
|
raise StandardError, "Unable to find the specification #{name} " \
|
122
|
-
"(#{version}) in the #{name} source."
|
211
|
+
"(#{version}) in the #{self.name} source."
|
123
212
|
end
|
124
|
-
|
213
|
+
specification_path
|
125
214
|
end
|
126
215
|
|
127
216
|
# @return [Array<Specification>] all the specifications contained by the
|
128
217
|
# source.
|
129
218
|
#
|
130
219
|
def all_specs
|
131
|
-
|
220
|
+
glob = specs_dir.join('*/' * metadata.prefix_lengths.size, '*', '*', '*.podspec{.json,}')
|
221
|
+
specs = Pathname.glob(glob).map do |path|
|
132
222
|
begin
|
133
|
-
|
223
|
+
Specification.from_file(path)
|
134
224
|
rescue
|
135
|
-
CoreUI.warn "Skipping `#{
|
225
|
+
CoreUI.warn "Skipping `#{path.relative_path_from(repo)}` because the " \
|
226
|
+
'podspec contains errors.'
|
136
227
|
next
|
137
228
|
end
|
138
229
|
end
|
139
|
-
specs.
|
230
|
+
specs.compact
|
140
231
|
end
|
141
232
|
|
142
233
|
# Returns the set for the Pod with the given name.
|
@@ -156,22 +247,6 @@ module Pod
|
|
156
247
|
pods.map { |pod_name| set(pod_name) }
|
157
248
|
end
|
158
249
|
|
159
|
-
# Returns the path of the specification with the given name and version.
|
160
|
-
#
|
161
|
-
# @param [String] name
|
162
|
-
# the name of the Pod.
|
163
|
-
#
|
164
|
-
# @param [Version,String] version
|
165
|
-
# the version for the specification.
|
166
|
-
#
|
167
|
-
# @return [Pathname] The path of the specification.
|
168
|
-
#
|
169
|
-
# @todo Remove.
|
170
|
-
#
|
171
|
-
def specification_path(name, version)
|
172
|
-
data_provider.specification_path(name, version)
|
173
|
-
end
|
174
|
-
|
175
250
|
public
|
176
251
|
|
177
252
|
# @!group Searching the source
|
@@ -180,16 +255,33 @@ module Pod
|
|
180
255
|
# @return [Set] a set for a given dependency. The set is identified by the
|
181
256
|
# name of the dependency and takes into account subspecs.
|
182
257
|
#
|
258
|
+
# @note This method is optimized for fast lookups by name, i.e. it does
|
259
|
+
# *not* require iterating through {#pod_sets}
|
260
|
+
#
|
183
261
|
# @todo Rename to #load_set
|
184
262
|
#
|
185
263
|
def search(query)
|
264
|
+
unless specs_dir
|
265
|
+
raise Informative, "Unable to find a source named: `#{name}`"
|
266
|
+
end
|
186
267
|
if query.is_a?(Dependency)
|
187
|
-
|
188
|
-
|
189
|
-
|
268
|
+
query = query.root_name
|
269
|
+
end
|
270
|
+
|
271
|
+
if (versions = @versions_by_name[query]) && !versions.empty?
|
272
|
+
set = set(query)
|
273
|
+
return set if set.specification_name == query
|
274
|
+
end
|
275
|
+
|
276
|
+
found = []
|
277
|
+
Pathname.glob(pod_path(query)) do |path|
|
278
|
+
next unless Dir.foreach(path).any? { |child| child != '.' && child != '..' }
|
279
|
+
found << path.basename.to_s
|
190
280
|
end
|
191
|
-
|
192
|
-
|
281
|
+
|
282
|
+
if [query] == found
|
283
|
+
set = set(query)
|
284
|
+
set if set.specification_name == query
|
193
285
|
end
|
194
286
|
end
|
195
287
|
|
@@ -198,7 +290,7 @@ module Pod
|
|
198
290
|
# @param [String] query
|
199
291
|
# the search term. Can be a regular expression.
|
200
292
|
#
|
201
|
-
# @param [
|
293
|
+
# @param [Boolean] full_text_search
|
202
294
|
# whether the search should be limited to the name of the Pod or
|
203
295
|
# should include also the author, the summary, and the description.
|
204
296
|
#
|
@@ -210,23 +302,19 @@ module Pod
|
|
210
302
|
def search_by_name(query, full_text_search = false)
|
211
303
|
regexp_query = /#{query}/i
|
212
304
|
if full_text_search
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
"contains errors."
|
225
|
-
end
|
226
|
-
texts.grep(regexp_query).empty?
|
305
|
+
pod_sets.reject do |set|
|
306
|
+
texts = []
|
307
|
+
begin
|
308
|
+
s = set.specification
|
309
|
+
texts << s.name
|
310
|
+
texts += s.authors.keys
|
311
|
+
texts << s.summary
|
312
|
+
texts << s.description
|
313
|
+
rescue
|
314
|
+
CoreUI.warn "Skipping `#{set.name}` because the podspec " \
|
315
|
+
'contains errors.'
|
227
316
|
end
|
228
|
-
|
229
|
-
[]
|
317
|
+
texts.grep(regexp_query).empty?
|
230
318
|
end
|
231
319
|
else
|
232
320
|
names = pods.grep(regexp_query)
|
@@ -250,6 +338,56 @@ module Pod
|
|
250
338
|
end
|
251
339
|
end
|
252
340
|
|
341
|
+
# @!group Updating the source
|
342
|
+
#-------------------------------------------------------------------------#
|
343
|
+
|
344
|
+
# Updates the local clone of the source repo.
|
345
|
+
#
|
346
|
+
# @param [Boolean] show_output
|
347
|
+
#
|
348
|
+
# @return [Array<String>] changed_spec_paths
|
349
|
+
# Returns the list of changed spec paths.
|
350
|
+
#
|
351
|
+
def update(show_output)
|
352
|
+
return [] if unchanged_github_repo?
|
353
|
+
prev_commit_hash = git_commit_hash
|
354
|
+
update_git_repo(show_output)
|
355
|
+
@versions_by_name.clear
|
356
|
+
refresh_metadata
|
357
|
+
if version = metadata.last_compatible_version(Version.new(CORE_VERSION))
|
358
|
+
tag = "v#{version}"
|
359
|
+
CoreUI.warn "Using the `#{tag}` tag of the `#{name}` source because " \
|
360
|
+
"it is the last version compatible with CocoaPods #{CORE_VERSION}."
|
361
|
+
repo_git(['checkout', tag])
|
362
|
+
end
|
363
|
+
diff_until_commit_hash(prev_commit_hash)
|
364
|
+
end
|
365
|
+
|
366
|
+
def updateable?
|
367
|
+
git?
|
368
|
+
end
|
369
|
+
|
370
|
+
def git?
|
371
|
+
repo.join('.git').exist? && !repo_git(%w(rev-parse HEAD)).empty?
|
372
|
+
end
|
373
|
+
|
374
|
+
def indexable?
|
375
|
+
true
|
376
|
+
end
|
377
|
+
|
378
|
+
def verify_compatibility!
|
379
|
+
return if metadata.compatible?(CORE_VERSION)
|
380
|
+
|
381
|
+
version_msg = if metadata.minimum_cocoapods_version == metadata.maximum_cocoapods_version
|
382
|
+
metadata.minimum_cocoapods_version
|
383
|
+
else
|
384
|
+
"#{metadata.minimum_cocoapods_version} - #{metadata.maximum_cocoapods_version}"
|
385
|
+
end
|
386
|
+
raise Informative, "The `#{name}` repo requires " \
|
387
|
+
"CocoaPods #{version_msg} (currently using #{CORE_VERSION})\n" \
|
388
|
+
'Update CocoaPods, or checkout the appropriate tag in the repo.'
|
389
|
+
end
|
390
|
+
|
253
391
|
public
|
254
392
|
|
255
393
|
# @!group Representations
|
@@ -295,11 +433,44 @@ module Pod
|
|
295
433
|
specification(name, version) if version
|
296
434
|
rescue Informative
|
297
435
|
Pod::CoreUI.warn "Skipping `#{name}` because the podspec " \
|
298
|
-
|
436
|
+
'contains errors.'
|
299
437
|
nil
|
300
438
|
end
|
301
439
|
|
302
|
-
|
440
|
+
def refresh_metadata
|
441
|
+
@metadata = Metadata.from_file(metadata_path)
|
442
|
+
end
|
303
443
|
|
444
|
+
def git_commit_hash
|
445
|
+
repo_git(%w(rev-parse HEAD))
|
446
|
+
end
|
447
|
+
|
448
|
+
def update_git_repo(show_output = false)
|
449
|
+
repo_git(['checkout', git_tracking_branch])
|
450
|
+
output = repo_git(%w(pull --ff-only), :include_error => true)
|
451
|
+
CoreUI.puts output if show_output
|
452
|
+
end
|
453
|
+
|
454
|
+
def git_tracking_branch
|
455
|
+
path = repo.join('.git', 'cocoapods_branch')
|
456
|
+
path.file? ? path.read.strip : DEFAULT_SPECS_BRANCH
|
457
|
+
end
|
458
|
+
|
459
|
+
def diff_until_commit_hash(commit_hash)
|
460
|
+
repo_git(%W(diff --name-only #{commit_hash}..HEAD)).split("\n")
|
461
|
+
end
|
462
|
+
|
463
|
+
def repo_git(args, include_error: false)
|
464
|
+
command = "env -u GIT_CONFIG git -C \"#{repo}\" " << args.join(' ')
|
465
|
+
command << ' 2>&1' if include_error
|
466
|
+
(`#{command}` || '').strip
|
467
|
+
end
|
468
|
+
|
469
|
+
def unchanged_github_repo?
|
470
|
+
return unless url =~ /github.com/
|
471
|
+
!GitHub.modified_since_commit(url, git_commit_hash)
|
472
|
+
end
|
473
|
+
|
474
|
+
#-------------------------------------------------------------------------#
|
304
475
|
end
|
305
476
|
end
|