cocoapods-core 1.6.2 → 1.7.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 -0
- data/lib/cocoapods-core/cdn_source.rb +292 -0
- data/lib/cocoapods-core/gem_version.rb +1 -1
- data/lib/cocoapods-core/lockfile.rb +11 -16
- data/lib/cocoapods-core/podfile.rb +1 -1
- data/lib/cocoapods-core/podfile/dsl.rb +50 -3
- data/lib/cocoapods-core/podfile/target_definition.rb +44 -4
- data/lib/cocoapods-core/source/manager.rb +13 -9
- data/lib/cocoapods-core/specification.rb +77 -13
- data/lib/cocoapods-core/specification/consumer.rb +16 -0
- data/lib/cocoapods-core/specification/dsl.rb +88 -11
- data/lib/cocoapods-core/specification/dsl/attribute.rb +9 -2
- data/lib/cocoapods-core/specification/json.rb +27 -14
- data/lib/cocoapods-core/specification/linter.rb +20 -3
- data/lib/cocoapods-core/specification/root_attribute_accessors.rb +17 -4
- data/lib/cocoapods-core/version.rb +3 -1
- data/lib/cocoapods-core/yaml_helper.rb +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d6029877133203026dca0a0536818e5799bb22a
|
4
|
+
data.tar.gz: 14c7457385e244d39a5fabff47257f702c6b5afe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b34c2e92c8d1125c7d30237ca3f8771195860817768873d4ca3c774a82d6d83cf2741e7ca81e21ec738ce6fdd3c14b442c4815dc11aab2260ae9416e9fdad437
|
7
|
+
data.tar.gz: 1e4bc919ec36bd8f87a92dae0ce64755103d4bcd04b510443a6ef87078c22352ac084470d5e95c6f02c883b940cf7f68c9c31d1e71bb05ca21011b983a1e495d
|
data/lib/cocoapods-core.rb
CHANGED
@@ -27,6 +27,7 @@ module Pod
|
|
27
27
|
autoload :Platform, 'cocoapods-core/platform'
|
28
28
|
autoload :Podfile, 'cocoapods-core/podfile'
|
29
29
|
autoload :Source, 'cocoapods-core/source'
|
30
|
+
autoload :CDNSource, 'cocoapods-core/cdn_source'
|
30
31
|
autoload :MasterSource, 'cocoapods-core/master_source'
|
31
32
|
autoload :Specification, 'cocoapods-core/specification'
|
32
33
|
autoload :StandardError, 'cocoapods-core/standard_error'
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require 'cocoapods-core/source'
|
2
|
+
require 'rest'
|
3
|
+
require 'concurrent'
|
4
|
+
|
5
|
+
module Pod
|
6
|
+
# Subclass of Pod::Source to provide support for CDN-based Specs repositories
|
7
|
+
#
|
8
|
+
class CDNSource < Source
|
9
|
+
# @param [String] repo The name of the repository
|
10
|
+
#
|
11
|
+
def initialize(repo)
|
12
|
+
@check_existing_files_for_update = false
|
13
|
+
# Optimization: we initialize startup_time when the source is first initialized
|
14
|
+
# and then test file modification dates against it. Any file that was touched
|
15
|
+
# after the source was initialized, is considered fresh enough.
|
16
|
+
@startup_time = Time.new
|
17
|
+
|
18
|
+
@executor = Concurrent::ThreadPoolExecutor.new(
|
19
|
+
:min_threads => 1,
|
20
|
+
:max_threads => 200,
|
21
|
+
:max_queue => 0 # unbounded work queue
|
22
|
+
)
|
23
|
+
super(repo)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] The URL of the source.
|
27
|
+
#
|
28
|
+
def url
|
29
|
+
@url ||= File.read(repo.join('.url'))
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String] The type of the source.
|
33
|
+
#
|
34
|
+
def type
|
35
|
+
'CDN'
|
36
|
+
end
|
37
|
+
|
38
|
+
def refresh_metadata
|
39
|
+
if metadata.nil?
|
40
|
+
unless repo.exist?
|
41
|
+
raise Informative, "Unable to find a source named: `#{name}`"
|
42
|
+
end
|
43
|
+
|
44
|
+
specs_dir.mkpath
|
45
|
+
download_file('CocoaPods-version.yml')
|
46
|
+
end
|
47
|
+
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
def preheat_existing_files
|
52
|
+
all_existing_files = [repo.join('**/*.yml'), repo.join('**/*.txt'), repo.join('**/*.json')].map(&Pathname.method(:glob)).flatten
|
53
|
+
loaders = all_existing_files.map { |f| f.relative_path_from(repo).to_s }.map do |file|
|
54
|
+
Concurrent::Promise.execute(:executor => @executor) do
|
55
|
+
download_file(file)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
Concurrent::Promise.zip(*loaders).wait!
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Pathname] The directory where the specs are stored.
|
62
|
+
#
|
63
|
+
def specs_dir
|
64
|
+
@specs_dir ||= repo + 'Specs'
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!group Querying the source
|
68
|
+
#-------------------------------------------------------------------------#
|
69
|
+
|
70
|
+
# @return [Array<String>] the list of the name of all the Pods.
|
71
|
+
#
|
72
|
+
def pods
|
73
|
+
download_file('all_pods.txt')
|
74
|
+
local_file('all_pods.txt', &:to_a).map(&:chomp)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [Array<Version>] all the available versions for the Pod, sorted
|
78
|
+
# from highest to lowest.
|
79
|
+
#
|
80
|
+
# @param [String] name
|
81
|
+
# the name of the Pod.
|
82
|
+
#
|
83
|
+
def versions(name)
|
84
|
+
return nil unless specs_dir
|
85
|
+
raise ArgumentError, 'No name' unless name
|
86
|
+
|
87
|
+
return @versions_by_name[name] unless @versions_by_name[name].nil?
|
88
|
+
|
89
|
+
pod_path_actual = pod_path(name)
|
90
|
+
pod_path_relative = relative_pod_path(name)
|
91
|
+
versions_file_path_relative = pod_path_relative.join(INDEX_FILE_NAME).to_s
|
92
|
+
download_file(versions_file_path_relative)
|
93
|
+
|
94
|
+
return nil unless pod_path_actual.join(INDEX_FILE_NAME).exist?
|
95
|
+
|
96
|
+
loaders = []
|
97
|
+
@versions_by_name[name] ||= local_file(versions_file_path_relative) do |file|
|
98
|
+
file.map do |v|
|
99
|
+
version = v.chomp
|
100
|
+
|
101
|
+
# Optimization: ensure all the podspec files at least exist. The correct one will get refreshed
|
102
|
+
# in #specification_path regardless.
|
103
|
+
podspec_version_path_relative = Pathname.new(version).join("#{name}.podspec.json")
|
104
|
+
unless pod_path_actual.join(podspec_version_path_relative).exist?
|
105
|
+
loaders << Concurrent::Promise.execute(:executor => @executor) do
|
106
|
+
download_file(pod_path_relative.join(podspec_version_path_relative).to_s)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
begin
|
110
|
+
Version.new(version) if version[0, 1] != '.'
|
111
|
+
rescue ArgumentError
|
112
|
+
raise Informative, 'An unexpected version directory ' \
|
113
|
+
"`#{version}` was encountered for the " \
|
114
|
+
"`#{pod_dir}` Pod in the `#{name}` repository."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end.compact.sort.reverse
|
118
|
+
Concurrent::Promise.zip(*loaders).wait!
|
119
|
+
@versions_by_name[name]
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns the path of the specification with the given name and version.
|
123
|
+
#
|
124
|
+
# @param [String] name
|
125
|
+
# the name of the Pod.
|
126
|
+
#
|
127
|
+
# @param [Version,String] version
|
128
|
+
# the version for the specification.
|
129
|
+
#
|
130
|
+
# @return [Pathname] The path of the specification.
|
131
|
+
#
|
132
|
+
def specification_path(name, version)
|
133
|
+
raise ArgumentError, 'No name' unless name
|
134
|
+
raise ArgumentError, 'No version' unless version
|
135
|
+
|
136
|
+
podspec_version_path_relative = Pathname.new(version.to_s).join("#{name}.podspec.json")
|
137
|
+
relative_podspec = relative_pod_path(name).join(podspec_version_path_relative).to_s
|
138
|
+
download_file(relative_podspec)
|
139
|
+
pod_path(name).join(podspec_version_path_relative)
|
140
|
+
end
|
141
|
+
|
142
|
+
# @return [Array<Specification>] all the specifications contained by the
|
143
|
+
# source.
|
144
|
+
#
|
145
|
+
def all_specs
|
146
|
+
raise Informative, "Can't retrieve all the specs for a CDN-backed source, it will take forever"
|
147
|
+
end
|
148
|
+
|
149
|
+
# @!group Searching the source
|
150
|
+
#-------------------------------------------------------------------------#
|
151
|
+
|
152
|
+
# @return [Set] a set for a given dependency. The set is identified by the
|
153
|
+
# name of the dependency and takes into account subspecs.
|
154
|
+
#
|
155
|
+
# @note This method is optimized for fast lookups by name, i.e. it does
|
156
|
+
# *not* require iterating through {#pod_sets}
|
157
|
+
#
|
158
|
+
# @todo Rename to #load_set
|
159
|
+
#
|
160
|
+
def search(query)
|
161
|
+
unless specs_dir
|
162
|
+
raise Informative, "Unable to find a source named: `#{name}`"
|
163
|
+
end
|
164
|
+
if query.is_a?(Dependency)
|
165
|
+
query = query.root_name
|
166
|
+
end
|
167
|
+
|
168
|
+
found = download_file(relative_pod_path(query).join(INDEX_FILE_NAME).to_s)
|
169
|
+
|
170
|
+
if found
|
171
|
+
set = set(query)
|
172
|
+
set if set.specification_name == query
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# @return [Array<Set>] The list of the sets that contain the search term.
|
177
|
+
#
|
178
|
+
# @param [String] query
|
179
|
+
# the search term. Can be a regular expression.
|
180
|
+
#
|
181
|
+
# @param [Bool] full_text_search
|
182
|
+
# not supported due to performance reasons
|
183
|
+
#
|
184
|
+
# @note full text search requires to load the specification for each pod,
|
185
|
+
# and therefore not supported.
|
186
|
+
#
|
187
|
+
def search_by_name(query, full_text_search = false)
|
188
|
+
if full_text_search
|
189
|
+
raise Informative, "Can't perform full text search, it will take forever"
|
190
|
+
else
|
191
|
+
super(query)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Check update dates for all existing files.
|
196
|
+
# Does not download non-existing specs, since CDN-backed repo is updated live.
|
197
|
+
#
|
198
|
+
# @param [Bool] show_output
|
199
|
+
#
|
200
|
+
# @return [Array<String>] Always returns empty array, as it cannot know
|
201
|
+
# everything that actually changed.
|
202
|
+
#
|
203
|
+
def update(_show_output)
|
204
|
+
@check_existing_files_for_update = true
|
205
|
+
begin
|
206
|
+
preheat_existing_files
|
207
|
+
ensure
|
208
|
+
@check_existing_files_for_update = false
|
209
|
+
end
|
210
|
+
[]
|
211
|
+
end
|
212
|
+
|
213
|
+
def git?
|
214
|
+
# Long story here. This property is actually used solely by Source::Manager to determine
|
215
|
+
# which sources are updatable. Ideally, this would require a name change but @segiddins
|
216
|
+
# has pointed out that it is public and could break plugins.
|
217
|
+
# In any case, CDN-backed repos can be updated and therefore the value ought to be true.
|
218
|
+
true
|
219
|
+
end
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
# Index files contain all the sub directories in the directory, separated by
|
224
|
+
# a newline. We use those because you can't get a directory listing from a CDN.
|
225
|
+
INDEX_FILE_NAME = 'index.txt'.freeze
|
226
|
+
|
227
|
+
def local_file(partial_url)
|
228
|
+
File.open(repo.join(partial_url)) do |file|
|
229
|
+
yield file if block_given?
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def relative_pod_path(pod_name)
|
234
|
+
pod_path(pod_name).relative_path_from(repo)
|
235
|
+
end
|
236
|
+
|
237
|
+
def download_file(partial_url)
|
238
|
+
file_remote_url = url + partial_url.to_s
|
239
|
+
path = repo + partial_url
|
240
|
+
|
241
|
+
if File.exist?(path)
|
242
|
+
if @startup_time < File.mtime(path)
|
243
|
+
debug "CDN: #{name} Relative path: #{partial_url} modified during this run! Returning local"
|
244
|
+
return partial_url
|
245
|
+
end
|
246
|
+
|
247
|
+
unless @check_existing_files_for_update
|
248
|
+
debug "CDN: #{name} Relative path: #{partial_url} exists! Returning local because checking is only perfomed in repo update"
|
249
|
+
return partial_url
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
path.dirname.mkpath
|
254
|
+
|
255
|
+
etag_path = path.sub_ext(path.extname + '.etag')
|
256
|
+
|
257
|
+
etag = File.read(etag_path) if File.exist?(etag_path)
|
258
|
+
debug "CDN: #{name} Relative path: #{partial_url}, has ETag? #{etag}" unless etag.nil?
|
259
|
+
|
260
|
+
response = etag.nil? ? REST.get(file_remote_url) : REST.get(file_remote_url, 'If-None-Match' => etag)
|
261
|
+
|
262
|
+
case response.status_code
|
263
|
+
when 304
|
264
|
+
debug "CDN: #{name} Relative path not modified: #{partial_url}"
|
265
|
+
# We need to update the file modification date, as it is later used for freshness
|
266
|
+
# optimization. See #initialize for more information.
|
267
|
+
FileUtils.touch path
|
268
|
+
partial_url
|
269
|
+
when 200
|
270
|
+
File.open(path, 'w') { |f| f.write(response.body) }
|
271
|
+
|
272
|
+
etag_new = response.headers['etag'].first if response.headers.include?('etag')
|
273
|
+
debug "CDN: #{name} Relative path downloaded: #{partial_url}, save ETag: #{etag_new}"
|
274
|
+
File.open(etag_path, 'w') { |f| f.write(etag_new) } unless etag_new.nil?
|
275
|
+
partial_url
|
276
|
+
when 404
|
277
|
+
debug "CDN: #{name} Relative path couldn't be downloaded: #{partial_url} Response: #{response.status_code}"
|
278
|
+
nil
|
279
|
+
else
|
280
|
+
raise Informative, "CDN: #{name} Relative path couldn't be downloaded: #{partial_url} Response: #{response.status_code}"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def debug(message)
|
285
|
+
if defined?(Pod::UI)
|
286
|
+
Pod::UI.message(message)
|
287
|
+
else
|
288
|
+
CoreUI.puts(message)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
@@ -454,22 +454,17 @@ module Pod
|
|
454
454
|
#
|
455
455
|
#
|
456
456
|
def generate_pods_data(specs)
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
pod_and_deps.each do |name, deps|
|
463
|
-
if tmp[name]
|
464
|
-
tmp[name].concat(deps).uniq!
|
465
|
-
else
|
466
|
-
tmp[name] = deps
|
467
|
-
end
|
457
|
+
pods_and_deps_merged = specs.reduce({}) do |result, spec|
|
458
|
+
name = spec.to_s
|
459
|
+
result[name] ||= []
|
460
|
+
result[name].concat(spec.all_dependencies.map(&:to_s))
|
461
|
+
result
|
468
462
|
end
|
469
|
-
|
470
|
-
|
463
|
+
|
464
|
+
pod_and_deps = pods_and_deps_merged.map do |name, deps|
|
465
|
+
deps.empty? ? name : { name => YAMLHelper.sorted_array(deps.uniq) }
|
471
466
|
end
|
472
|
-
pod_and_deps
|
467
|
+
YAMLHelper.sorted_array(pod_and_deps)
|
473
468
|
end
|
474
469
|
|
475
470
|
# Generates the list of the dependencies of the Podfile.
|
@@ -481,7 +476,7 @@ module Pod
|
|
481
476
|
# @return [Array] the generated data.
|
482
477
|
#
|
483
478
|
def generate_dependencies_data(podfile)
|
484
|
-
podfile.dependencies.map(&:to_s)
|
479
|
+
YAMLHelper.sorted_array(podfile.dependencies.map(&:to_s))
|
485
480
|
end
|
486
481
|
|
487
482
|
# Generates the hash of spec repo sources used in the Podfile.
|
@@ -496,7 +491,7 @@ module Pod
|
|
496
491
|
key = source.url || source.name
|
497
492
|
key = key.downcase if source.name == Pod::MasterSource::MASTER_REPO_NAME
|
498
493
|
value = specs.map { |s| s.root.name }.uniq
|
499
|
-
[key, value]
|
494
|
+
[key, YAMLHelper.sorted_array(value)]
|
500
495
|
end.compact]
|
501
496
|
end
|
502
497
|
|
@@ -20,7 +20,7 @@ module Pod
|
|
20
20
|
# target 'MyApp' do
|
21
21
|
# pod 'ObjectiveSugar', '~> 0.5'
|
22
22
|
#
|
23
|
-
# target
|
23
|
+
# target 'MyAppTests' do
|
24
24
|
# inherit! :search_paths
|
25
25
|
# pod 'OCMock', '~> 2.0.1'
|
26
26
|
# end
|
@@ -112,6 +112,9 @@ module Pod
|
|
112
112
|
# specify in your version requirement. The example is equal to
|
113
113
|
# `>= 0.1.2` combined with `< 0.2.0` and will always match the
|
114
114
|
# latest known version matching your requirements.
|
115
|
+
# * `~> 0.1.3-beta.0` Beta and release versions for 0.1.3, release versions
|
116
|
+
# up to 0.2 excluding 0.2. Components separated by a dash (-)
|
117
|
+
# will not be considered for the version requirement.
|
115
118
|
#
|
116
119
|
# A list of version requirements can be specified for even more fine
|
117
120
|
# grained control.
|
@@ -182,6 +185,18 @@ module Pod
|
|
182
185
|
#
|
183
186
|
# pod 'QueryKit', :subspecs => ['Attribute', 'QuerySet']
|
184
187
|
#
|
188
|
+
# ### Test Specs
|
189
|
+
#
|
190
|
+
# Test specs can be optionally included via the `:testspecs` option. By default,
|
191
|
+
# none of a Pod's test specs are included.
|
192
|
+
#
|
193
|
+
# You may specify a list of test spec names to install using the following:
|
194
|
+
#
|
195
|
+
# pod 'AFNetworking', :testspecs => ['UnitTests', 'SomeOtherTests']
|
196
|
+
#
|
197
|
+
# The values provided to `:testspecs` correspond to the name provided to the
|
198
|
+
# `test_spec` DSL attribute in a Podspec.
|
199
|
+
#
|
185
200
|
# ------
|
186
201
|
#
|
187
202
|
# Dependencies can be obtained also from external sources.
|
@@ -753,8 +768,7 @@ module Pod
|
|
753
768
|
# @param [String] source
|
754
769
|
# The URL of a specs repository.
|
755
770
|
#
|
756
|
-
# @example Specifying to first use the Artsy repository and then the
|
757
|
-
# CocoaPods Master Repository
|
771
|
+
# @example Specifying to first use the Artsy repository and then the CocoaPods Master Repository
|
758
772
|
#
|
759
773
|
# source 'https://github.com/artsy/Specs.git'
|
760
774
|
# source 'https://github.com/CocoaPods/Specs.git'
|
@@ -847,6 +861,39 @@ module Pod
|
|
847
861
|
raise Informative, 'Specifying multiple `post_install` hooks is unsupported.' if @post_install_callback
|
848
862
|
@post_install_callback = block
|
849
863
|
end
|
864
|
+
|
865
|
+
# Specifies the Swift version requirements this target definition supports.
|
866
|
+
#
|
867
|
+
# **Note** These requirements are inherited from the parent, if specified and if none
|
868
|
+
# are specified at the root level then all versions are considered to be supported.
|
869
|
+
#
|
870
|
+
# @param [String, Version, Array<String>, Array<Version>] requirements
|
871
|
+
# The set of requirements this target supports.
|
872
|
+
#
|
873
|
+
# @example
|
874
|
+
#
|
875
|
+
# target 'MyApp' do
|
876
|
+
# supports_swift_versions '>= 3.0', '< 4.0'
|
877
|
+
# pod 'AFNetworking', '~> 1.0'
|
878
|
+
# end
|
879
|
+
#
|
880
|
+
# @example
|
881
|
+
#
|
882
|
+
# supports_swift_versions '>= 3.0', '< 4.0'
|
883
|
+
#
|
884
|
+
# target 'MyApp' do
|
885
|
+
# pod 'AFNetworking', '~> 1.0'
|
886
|
+
# end
|
887
|
+
#
|
888
|
+
# target 'ZipApp' do
|
889
|
+
# pod 'SSZipArchive'
|
890
|
+
# end
|
891
|
+
#
|
892
|
+
# @return [void]
|
893
|
+
#
|
894
|
+
def supports_swift_versions(*requirements)
|
895
|
+
current_target_definition.store_swift_version_requirements(*requirements)
|
896
|
+
end
|
850
897
|
end
|
851
898
|
end
|
852
899
|
end
|
@@ -140,7 +140,7 @@ module Pod
|
|
140
140
|
# Sets the path of the user project this target definition should link
|
141
141
|
# with.
|
142
142
|
#
|
143
|
-
# @param [String]
|
143
|
+
# @param [String] name
|
144
144
|
# The path of the project.
|
145
145
|
#
|
146
146
|
# @return [void]
|
@@ -393,6 +393,27 @@ module Pod
|
|
393
393
|
get_hash_value('swift_version')
|
394
394
|
end
|
395
395
|
|
396
|
+
# @return [Array<String>] the Swift version requirements this target definition enforces.
|
397
|
+
#
|
398
|
+
def swift_version_requirements
|
399
|
+
get_hash_value('swift_version_requirements')
|
400
|
+
end
|
401
|
+
|
402
|
+
# Queries the target if a version of Swift is supported or not.
|
403
|
+
#
|
404
|
+
# @param [Version] swift_version
|
405
|
+
# The Swift version to query against.
|
406
|
+
#
|
407
|
+
# @return [Boolean] Whether the target accepts the specified Swift version.
|
408
|
+
#
|
409
|
+
def supports_swift_version?(swift_version)
|
410
|
+
if swift_version_requirements.nil?
|
411
|
+
root? || parent.supports_swift_version?(swift_version)
|
412
|
+
else
|
413
|
+
Requirement.create(swift_version_requirements).satisfied_by?(swift_version)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
396
417
|
#--------------------------------------#
|
397
418
|
|
398
419
|
# Whether a specific pod should be linked to the target when building for
|
@@ -610,6 +631,17 @@ module Pod
|
|
610
631
|
set_platform(name, target)
|
611
632
|
end
|
612
633
|
|
634
|
+
# Stores the Swift version requirements to be used for this target.
|
635
|
+
#
|
636
|
+
# @param [String, Version, Array<String>, Array<Version>] requirements
|
637
|
+
# The set of requirements this target supports.
|
638
|
+
#
|
639
|
+
# @return [void]
|
640
|
+
#
|
641
|
+
def store_swift_version_requirements(*requirements)
|
642
|
+
set_hash_value('swift_version_requirements', requirements.flatten.map(&:to_s))
|
643
|
+
end
|
644
|
+
|
613
645
|
#--------------------------------------#
|
614
646
|
|
615
647
|
# Stores the dependency for a Pod with the given name.
|
@@ -742,6 +774,7 @@ module Pod
|
|
742
774
|
children
|
743
775
|
configuration_pod_whitelist
|
744
776
|
uses_frameworks
|
777
|
+
swift_version_requirements
|
745
778
|
inheritance
|
746
779
|
abstract
|
747
780
|
swift_version
|
@@ -860,6 +893,7 @@ module Pod
|
|
860
893
|
if inhibit_hash['all']
|
861
894
|
# Clean pods that are set to not inhibit inside parent if inhibit_all_warnings! was set.
|
862
895
|
parent_hash['not_for_pods'] = nil
|
896
|
+
inhibit_hash.delete('all') if parent_hash['all']
|
863
897
|
end
|
864
898
|
parent_hash.merge(inhibit_hash) do |_, l, r|
|
865
899
|
Array(l).concat(r).uniq
|
@@ -966,7 +1000,7 @@ module Pod
|
|
966
1000
|
# Removes :inhibit_warnings from the requirements list, and adds
|
967
1001
|
# the pod's name into internal hash for disabling warnings.
|
968
1002
|
#
|
969
|
-
# @param [String]
|
1003
|
+
# @param [String] name The name of the pod
|
970
1004
|
#
|
971
1005
|
# @param [Array] requirements
|
972
1006
|
# If :inhibit_warnings is the only key in the hash, the hash
|
@@ -988,7 +1022,7 @@ module Pod
|
|
988
1022
|
# Removes :modular_headers from the requirements list, and adds
|
989
1023
|
# the pods name into internal hash for modular headers.
|
990
1024
|
#
|
991
|
-
# @param [String]
|
1025
|
+
# @param [String] name The name of the pod
|
992
1026
|
#
|
993
1027
|
# @param [Array] requirements
|
994
1028
|
# If :modular_headers is the only key in the hash, the hash
|
@@ -1011,7 +1045,7 @@ module Pod
|
|
1011
1045
|
# and adds the pod's name into the internal hash for which pods should be
|
1012
1046
|
# linked in which configuration only.
|
1013
1047
|
#
|
1014
|
-
# @param [String]
|
1048
|
+
# @param [String] name The name of the pod
|
1015
1049
|
#
|
1016
1050
|
# @param [Array] requirements
|
1017
1051
|
# If :configurations is the only key in the hash, the hash
|
@@ -1048,6 +1082,7 @@ module Pod
|
|
1048
1082
|
|
1049
1083
|
subspecs = options.delete(:subspecs)
|
1050
1084
|
test_specs = options.delete(:testspecs)
|
1085
|
+
app_specs = options.delete(:appspecs)
|
1051
1086
|
|
1052
1087
|
subspecs.each do |ss|
|
1053
1088
|
store_pod("#{name}/#{ss}", *requirements.dup)
|
@@ -1058,6 +1093,11 @@ module Pod
|
|
1058
1093
|
store_pod("#{name}/#{ss}", *requirements_copy)
|
1059
1094
|
end if test_specs
|
1060
1095
|
|
1096
|
+
app_specs.each do |as|
|
1097
|
+
requirements_copy = requirements.map(&:dup)
|
1098
|
+
store_pod("#{name}/#{as}", *requirements_copy)
|
1099
|
+
end if app_specs
|
1100
|
+
|
1061
1101
|
requirements.pop if options.empty?
|
1062
1102
|
!subspecs.nil?
|
1063
1103
|
end
|
@@ -33,15 +33,12 @@ module Pod
|
|
33
33
|
# will be used.
|
34
34
|
#
|
35
35
|
def aggregate_for_dependency(dependency)
|
36
|
-
if dependency.podspec_repo
|
37
|
-
source = source_with_url(dependency.podspec_repo)
|
38
|
-
raise StandardError, '[Bug] Failed to find known source with the URL ' \
|
39
|
-
"#{dependency.podspec_repo.inspect}" if source.nil?
|
36
|
+
return aggregate if dependency.podspec_repo.nil?
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
source = source_with_url(dependency.podspec_repo)
|
39
|
+
return aggregate if source.nil?
|
40
|
+
|
41
|
+
aggregate_with_repos([source.repo])
|
45
42
|
end
|
46
43
|
|
47
44
|
# @return [Array<Source>] The list of the sources with the given names.
|
@@ -234,6 +231,10 @@ module Pod
|
|
234
231
|
# A hash containing changed specification paths for each source.
|
235
232
|
#
|
236
233
|
def update_search_index_if_needed_in_background(changed_spec_paths)
|
234
|
+
if Gem.win_platform?
|
235
|
+
update_search_index_if_needed(changed_spec_paths)
|
236
|
+
return
|
237
|
+
end
|
237
238
|
Process.fork do
|
238
239
|
Process.daemon
|
239
240
|
update_search_index_if_needed(changed_spec_paths)
|
@@ -283,7 +284,10 @@ module Pod
|
|
283
284
|
#
|
284
285
|
def source_from_path(path)
|
285
286
|
@sources_by_path ||= Hash.new do |hash, key|
|
286
|
-
hash[key] =
|
287
|
+
hash[key] = case
|
288
|
+
when (key + '.url').exist?
|
289
|
+
CDNSource.new(key)
|
290
|
+
when key.basename.to_s == Pod::MasterSource::MASTER_REPO_NAME
|
287
291
|
MasterSource.new(key)
|
288
292
|
else
|
289
293
|
Source.new(key)
|
@@ -37,13 +37,18 @@ module Pod
|
|
37
37
|
# @param [Bool] test_specification
|
38
38
|
# Whether the specification is a test specification
|
39
39
|
#
|
40
|
-
|
40
|
+
# @param [Bool] app_specification
|
41
|
+
# Whether the specification is an app specification
|
42
|
+
#
|
43
|
+
def initialize(parent = nil, name = nil, test_specification = false, app_specification: false)
|
44
|
+
raise StandardError, "#{self} can not be both an app and test specification." if test_specification && app_specification
|
41
45
|
@attributes_hash = {}
|
42
46
|
@subspecs = []
|
43
47
|
@consumers = {}
|
44
48
|
@parent = parent
|
45
49
|
@hash_value = nil
|
46
50
|
@test_specification = test_specification
|
51
|
+
@app_specification = app_specification
|
47
52
|
attributes_hash['name'] = name
|
48
53
|
attributes_hash['test_type'] = :unit if test_specification
|
49
54
|
|
@@ -74,6 +79,11 @@ module Pod
|
|
74
79
|
attr_accessor :test_specification
|
75
80
|
alias_method :test_specification?, :test_specification
|
76
81
|
|
82
|
+
# @return [Bool] If this specification is an app specification.
|
83
|
+
#
|
84
|
+
attr_accessor :app_specification
|
85
|
+
alias_method :app_specification?, :app_specification
|
86
|
+
|
77
87
|
# Checks if a specification is equal to the given one according its name
|
78
88
|
# and to its version.
|
79
89
|
#
|
@@ -221,8 +231,35 @@ module Pod
|
|
221
231
|
|
222
232
|
public
|
223
233
|
|
234
|
+
# @return [Symbol] Spec type of the current spec.
|
235
|
+
#
|
236
|
+
# @note see Attribute#SUPPORTED_SPEC_TYPES for the list of available spec_types.
|
237
|
+
#
|
238
|
+
def spec_type
|
239
|
+
return :app if app_specification?
|
240
|
+
return :test if test_specification?
|
241
|
+
|
242
|
+
:library
|
243
|
+
end
|
244
|
+
|
224
245
|
# @!group Dependencies & Subspecs
|
225
246
|
|
247
|
+
# @return [Bool] If this specification is a library specification.
|
248
|
+
#
|
249
|
+
# @note a library specification is a specification that is not of type app or test.
|
250
|
+
#
|
251
|
+
def library_specification?
|
252
|
+
!app_specification? && !test_specification?
|
253
|
+
end
|
254
|
+
|
255
|
+
# @return [Bool] If this specification is not a library specification.
|
256
|
+
#
|
257
|
+
# @note see #library_specification?
|
258
|
+
#
|
259
|
+
def non_library_specification?
|
260
|
+
!library_specification?
|
261
|
+
end
|
262
|
+
|
226
263
|
# @return [Symbol] the test type supported if this is a test specification.
|
227
264
|
#
|
228
265
|
def test_type
|
@@ -236,6 +273,20 @@ module Pod
|
|
236
273
|
subspecs.select(&:test_specification?)
|
237
274
|
end
|
238
275
|
|
276
|
+
# @return [Array<Specification>] the list of all the app subspecs of
|
277
|
+
# a specification.
|
278
|
+
#
|
279
|
+
def app_specs
|
280
|
+
subspecs.select(&:app_specification?)
|
281
|
+
end
|
282
|
+
|
283
|
+
# @return [Array<Specification>] the list of all the non libary (app or test) subspecs of
|
284
|
+
# a specification.
|
285
|
+
#
|
286
|
+
def non_library_specs
|
287
|
+
subspecs.select(&:non_library_specification?)
|
288
|
+
end
|
289
|
+
|
239
290
|
# @return [Array<Specification>] the recursive list of all the subspecs of
|
240
291
|
# a specification.
|
241
292
|
#
|
@@ -265,7 +316,7 @@ module Pod
|
|
265
316
|
#
|
266
317
|
# @return [Specification] the subspec with the given name or self.
|
267
318
|
#
|
268
|
-
def subspec_by_name(relative_name, raise_if_missing = true,
|
319
|
+
def subspec_by_name(relative_name, raise_if_missing = true, include_non_library_specifications = false)
|
269
320
|
if relative_name.nil? || relative_name == base_name
|
270
321
|
self
|
271
322
|
elsif relative_name.downcase == base_name.downcase
|
@@ -274,7 +325,7 @@ module Pod
|
|
274
325
|
else
|
275
326
|
remainder = relative_name[base_name.size + 1..-1]
|
276
327
|
subspec_name = remainder.split('/').shift
|
277
|
-
subspec = subspecs.find { |s| s.base_name == subspec_name && (
|
328
|
+
subspec = subspecs.find { |s| s.base_name == subspec_name && (include_non_library_specifications || !s.non_library_specification?) }
|
278
329
|
unless subspec
|
279
330
|
if raise_if_missing
|
280
331
|
raise Informative, 'Unable to find a specification named ' \
|
@@ -283,7 +334,7 @@ module Pod
|
|
283
334
|
return nil
|
284
335
|
end
|
285
336
|
end
|
286
|
-
subspec.subspec_by_name(remainder, raise_if_missing,
|
337
|
+
subspec.subspec_by_name(remainder, raise_if_missing, include_non_library_specifications)
|
287
338
|
end
|
288
339
|
end
|
289
340
|
|
@@ -307,7 +358,7 @@ module Pod
|
|
307
358
|
#
|
308
359
|
def subspec_dependencies(platform = nil)
|
309
360
|
specs = if default_subspecs.empty?
|
310
|
-
subspecs.compact.reject(&:
|
361
|
+
subspecs.compact.reject(&:non_library_specification?)
|
311
362
|
else
|
312
363
|
default_subspecs.map do |subspec_name|
|
313
364
|
root.subspec_by_name("#{name}/#{subspec_name}")
|
@@ -377,6 +428,13 @@ module Pod
|
|
377
428
|
end
|
378
429
|
end
|
379
430
|
|
431
|
+
# @return [Hash] The scheme value.
|
432
|
+
#
|
433
|
+
def scheme
|
434
|
+
value = attributes_hash['scheme'] || {}
|
435
|
+
Specification.convert_keys_to_symbol(value, :recursive => false)
|
436
|
+
end
|
437
|
+
|
380
438
|
#-------------------------------------------------------------------------#
|
381
439
|
|
382
440
|
public
|
@@ -520,30 +578,36 @@ module Pod
|
|
520
578
|
# @param [Object] value
|
521
579
|
# the value that needs to be stripped from the Symbols.
|
522
580
|
#
|
523
|
-
# @
|
581
|
+
# @param [Boolean] recursive
|
582
|
+
# whether to convert keys of nested hashes.
|
583
|
+
#
|
584
|
+
# @return [Hash] the hash with the keys as strings instead of symbols.
|
524
585
|
#
|
525
|
-
def self.convert_keys_to_string(value)
|
586
|
+
def self.convert_keys_to_string(value, recursive: true)
|
526
587
|
return unless value
|
527
588
|
result = {}
|
528
589
|
value.each do |key, subvalue|
|
529
|
-
subvalue = Specification.convert_keys_to_string(subvalue) if subvalue.is_a?(Hash)
|
590
|
+
subvalue = Specification.convert_keys_to_string(subvalue) if recursive && subvalue.is_a?(Hash)
|
530
591
|
result[key.to_s] = subvalue
|
531
592
|
end
|
532
593
|
result
|
533
594
|
end
|
534
595
|
|
535
|
-
# Converts the keys of the given hash to a
|
596
|
+
# Converts the keys of the given hash to a symbol.
|
536
597
|
#
|
537
598
|
# @param [Object] value
|
538
|
-
# the value that needs to be stripped from the
|
599
|
+
# the value that needs to be stripped from the Strings.
|
600
|
+
#
|
601
|
+
# @param [Boolean] recursive
|
602
|
+
# whether to convert keys of nested hashes.
|
539
603
|
#
|
540
|
-
# @return [Hash] the hash with the
|
604
|
+
# @return [Hash] the hash with the keys as symbols instead of strings.
|
541
605
|
#
|
542
|
-
def self.convert_keys_to_symbol(value)
|
606
|
+
def self.convert_keys_to_symbol(value, recursive: true)
|
543
607
|
return unless value
|
544
608
|
result = {}
|
545
609
|
value.each do |key, subvalue|
|
546
|
-
subvalue = Specification.convert_keys_to_symbol(subvalue) if subvalue.is_a?(Hash)
|
610
|
+
subvalue = Specification.convert_keys_to_symbol(subvalue) if recursive && subvalue.is_a?(Hash)
|
547
611
|
result[key.to_sym] = subvalue
|
548
612
|
end
|
549
613
|
result
|
@@ -9,6 +9,7 @@ module Pod
|
|
9
9
|
# - standardizing the attributes
|
10
10
|
# - handling multi-platform values
|
11
11
|
# - handle default values
|
12
|
+
# - handle automatic container wrapping of values
|
12
13
|
# - handle inherited values
|
13
14
|
#
|
14
15
|
# This class allows to store the values of the attributes in the
|
@@ -184,6 +185,10 @@ module Pod
|
|
184
185
|
#
|
185
186
|
spec_attr_accessor :script_phases
|
186
187
|
|
188
|
+
# @return [Hash] A hash that contains the scheme configuration.
|
189
|
+
#
|
190
|
+
spec_attr_accessor :scheme
|
191
|
+
|
187
192
|
# @return [Array<String>] A hash where the key represents the
|
188
193
|
# paths of the resources to copy and the values the paths of
|
189
194
|
# the resources that should be copied.
|
@@ -407,6 +412,17 @@ module Pod
|
|
407
412
|
end
|
408
413
|
end
|
409
414
|
|
415
|
+
# Converts the a scheme where keys are strings into symbols.
|
416
|
+
#
|
417
|
+
# @param [Hash] value.
|
418
|
+
# The value of the attribute as specified by the user.
|
419
|
+
#
|
420
|
+
# @return [Hash] the scheme with symbols as keys instead of strings or `nil` if the value is not a hash.
|
421
|
+
#
|
422
|
+
def _prepare_scheme(value)
|
423
|
+
Specification.convert_keys_to_symbol(value, :recursive => false) if value && value.is_a?(Hash)
|
424
|
+
end
|
425
|
+
|
410
426
|
# Ensures that the file patterns of the resource bundles are contained in
|
411
427
|
# an array.
|
412
428
|
#
|
@@ -129,18 +129,35 @@ module Pod
|
|
129
129
|
|
130
130
|
#------------------#
|
131
131
|
|
132
|
-
# @!method
|
132
|
+
# @!method swift_versions=(version)
|
133
133
|
#
|
134
|
-
# The
|
134
|
+
# The versions of Swift that the specification supports. A version of '4' will be treated as
|
135
|
+
# '4.0' by CocoaPods and not '4.1' or '4.2'.
|
136
|
+
#
|
137
|
+
# **Note** The Swift compiler mostly accepts major versions and sometimes will honor minor versions.
|
138
|
+
# While CocoaPods allows specifying a minor or patch version it might not be honored fully by the Swift compiler.
|
139
|
+
#
|
140
|
+
# @example
|
141
|
+
#
|
142
|
+
# spec.swift_versions = ['3.0']
|
135
143
|
#
|
136
144
|
# @example
|
137
145
|
#
|
138
|
-
# spec.
|
146
|
+
# spec.swift_versions = ['3.0', '4.0', '4.2']
|
147
|
+
#
|
148
|
+
# @example
|
139
149
|
#
|
140
|
-
#
|
150
|
+
# spec.swift_version = '3.0'
|
141
151
|
#
|
142
|
-
|
143
|
-
|
152
|
+
# @example
|
153
|
+
#
|
154
|
+
# spec.swift_version = '3.0', '4.0'
|
155
|
+
#
|
156
|
+
# @param [String, Array<String>] swift_versions
|
157
|
+
#
|
158
|
+
root_attribute :swift_versions,
|
159
|
+
:container => Array,
|
160
|
+
:singularize => true
|
144
161
|
|
145
162
|
#-----------------------------------------------------------------------#
|
146
163
|
|
@@ -660,8 +677,21 @@ module Pod
|
|
660
677
|
end
|
661
678
|
end
|
662
679
|
unless version_requirements.all? { |req| req.is_a?(String) }
|
663
|
-
|
680
|
+
version_requirements.each do |requirement|
|
681
|
+
if requirement.is_a?(Hash)
|
682
|
+
if !requirement[:path].nil?
|
683
|
+
raise Informative, 'Podspecs cannot specify the source of dependencies. The `:path` option is not supported.'\
|
684
|
+
' `:path` can be used in the Podfile instead to override global dependencies.'
|
685
|
+
elsif !requirement[:git].nil?
|
686
|
+
raise Informative, 'Podspecs cannot specify the source of dependencies. The `:git` option is not supported.'\
|
687
|
+
' `:git` can be used in the Podfile instead to override global dependencies.'
|
688
|
+
end
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
raise Informative, "Unsupported version requirements. #{version_requirements.inspect} is not valid."
|
664
693
|
end
|
694
|
+
|
665
695
|
attributes_hash['dependencies'] ||= {}
|
666
696
|
attributes_hash['dependencies'][name] = version_requirements
|
667
697
|
end
|
@@ -1230,10 +1260,10 @@ module Pod
|
|
1230
1260
|
#
|
1231
1261
|
# spec.resource_bundles = {
|
1232
1262
|
# 'MapBox' => ['MapView/Map/Resources/*.png'],
|
1233
|
-
# '
|
1263
|
+
# 'MapBoxOtherResources' => ['MapView/Map/OtherResources/*.png']
|
1234
1264
|
# }
|
1235
1265
|
#
|
1236
|
-
# @param [Hash{String=>String}] resource_bundles
|
1266
|
+
# @param [Hash{String=>String}, Hash{String=>Array<String>}] resource_bundles
|
1237
1267
|
# A hash where the keys are the names of the resource bundles
|
1238
1268
|
# and the values are their relative file patterns.
|
1239
1269
|
#
|
@@ -1443,10 +1473,11 @@ module Pod
|
|
1443
1473
|
#
|
1444
1474
|
# @param [Symbol, String] type
|
1445
1475
|
# The test type to use.
|
1476
|
+
#
|
1446
1477
|
attribute :test_type,
|
1447
1478
|
:types => [Symbol, String],
|
1448
1479
|
:multi_platform => false,
|
1449
|
-
:
|
1480
|
+
:spec_types => [:test]
|
1450
1481
|
|
1451
1482
|
# @!method requires_app_host=(flag)
|
1452
1483
|
#
|
@@ -1462,7 +1493,31 @@ module Pod
|
|
1462
1493
|
attribute :requires_app_host,
|
1463
1494
|
:types => [TrueClass, FalseClass],
|
1464
1495
|
:default_value => false,
|
1465
|
-
:
|
1496
|
+
:spec_types => [:test]
|
1497
|
+
|
1498
|
+
SCHEME_KEYS = [:launch_arguments, :environment_variables].freeze
|
1499
|
+
|
1500
|
+
# @!method scheme=(flag)
|
1501
|
+
#
|
1502
|
+
# Specifies the scheme configuration to be used for this specification.
|
1503
|
+
#
|
1504
|
+
# ---
|
1505
|
+
#
|
1506
|
+
# @example
|
1507
|
+
#
|
1508
|
+
# spec.scheme = { :launch_arguments => ['Arg1'] }
|
1509
|
+
#
|
1510
|
+
# @example
|
1511
|
+
#
|
1512
|
+
# spec.scheme = { :launch_arguments => ['Arg1', 'Arg2'], :environment_variables => { 'Key1' => 'Val1'} }
|
1513
|
+
#
|
1514
|
+
# @param [Hash] scheme
|
1515
|
+
# the scheme configuration to be used for this specification.
|
1516
|
+
#
|
1517
|
+
attribute :scheme,
|
1518
|
+
:types => [Hash],
|
1519
|
+
:container => Hash,
|
1520
|
+
:keys => SCHEME_KEYS
|
1466
1521
|
|
1467
1522
|
# Represents a test specification for the library. Here you can place all
|
1468
1523
|
# your tests for your podspec along with the test dependencies.
|
@@ -1486,6 +1541,28 @@ module Pod
|
|
1486
1541
|
subspec
|
1487
1542
|
end
|
1488
1543
|
|
1544
|
+
# Represents an app specification for the library. Here you can place all
|
1545
|
+
# your app source files for your podspec along with the app dependencies.
|
1546
|
+
#
|
1547
|
+
# ---
|
1548
|
+
#
|
1549
|
+
# @example
|
1550
|
+
#
|
1551
|
+
# Pod::Spec.new do |spec|
|
1552
|
+
# spec.name = 'NSAttributedString+CCLFormat'
|
1553
|
+
#
|
1554
|
+
# spec.app_spec do |app_spec|
|
1555
|
+
# app_spec.source_files = 'NSAttributedString+CCLFormat.m'
|
1556
|
+
# app_spec.dependency 'AFNetworking'
|
1557
|
+
# end
|
1558
|
+
# end
|
1559
|
+
#
|
1560
|
+
def app_spec(name = 'App', &block)
|
1561
|
+
appspec = Specification.new(self, name, :app_specification => true, &block)
|
1562
|
+
@subspecs << appspec
|
1563
|
+
appspec
|
1564
|
+
end
|
1565
|
+
|
1489
1566
|
#------------------#
|
1490
1567
|
|
1491
1568
|
# @!method default_subspecs=(subspec_array)
|
@@ -7,6 +7,10 @@ module Pod
|
|
7
7
|
class Attribute
|
8
8
|
require 'active_support/inflector/inflections'
|
9
9
|
|
10
|
+
# Spec types currently supported.
|
11
|
+
#
|
12
|
+
SUPPORTED_SPEC_TYPES = [:library, :app, :test].freeze
|
13
|
+
|
10
14
|
# @return [Symbol] the name of the attribute.
|
11
15
|
#
|
12
16
|
attr_reader :name
|
@@ -31,7 +35,7 @@ module Pod
|
|
31
35
|
|
32
36
|
@multi_platform = options.delete(:multi_platform) { true }
|
33
37
|
@root_only = options.delete(:root_only) { false }
|
34
|
-
@
|
38
|
+
@spec_types = options.delete(:spec_types) { SUPPORTED_SPEC_TYPES }
|
35
39
|
@inherited = options.delete(:inherited) { @root_only }
|
36
40
|
@required = options.delete(:required) { false }
|
37
41
|
@singularize = options.delete(:singularize) { false }
|
@@ -46,6 +50,9 @@ module Pod
|
|
46
50
|
unless options.empty?
|
47
51
|
raise StandardError, "Unrecognized options: #{options} for #{self}"
|
48
52
|
end
|
53
|
+
unless (@spec_types - SUPPORTED_SPEC_TYPES).empty?
|
54
|
+
raise StandardError, "Unrecognized spec type option: #{@spec_types} for #{self}"
|
55
|
+
end
|
49
56
|
end
|
50
57
|
|
51
58
|
# @return [String] A string representation suitable for UI.
|
@@ -126,7 +133,7 @@ module Pod
|
|
126
133
|
# test specifications.
|
127
134
|
#
|
128
135
|
def test_only?
|
129
|
-
@
|
136
|
+
@spec_types == [:test]
|
130
137
|
end
|
131
138
|
|
132
139
|
# @return [Bool] whether the attribute is multi-platform and should
|
@@ -26,13 +26,15 @@ module Pod
|
|
26
26
|
platforms = Hash[available_platforms.map { |p| [p.name.to_s, p.deployment_target && p.deployment_target.to_s] }]
|
27
27
|
hash['platforms'] = platforms
|
28
28
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
specs_by_type = subspecs.group_by(&:spec_type)
|
30
|
+
all_appspecs = specs_by_type[:app] || []
|
31
|
+
all_testspecs = specs_by_type[:test] || []
|
32
|
+
all_subspecs = specs_by_type[:library] || []
|
33
|
+
|
34
|
+
hash['testspecs'] = all_testspecs.map(&:to_hash) unless all_testspecs.empty?
|
35
|
+
hash['appspecs'] = all_appspecs.map(&:to_hash) unless all_appspecs.empty?
|
36
|
+
hash['subspecs'] = all_subspecs.map(&:to_hash) unless all_subspecs.empty?
|
37
|
+
|
36
38
|
hash
|
37
39
|
end
|
38
40
|
end
|
@@ -61,22 +63,33 @@ module Pod
|
|
61
63
|
#
|
62
64
|
# @return [Specification] the specification
|
63
65
|
#
|
64
|
-
def self.from_hash(hash, parent = nil)
|
65
|
-
spec = Spec.new(parent)
|
66
|
+
def self.from_hash(hash, parent = nil, test_specification: false, app_specification: false)
|
66
67
|
attributes_hash = hash.dup
|
68
|
+
spec = Spec.new(parent, nil, test_specification, :app_specification => app_specification)
|
67
69
|
subspecs = attributes_hash.delete('subspecs')
|
68
70
|
testspecs = attributes_hash.delete('testspecs')
|
69
|
-
|
71
|
+
appspecs = attributes_hash.delete('appspecs')
|
72
|
+
|
73
|
+
## backwards compatibility with 1.3.0
|
70
74
|
spec.test_specification = !attributes_hash['test_type'].nil?
|
71
|
-
|
72
|
-
|
75
|
+
|
76
|
+
testspecs.each { |ts| ts['test_specification'] = true; } unless testspecs.nil?
|
77
|
+
appspecs.each { |ts| ts['app_specification'] = true; } unless appspecs.nil?
|
78
|
+
|
79
|
+
spec.attributes_hash = attributes_hash
|
80
|
+
spec.subspecs.concat(subspecs_from_hash(spec, subspecs, false, false))
|
81
|
+
spec.subspecs.concat(subspecs_from_hash(spec, testspecs, true, false))
|
82
|
+
spec.subspecs.concat(subspecs_from_hash(spec, appspecs, false, true))
|
83
|
+
|
73
84
|
spec
|
74
85
|
end
|
75
86
|
|
76
|
-
def self.subspecs_from_hash(spec, subspecs)
|
87
|
+
def self.subspecs_from_hash(spec, subspecs, test_specification, app_specification)
|
77
88
|
return [] if subspecs.nil?
|
78
89
|
subspecs.map do |s_hash|
|
79
|
-
Specification.from_hash(s_hash, spec
|
90
|
+
Specification.from_hash(s_hash, spec,
|
91
|
+
:test_specification => test_specification,
|
92
|
+
:app_specification => app_specification)
|
80
93
|
end
|
81
94
|
end
|
82
95
|
|
@@ -401,8 +401,8 @@ module Pod
|
|
401
401
|
keys = script_phase.keys
|
402
402
|
unrecognized_keys = keys - Specification::ALL_SCRIPT_PHASE_KEYS
|
403
403
|
unless unrecognized_keys.empty?
|
404
|
-
results.add_error('script_phases', "Unrecognized
|
405
|
-
"Available options are `#{Specification::ALL_SCRIPT_PHASE_KEYS}`.")
|
404
|
+
results.add_error('script_phases', "Unrecognized option(s) `#{unrecognized_keys.join(', ')}` in script phase `#{script_phase[:name]}`. " \
|
405
|
+
"Available options are `#{Specification::ALL_SCRIPT_PHASE_KEYS.join(', ')}`.")
|
406
406
|
end
|
407
407
|
missing_required_keys = Specification::SCRIPT_PHASE_REQUIRED_KEYS - keys
|
408
408
|
unless missing_required_keys.empty?
|
@@ -410,7 +410,24 @@ module Pod
|
|
410
410
|
end
|
411
411
|
unless Specification::EXECUTION_POSITION_KEYS.include?(script_phase[:execution_position])
|
412
412
|
results.add_error('script_phases', "Invalid execution position value `#{script_phase[:execution_position]}` in shell script `#{script_phase[:name]}`. " \
|
413
|
-
"Available options are `#{Specification::EXECUTION_POSITION_KEYS}`.")
|
413
|
+
"Available options are `#{Specification::EXECUTION_POSITION_KEYS.join(', ')}`.")
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
# Performs validation related to the `scheme` attribute.
|
419
|
+
#
|
420
|
+
def _validate_scheme(s)
|
421
|
+
unless s.empty?
|
422
|
+
if consumer.spec.subspec? && consumer.spec.library_specification?
|
423
|
+
results.add_error('scheme', 'Scheme configuration is not currently supported for subspecs.')
|
424
|
+
return
|
425
|
+
end
|
426
|
+
if s.key?(:launch_arguments) && !s[:launch_arguments].is_a?(Array)
|
427
|
+
results.add_error('scheme', 'Expected an array for key `launch_arguments`.')
|
428
|
+
end
|
429
|
+
if s.key?(:environment_variables) && !s[:environment_variables].is_a?(Hash)
|
430
|
+
results.add_error('scheme', 'Expected a hash for key `environment_variables`.')
|
414
431
|
end
|
415
432
|
end
|
416
433
|
end
|
@@ -40,12 +40,25 @@ module Pod
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
# @
|
43
|
+
# @deprecated in favor of #swift_versions
|
44
|
+
#
|
45
|
+
# @return [Version] The Swift version specified by the specification.
|
44
46
|
#
|
45
47
|
def swift_version
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
swift_versions.last
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Array<Version>] The Swift versions supported by the specification.
|
52
|
+
#
|
53
|
+
def swift_versions
|
54
|
+
@swift_versions ||= begin
|
55
|
+
swift_versions = Array(attributes_hash['swift_versions'])
|
56
|
+
# Pre 1.7.0, the DSL was singularized as it supported only a single version of Swift. In 1.7.0 the DSL
|
57
|
+
# is now pluralized always and a specification can support multiple versions of Swift. This ensures
|
58
|
+
# we parse the old JSON serialized format and include it as part of the Swift versions supported.
|
59
|
+
swift_versions << attributes_hash['swift_version'] unless attributes_hash['swift_version'].nil?
|
60
|
+
swift_versions.map { |swift_version| Version.new(swift_version) }.uniq.sort
|
61
|
+
end
|
49
62
|
end
|
50
63
|
|
51
64
|
# @return [Requirement] The CocoaPods version required to use the specification.
|
@@ -221,7 +221,9 @@ module Pod
|
|
221
221
|
return 1 if rhs.nil?
|
222
222
|
end
|
223
223
|
|
224
|
-
|
224
|
+
if comparison = lhs <=> rhs
|
225
|
+
return comparison
|
226
|
+
end
|
225
227
|
return 1 if lhs.is_a?(String) && rhs.is_a?(Numeric)
|
226
228
|
return -1 if lhs.is_a?(Numeric) && rhs.is_a?(String)
|
227
229
|
end
|
@@ -239,6 +239,8 @@ module Pod
|
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
242
|
+
public
|
243
|
+
|
242
244
|
# Sorts an array according to the string representation of it values.
|
243
245
|
# This method allows to sort arrays which contains strings or hashes.
|
244
246
|
#
|
@@ -259,6 +261,8 @@ module Pod
|
|
259
261
|
end.map(&:first)
|
260
262
|
end
|
261
263
|
|
264
|
+
private
|
265
|
+
|
262
266
|
# Returns the string representation of a value useful for sorting.
|
263
267
|
#
|
264
268
|
# @param [String, Symbol, Array, Hash] value
|
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.7.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-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- LICENSE
|
88
88
|
- README.md
|
89
89
|
- lib/cocoapods-core.rb
|
90
|
+
- lib/cocoapods-core/cdn_source.rb
|
90
91
|
- lib/cocoapods-core/core_ui.rb
|
91
92
|
- lib/cocoapods-core/dependency.rb
|
92
93
|
- lib/cocoapods-core/gem_version.rb
|