cocoapods-modularization 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/cocoapods-modularization/command/install.rb +98 -0
- data/lib/cocoapods-modularization/command/mod/add.rb +97 -0
- data/lib/cocoapods-modularization/command/mod/base.rb +35 -0
- data/lib/cocoapods-modularization/command/mod/binary.rb +82 -0
- data/lib/cocoapods-modularization/command/mod/config.rb +51 -0
- data/lib/cocoapods-modularization/command/mod/create.rb +34 -0
- data/lib/cocoapods-modularization/command/mod/inspect.rb +26 -0
- data/lib/cocoapods-modularization/command/mod/source.rb +81 -0
- data/lib/cocoapods-modularization/command/mod/sync.rb +29 -0
- data/lib/cocoapods-modularization/command/mod/update.rb +64 -0
- data/lib/cocoapods-modularization/command/mod.rb +28 -0
- data/lib/cocoapods-modularization/command.rb +2 -0
- data/lib/cocoapods-modularization/gem_version.rb +3 -0
- data/lib/cocoapods-modularization/generate/configuration.rb +364 -0
- data/lib/cocoapods-modularization/generate/installer.rb +388 -0
- data/lib/cocoapods-modularization/generate/podfile_generator.rb +398 -0
- data/lib/cocoapods-modularization/generate.rb +7 -0
- data/lib/cocoapods-modularization/meta/meta_accessor.rb +134 -0
- data/lib/cocoapods-modularization/meta/meta_constants.rb +135 -0
- data/lib/cocoapods-modularization/meta/meta_reference.rb +255 -0
- data/lib/cocoapods-modularization/meta.rb +7 -0
- data/lib/cocoapods-modularization/private/private_cache.rb +277 -0
- data/lib/cocoapods-modularization/private.rb +5 -0
- data/lib/cocoapods-modularization.rb +1 -0
- data/lib/cocoapods_plugin.rb +1 -0
- metadata +96 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Generate
|
5
|
+
# Generates podfiles for pod specifications given a configuration.
|
6
|
+
#
|
7
|
+
class PodfileGenerator
|
8
|
+
# @return [Configuration]
|
9
|
+
# the configuration used when generating podfiles
|
10
|
+
#
|
11
|
+
attr_reader :configuration
|
12
|
+
|
13
|
+
def initialize(configuration)
|
14
|
+
@configuration = configuration
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash<Specification, Podfile>]
|
18
|
+
# a hash of specifications to generated podfiles
|
19
|
+
#
|
20
|
+
def podfiles_by_spec
|
21
|
+
Hash[configuration.podspecs.map do |spec|
|
22
|
+
[spec, podfile_for_spec(spec)]
|
23
|
+
end]
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Podfile] a podfile suitable for installing the given spec
|
27
|
+
#
|
28
|
+
# @param [Specification] spec
|
29
|
+
#
|
30
|
+
def podfile_for_spec(spec)
|
31
|
+
generator = self
|
32
|
+
dir = configuration.gen_dir_for_pod(spec.name)
|
33
|
+
project_name = configuration.project_name_for_spec(spec)
|
34
|
+
|
35
|
+
Pod::Podfile.new do
|
36
|
+
project "#{project_name}.xcodeproj"
|
37
|
+
workspace "#{spec.name}.xcworkspace"
|
38
|
+
|
39
|
+
plugin 'cocoapods-modularization'
|
40
|
+
|
41
|
+
install! 'cocoapods', generator.installation_options
|
42
|
+
|
43
|
+
generator.podfile_plugins.each do |name, options|
|
44
|
+
plugin(*[name, options].compact)
|
45
|
+
end
|
46
|
+
|
47
|
+
use_frameworks!(generator.use_frameworks_value)
|
48
|
+
|
49
|
+
if (supported_swift_versions = generator.supported_swift_versions)
|
50
|
+
supports_swift_versions(supported_swift_versions)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Explicitly set sources
|
54
|
+
generator.configuration.sources.each do |source_url|
|
55
|
+
source(source_url)
|
56
|
+
end
|
57
|
+
|
58
|
+
self.defined_in_file = dir.join('CocoaPods.podfile.yaml')
|
59
|
+
|
60
|
+
test_specs = spec.recursive_subspecs.select(&:test_specification?)
|
61
|
+
app_specs = if spec.respond_to?(:app_specification?)
|
62
|
+
spec.recursive_subspecs.select(&:app_specification?)
|
63
|
+
else
|
64
|
+
[]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Stick all of the transitive dependencies in an abstract target.
|
68
|
+
# This allows us to force CocoaPods to use the versions / sources / external sources
|
69
|
+
# that we want.
|
70
|
+
# By using an abstract target,
|
71
|
+
abstract_target 'Transitive Dependencies' do
|
72
|
+
pods_for_transitive_dependencies = [spec.name]
|
73
|
+
.concat(test_specs.map(&:name))
|
74
|
+
.concat(test_specs.flat_map { |ts| ts.dependencies.flat_map(&:name) })
|
75
|
+
.concat(app_specs.map(&:name))
|
76
|
+
.concat(app_specs.flat_map { |as| as.dependencies.flat_map(&:name) })
|
77
|
+
|
78
|
+
dependencies = generator
|
79
|
+
.transitive_dependencies_by_pod
|
80
|
+
.values_at(*pods_for_transitive_dependencies)
|
81
|
+
.compact
|
82
|
+
.flatten(1)
|
83
|
+
.uniq
|
84
|
+
.sort_by(&:name)
|
85
|
+
.reject { |d| d.root_name == spec.root.name }
|
86
|
+
|
87
|
+
dependencies.each do |dependency|
|
88
|
+
pod_args = generator.pod_args_for_dependency(self, dependency)
|
89
|
+
pod(*pod_args)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Add platform-specific concrete targets that inherit the
|
94
|
+
# `pod` declaration for the local pod.
|
95
|
+
spec_platform_names = spec.available_platforms.map(&:string_name).flatten.each.reject do |platform_name|
|
96
|
+
!generator.configuration.platforms.nil? && !generator.configuration.platforms.include?(platform_name.downcase)
|
97
|
+
end
|
98
|
+
|
99
|
+
spec_platform_names.sort.each do |platform_name|
|
100
|
+
target "App-#{platform_name}" do
|
101
|
+
current_target_definition.swift_version = generator.swift_version if generator.swift_version
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# this block has to come _before_ inhibit_all_warnings! / use_modular_headers!,
|
106
|
+
# and the local `pod` declaration
|
107
|
+
current_target_definition.instance_exec do
|
108
|
+
transitive_dependencies = children.find { |c| c.name == 'Transitive Dependencies' }
|
109
|
+
|
110
|
+
%w[use_modular_headers inhibit_warnings].each do |key|
|
111
|
+
value = transitive_dependencies.send(:internal_hash).delete(key)
|
112
|
+
next if value.blank?
|
113
|
+
set_hash_value(key, value)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
inhibit_all_warnings! if generator.inhibit_all_warnings?
|
118
|
+
use_modular_headers! if generator.use_modular_headers?
|
119
|
+
|
120
|
+
# This is the pod declaration for the local pod,
|
121
|
+
# it will be inherited by the concrete target definitions below
|
122
|
+
pod_options = generator.dependency_compilation_kwargs(spec.name)
|
123
|
+
pod_options[:path] = spec.defined_in_file.relative_path_from(dir).to_s
|
124
|
+
{ testspecs: test_specs, appspecs: app_specs }.each do |key, specs|
|
125
|
+
pod_options[key] = specs.map { |s| s.name.sub(%r{^#{Regexp.escape spec.root.name}/}, '') }.sort unless specs.empty?
|
126
|
+
end
|
127
|
+
|
128
|
+
pod spec.name, **pod_options
|
129
|
+
|
130
|
+
# Implement local-sources option to set up dependencies to podspecs in the local filesystem.
|
131
|
+
next if generator.configuration.local_sources.empty?
|
132
|
+
generator.transitive_local_dependencies(spec, generator.configuration.local_sources).sort_by(&:first).each do |dependency, podspec_file|
|
133
|
+
pod_options = generator.dependency_compilation_kwargs(dependency.name)
|
134
|
+
pod_options[:path] = if podspec_file[0] == '/' # absolute path
|
135
|
+
podspec_file
|
136
|
+
else
|
137
|
+
'../../' + podspec_file
|
138
|
+
end
|
139
|
+
pod dependency.name, **pod_options
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def transitive_local_dependencies(spec, paths, found_podspecs: {}, include_non_library_subspecs: true)
|
145
|
+
if include_non_library_subspecs
|
146
|
+
non_library_specs = spec.recursive_subspecs.select do |ss|
|
147
|
+
ss.test_specification? || (ss.respond_to?(:app_specification?) && ss.app_specification?)
|
148
|
+
end
|
149
|
+
non_library_specs.each do |subspec|
|
150
|
+
transitive_local_dependencies(subspec, paths, found_podspecs: found_podspecs, include_non_library_subspecs: false)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
spec.dependencies.each do |dependency|
|
154
|
+
next if found_podspecs.key?(dependency)
|
155
|
+
found_podspec_file = nil
|
156
|
+
name = dependency.name.split('/')[0]
|
157
|
+
paths.each do |path|
|
158
|
+
podspec_file = File.join(path, name + '.podspec')
|
159
|
+
next unless File.file?(podspec_file)
|
160
|
+
found_podspec_file = podspec_file
|
161
|
+
break
|
162
|
+
end
|
163
|
+
next unless found_podspec_file
|
164
|
+
found_podspecs[dependency] = found_podspec_file.sub(%r{\A\./}, '')
|
165
|
+
transitive_local_dependencies(Pod::Specification.from_file(found_podspec_file), paths, found_podspecs: found_podspecs)
|
166
|
+
end
|
167
|
+
found_podspecs
|
168
|
+
end
|
169
|
+
|
170
|
+
# @return [Boolean]
|
171
|
+
# whether all warnings should be inhibited
|
172
|
+
#
|
173
|
+
def inhibit_all_warnings?
|
174
|
+
return false unless configuration.use_podfile?
|
175
|
+
target_definition_list.all? do |target_definition|
|
176
|
+
target_definition.send(:inhibit_warnings_hash)['all']
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# @return [Boolean]
|
181
|
+
# whether all pods should use modular headers
|
182
|
+
#
|
183
|
+
def use_modular_headers?
|
184
|
+
if configuration.use_podfile? && configuration.use_modular_headers?
|
185
|
+
raise Informative, 'Conflicting `use_modular_headers` option. Cannot specify both `--use-modular-headers` and `--use-podfile`.'
|
186
|
+
end
|
187
|
+
|
188
|
+
if configuration.use_podfile?
|
189
|
+
target_definition_list.all? do |target_definition|
|
190
|
+
target_definition.use_modular_headers_hash['all']
|
191
|
+
end
|
192
|
+
else
|
193
|
+
configuration.use_modular_headers?
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# @return [Boolean, Hash]
|
198
|
+
# the value to use for `use_frameworks!` DSL directive
|
199
|
+
#
|
200
|
+
def use_frameworks_value
|
201
|
+
return configuration.use_frameworks? unless configuration.use_podfile?
|
202
|
+
use_framework_values = target_definition_list.map do |target_definition|
|
203
|
+
if target_definition.respond_to?(:build_type) # CocoaPods >= 1.9
|
204
|
+
build_type = target_definition.build_type
|
205
|
+
if build_type.static_library?
|
206
|
+
false
|
207
|
+
else
|
208
|
+
{ linkage: build_type == BuildType.dynamic_framework ? :dynamic : :static }
|
209
|
+
end
|
210
|
+
else
|
211
|
+
target_definition.uses_frameworks?
|
212
|
+
end
|
213
|
+
end.uniq
|
214
|
+
raise Informative, 'Multiple use_frameworks! values detected in user Podfile.' unless use_framework_values.count == 1
|
215
|
+
use_framework_values.first
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [Hash]
|
219
|
+
# a hash with "compilation"-related dependency options for the `pod` DSL method
|
220
|
+
#
|
221
|
+
# @param [String] pod_name
|
222
|
+
#
|
223
|
+
def dependency_compilation_kwargs(pod_name)
|
224
|
+
options = {}
|
225
|
+
options[:inhibit_warnings] = inhibit_warnings?(pod_name) if inhibit_warnings?(pod_name) != inhibit_all_warnings?
|
226
|
+
options[:modular_headers] = modular_headers?(pod_name) if modular_headers?(pod_name) != use_modular_headers?
|
227
|
+
options
|
228
|
+
end
|
229
|
+
|
230
|
+
# @return [Hash<String,Array<Dependency>>]
|
231
|
+
# the transitive dependency objects dependency upon by each pod
|
232
|
+
#
|
233
|
+
def transitive_dependencies_by_pod
|
234
|
+
return {} unless configuration.use_lockfile?
|
235
|
+
@transitive_dependencies_by_pod ||= begin
|
236
|
+
lda = ::Pod::Installer::Analyzer::LockingDependencyAnalyzer
|
237
|
+
dependency_graph = Molinillo::DependencyGraph.new
|
238
|
+
configuration.lockfile.dependencies.each do |dependency|
|
239
|
+
dependency_graph.add_vertex(dependency.name, dependency, true)
|
240
|
+
end
|
241
|
+
add_to_dependency_graph = if lda.method(:add_to_dependency_graph).parameters.size == 4 # CocoaPods < 1.6.0
|
242
|
+
->(pod) { lda.add_to_dependency_graph(pod, [], dependency_graph, []) }
|
243
|
+
else
|
244
|
+
->(pod) { lda.add_to_dependency_graph(pod, [], dependency_graph, [], Set.new) }
|
245
|
+
end
|
246
|
+
configuration.lockfile.internal_data['PODS'].each(&add_to_dependency_graph)
|
247
|
+
|
248
|
+
transitive_dependencies_by_pod = Hash.new { |hash, key| hash[key] = [] }
|
249
|
+
dependency_graph.each do |v|
|
250
|
+
transitive_dependencies_by_pod[v.name].concat v.recursive_successors.map(&:payload) << v.payload
|
251
|
+
end
|
252
|
+
|
253
|
+
transitive_dependencies_by_pod.each_value(&:uniq!)
|
254
|
+
transitive_dependencies_by_pod
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# @return [Hash<String,Array<Dependency>>]
|
259
|
+
# dependencies in the podfile grouped by root name
|
260
|
+
#
|
261
|
+
def podfile_dependencies
|
262
|
+
return {} unless configuration.use_podfile?
|
263
|
+
@podfile_dependencies ||= configuration.podfile.dependencies.group_by(&:root_name).tap { |h| h.default = [] }
|
264
|
+
end
|
265
|
+
|
266
|
+
# @return [Hash<String,String>]
|
267
|
+
# versions in the lockfile keyed by pod name
|
268
|
+
#
|
269
|
+
def lockfile_versions
|
270
|
+
return {} unless configuration.use_lockfile_versions?
|
271
|
+
@lockfile_versions ||= Hash[configuration.lockfile.pod_names.map { |name| [name, "= #{configuration.lockfile.version(name)}"] }]
|
272
|
+
end
|
273
|
+
|
274
|
+
# @return [Hash<String,Array<Dependency>>]
|
275
|
+
# returns the arguments that should be passed to the Podfile DSL's
|
276
|
+
# `pod` method for the given podfile and dependency
|
277
|
+
#
|
278
|
+
# @param [Podfile] podfile
|
279
|
+
#
|
280
|
+
# @param [Dependency] dependency
|
281
|
+
#
|
282
|
+
def pod_args_for_dependency(podfile, dependency)
|
283
|
+
dependency = podfile_dependencies[dependency.root_name]
|
284
|
+
.map { |dep| dep.dup.tap { |d| d.name = dependency.name } }
|
285
|
+
.push(dependency)
|
286
|
+
.reduce(&:merge)
|
287
|
+
|
288
|
+
options = dependency_compilation_kwargs(dependency.name)
|
289
|
+
options[:source] = dependency.podspec_repo if dependency.podspec_repo
|
290
|
+
options.update(dependency.external_source) if dependency.external_source
|
291
|
+
%i[path podspec].each do |key|
|
292
|
+
next unless (path = options[key])
|
293
|
+
options[key] = Pathname(path)
|
294
|
+
.expand_path(configuration.podfile.defined_in_file.dirname)
|
295
|
+
.relative_path_from(podfile.defined_in_file.dirname)
|
296
|
+
.to_s
|
297
|
+
end
|
298
|
+
args = [dependency.name]
|
299
|
+
if dependency.external_source.nil?
|
300
|
+
requirements = dependency.requirement.as_list
|
301
|
+
if (version = lockfile_versions[dependency.name])
|
302
|
+
requirements << version
|
303
|
+
end
|
304
|
+
args.concat requirements.uniq
|
305
|
+
end
|
306
|
+
args << options unless options.empty?
|
307
|
+
args
|
308
|
+
end
|
309
|
+
|
310
|
+
def swift_version
|
311
|
+
@swift_version ||= target_definition_list.map(&:swift_version).compact.max
|
312
|
+
end
|
313
|
+
|
314
|
+
def supported_swift_versions
|
315
|
+
return unless configuration.use_podfile?
|
316
|
+
return if target_definition_list.empty?
|
317
|
+
return unless target_definition_list.first.respond_to?(:swift_version_requirements)
|
318
|
+
target_definition_list.reduce(nil) do |supported_swift_versions, target_definition|
|
319
|
+
target_swift_versions = target_definition.swift_version_requirements
|
320
|
+
next supported_swift_versions unless target_swift_versions
|
321
|
+
Array(target_swift_versions) | Array(supported_swift_versions)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def installation_options
|
326
|
+
installation_options = {
|
327
|
+
deterministic_uuids: configuration.deterministic_uuids?,
|
328
|
+
share_schemes_for_development_pods: configuration.share_schemes_for_development_pods?,
|
329
|
+
warn_for_multiple_pod_sources: configuration.warn_for_multiple_pod_sources?
|
330
|
+
}
|
331
|
+
|
332
|
+
if Pod::Installer::InstallationOptions.all_options.include?('generate_multiple_pod_projects')
|
333
|
+
installation_options[:generate_multiple_pod_projects] = configuration.generate_multiple_pod_projects?
|
334
|
+
end
|
335
|
+
|
336
|
+
if Pod::Installer::InstallationOptions.all_options.include?('incremental_installation')
|
337
|
+
installation_options[:incremental_installation] = configuration.incremental_installation?
|
338
|
+
end
|
339
|
+
|
340
|
+
installation_options
|
341
|
+
end
|
342
|
+
|
343
|
+
def podfile_plugins
|
344
|
+
configuration.podfile_plugins.merge('cocoapods-disable-podfile-validations' => { 'no_abstract_only_pods' => true }) do |_key, old_value, new_value|
|
345
|
+
old_value.merge(new_value)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
private
|
350
|
+
|
351
|
+
# @return [Array<Podfile::TargetDefinition>]
|
352
|
+
# a list of all target definitions to consider from the podfile
|
353
|
+
#
|
354
|
+
def target_definition_list
|
355
|
+
return [] unless configuration.use_podfile?
|
356
|
+
@target_definition_list ||= begin
|
357
|
+
list = configuration.podfile.target_definition_list
|
358
|
+
list.reject!(&:abstract?) unless list.all?(&:abstract?)
|
359
|
+
list
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
# @return [Boolean]
|
364
|
+
# whether warnings should be inhibited for the given pod
|
365
|
+
#
|
366
|
+
# @param [String] pod_name
|
367
|
+
#
|
368
|
+
def inhibit_warnings?(pod_name)
|
369
|
+
return false unless configuration.use_podfile?
|
370
|
+
target_definitions_for_pod(pod_name).all? do |target_definition|
|
371
|
+
target_definition.inhibits_warnings_for_pod?(pod_name)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# @return [Boolean]
|
376
|
+
# whether modular headers should be enabled for the given pod
|
377
|
+
#
|
378
|
+
# @param [String] pod_name
|
379
|
+
#
|
380
|
+
def modular_headers?(pod_name)
|
381
|
+
return true if configuration.use_modular_headers?
|
382
|
+
return false unless configuration.use_podfile?
|
383
|
+
target_definitions_for_pod(pod_name).all? do |target_definition|
|
384
|
+
target_definition.build_pod_as_module?(pod_name)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# @return [Podfile::TargetDefinition]
|
389
|
+
#
|
390
|
+
# @param [String] pod_name
|
391
|
+
#
|
392
|
+
def target_definitions_for_pod(pod_name)
|
393
|
+
target_definitions = target_definition_list.reject { |td| td.dependencies.none? { |d| d.name == pod_name } }
|
394
|
+
target_definitions.empty? ? target_definition_list : target_definitions
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module Pod
|
2
|
+
module Generate
|
3
|
+
autoload :Configuration, 'cocoapods-modularization/generate/configuration'
|
4
|
+
autoload :Installer, 'cocoapods-modularization/generate/installer'
|
5
|
+
autoload :PodfileGenerator, 'cocoapods-modularization/generate/podfile_generator'
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'cocoapods-modularization/private'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
module Meta
|
6
|
+
module MetaAccessor
|
7
|
+
class << self
|
8
|
+
def edit_meta
|
9
|
+
meta_hash = YAML.load_file(MetaConstants.meta_path)
|
10
|
+
|
11
|
+
yield meta_hash
|
12
|
+
|
13
|
+
File::open(MetaConstants.meta_path, "w") { |io| io.puts meta_hash.to_yaml }
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_dep(key, binary, version)
|
17
|
+
edit_data(key) do |meta|
|
18
|
+
dep_map = Hash[
|
19
|
+
MetaConstants.version_key => version,
|
20
|
+
MetaConstants.binary_key => binary || true,
|
21
|
+
MetaConstants.source_key => binary ? Private::PrivateCache.binary_repo_url : Private::PrivateCache.source_repo_url,
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
edit_podfile_local(key) do |meta|
|
26
|
+
dep_map = Hash[
|
27
|
+
MetaConstants.binary_key => binary || true,
|
28
|
+
MetaConstants.local_key => false,
|
29
|
+
MetaConstants.local_path_key => Private::PrivateCache.read_local_path(key)
|
30
|
+
]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_dep(key, version)
|
35
|
+
edit_data(key) { |meta_data| meta_data[MetaConstants.version_key] = version }
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_dep(key)
|
39
|
+
edit_data(key) do |meta|
|
40
|
+
meta.delete(key)
|
41
|
+
end
|
42
|
+
|
43
|
+
edit_podfile_local(nil) do |meta|
|
44
|
+
meta.delete(key)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_source(key)
|
49
|
+
edit_podfile_local(key) { |meta_data| meta_data[MetaConstants.binary_key] = false }
|
50
|
+
end
|
51
|
+
|
52
|
+
def remove_source(key)
|
53
|
+
edit_podfile_local(key) { |meta_data| meta_data[MetaConstants.binary_key] = true }
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_binary(key)
|
57
|
+
edit_podfile_local(key) { |meta_data| meta_data[MetaConstants.binary_key] = true }
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_binary(key)
|
61
|
+
edit_podfile_local(key) { |meta_data| meta_data[MetaConstants.binary_key] = false }
|
62
|
+
end
|
63
|
+
|
64
|
+
def sources
|
65
|
+
MetaConstants.read_data.select { |key, value| !value[MetaConstants.binary_key] }.keys if MetaConstants.read_data.kind_of?(Hash)
|
66
|
+
end
|
67
|
+
|
68
|
+
def binaries
|
69
|
+
MetaConstants.read_data.select { |key, value| value[MetaConstants.binary_key] }.keys if MetaConstants.read_data.kind_of?(Hash)
|
70
|
+
end
|
71
|
+
|
72
|
+
def dependencies
|
73
|
+
MetaConstants.dependencies
|
74
|
+
end
|
75
|
+
|
76
|
+
def local_path(key)
|
77
|
+
meta_data = MetaConstants.read_data[key] if MetaConstants.read_data.kind_of?(Hash)
|
78
|
+
return meta_data[MetaConstants.local_path_key] if meta_data.kind_of?(Hash)
|
79
|
+
end
|
80
|
+
|
81
|
+
def version(key)
|
82
|
+
meta_data = MetaConstants.read_data[key] if MetaConstants.read_data.kind_of?(Hash)
|
83
|
+
return meta_data[MetaConstants.version_key] if meta_data.kind_of?(Hash)
|
84
|
+
end
|
85
|
+
|
86
|
+
def set_local_path(key, value)
|
87
|
+
# edit data
|
88
|
+
edit_podfile_local(key) do |meta_data|
|
89
|
+
meta_data[MetaConstants.local_key] = true
|
90
|
+
meta_data[MetaConstants.local_path_key] = value
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def cache_local_path(key, value)
|
95
|
+
edit_podfile_local(key) do |meta_data|
|
96
|
+
meta_data[MetaConstants.local_path_key] = value
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def remove_local_path(key)
|
101
|
+
edit_podfile_local(key) do |meta_data|
|
102
|
+
meta_data[MetaConstants.local_key] = false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def edit_podfile_local(key)
|
107
|
+
_edit_data(key, MetaConstants.podfile_local_path) { |e| yield e }
|
108
|
+
end
|
109
|
+
|
110
|
+
def edit_data(key)
|
111
|
+
_edit_data(key, MetaConstants.data_path) { |e| yield e }
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
def _edit_data(key, path)
|
116
|
+
raise "#{path} not found" unless File.exists?(path)
|
117
|
+
|
118
|
+
data_hash = MetaConstants.generate_yml_to_hash(path)
|
119
|
+
raise "#{key} illegal" unless key.kind_of?(String)
|
120
|
+
|
121
|
+
meta_data = data_hash[key]
|
122
|
+
|
123
|
+
if meta_data.kind_of?(Hash)
|
124
|
+
yield meta_data
|
125
|
+
else
|
126
|
+
data_hash[key] = yield Hash.new
|
127
|
+
end
|
128
|
+
|
129
|
+
File::open(path, "w") { |io| io.puts data_hash.to_yaml }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Pod
|
2
|
+
module Meta
|
3
|
+
class MetaConstants
|
4
|
+
class << self
|
5
|
+
require 'yaml'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
def generate_yml_to_hash(path)
|
9
|
+
return Hash.new unless File.exists?(path)
|
10
|
+
_hash = YAML.load_file(path)
|
11
|
+
if _hash.kind_of?(Hash)
|
12
|
+
_hash
|
13
|
+
else
|
14
|
+
Hash.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def dependencies
|
19
|
+
generate_yml_to_hash(data_path).keys
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_data(enable_branch = false)
|
23
|
+
# read data
|
24
|
+
data_hash = generate_yml_to_hash(data_path)
|
25
|
+
|
26
|
+
# read Podfile.yml
|
27
|
+
podfile_local_hash = generate_yml_to_hash(podfile_local_path)
|
28
|
+
|
29
|
+
# cache branch if local_path is set
|
30
|
+
unless enable_branch
|
31
|
+
branch_caches = Array.new
|
32
|
+
podfile_local_hash.each do |key, value|
|
33
|
+
next unless value.kind_of?(Hash)
|
34
|
+
local = value[local_key]
|
35
|
+
next unless local
|
36
|
+
|
37
|
+
local_path = value[local_path_key]
|
38
|
+
next unless local_path.kind_of?(String)
|
39
|
+
|
40
|
+
branch_cache = Pod::Private::PrivateCache::BranchCache.new(key, local_path)
|
41
|
+
branch_caches << branch_cache
|
42
|
+
end
|
43
|
+
|
44
|
+
Pod::Private::PrivateCache.cache_branch(branch_caches)
|
45
|
+
end
|
46
|
+
|
47
|
+
# merge local data and remote data
|
48
|
+
merged_data = Hash.new
|
49
|
+
data_hash.each do |key, value|
|
50
|
+
# check value
|
51
|
+
unless value.kind_of?(Hash)
|
52
|
+
UI.puts "data not found in data.yaml with key: #{key}"
|
53
|
+
next
|
54
|
+
end
|
55
|
+
|
56
|
+
# check value in local podfile
|
57
|
+
local_data_value = podfile_local_hash[key]
|
58
|
+
unless value.kind_of?(Hash)
|
59
|
+
UI.puts "data not found in Podfile.yaml with key: #{key}"
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
if local_data_value.kind_of?(Hash)
|
64
|
+
merged_data[key] = value.merge(local_data_value)
|
65
|
+
else
|
66
|
+
merged_data[key] = value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
merged_data
|
71
|
+
end
|
72
|
+
|
73
|
+
def pods_scripts_path
|
74
|
+
'pods-scripts'
|
75
|
+
end
|
76
|
+
|
77
|
+
def pods_generator_path
|
78
|
+
"#{pods_scripts_path}/PodfileGenerator"
|
79
|
+
end
|
80
|
+
|
81
|
+
def branch_cache_path
|
82
|
+
"#{pods_generator_path}/branch_cache.yml"
|
83
|
+
end
|
84
|
+
|
85
|
+
def meta_path
|
86
|
+
"#{pods_generator_path}/meta.yml"
|
87
|
+
end
|
88
|
+
|
89
|
+
def data_path
|
90
|
+
"#{pods_generator_path}/data.yml"
|
91
|
+
end
|
92
|
+
|
93
|
+
def post_install_hooks_path
|
94
|
+
"#{pods_scripts_path}/PostInstallHooks"
|
95
|
+
end
|
96
|
+
|
97
|
+
def podfile_local_path
|
98
|
+
'Podfile.yml'
|
99
|
+
end
|
100
|
+
|
101
|
+
def branch_key
|
102
|
+
'branch'
|
103
|
+
end
|
104
|
+
|
105
|
+
def git_key
|
106
|
+
'git'
|
107
|
+
end
|
108
|
+
|
109
|
+
def version_key
|
110
|
+
'version'
|
111
|
+
end
|
112
|
+
|
113
|
+
def source_key
|
114
|
+
'source'
|
115
|
+
end
|
116
|
+
|
117
|
+
def binary_key
|
118
|
+
'binary'
|
119
|
+
end
|
120
|
+
|
121
|
+
def local_key
|
122
|
+
'local'
|
123
|
+
end
|
124
|
+
|
125
|
+
def local_path_key
|
126
|
+
'local_path'
|
127
|
+
end
|
128
|
+
|
129
|
+
def branch_key
|
130
|
+
'branch'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|