podfileDep 1.1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,449 @@
1
+ require_relative '../version'
2
+ require_relative '../constants'
3
+ require_relative '../check/xcodeproj'
4
+
5
+ module Pod
6
+
7
+ class YamlRely
8
+ attr_reader :pod, :subspecs, :version, :git, :tag, :branch, :podspec, :configurations, :path, :inhibit_warnings, :source, :binary
9
+ def initialize(module_name, pod, subspecs, path, podspec, version, git, tag, branch, configurations, inhibit_warnings, source, binary)
10
+ @module_name = module_name
11
+ @pod = pod
12
+ @subspecs = subspecs
13
+ @path = path
14
+ @podspec = podspec
15
+ @version = version
16
+ @git = git
17
+ @tag = tag
18
+ @branch = branch
19
+ @configurations = configurations
20
+ @inhibit_warnings = inhibit_warnings
21
+ @source = source
22
+ @binary = binary
23
+ end
24
+
25
+ def option
26
+ result = {:configurations => self.configurations, :inhibit_warnings => self.inhibit_warnings, :subspecs => self.subspecs}
27
+ if self.path #路径依赖
28
+ result[:path] = self.path
29
+ elsif self.podspec #podspec引用
30
+ result[:podspec] = self.podspec
31
+ elsif self.version #版本号依赖
32
+ result[:source] = self.source
33
+ elsif self.git #git仓库引用
34
+ result[:git] = self.git
35
+ if self.tag #tag引用
36
+ result[:tag] = self.tag
37
+ else #分支引用 或着未指定分支 也按分支引用
38
+ result[:branch] = self.branch
39
+ end
40
+ end
41
+ result
42
+ end
43
+
44
+ end
45
+ class YamlRelies
46
+
47
+ def self.analysis_yaml(podfile, old)
48
+
49
+ # 获取targets列表
50
+ project_manager = XCProject::XcodeprojManager.share_manager
51
+
52
+ targets = project_manager.get_app_targets
53
+
54
+ podfile_local_yaml = Constants::PODFILE_LOCAL_YAML
55
+ podfile_module_yaml = Constants::PODFILE_MODULE_YAML
56
+ podfile_third_party_yaml = Constants::PODFILE_THIRD_PARTY_YAML
57
+
58
+ # 检查参数
59
+ self.check_param(targets)
60
+
61
+ # 生成YAML文件
62
+ self.generate_local_yaml(podfile_local_yaml)
63
+ self.generate_module_yaml(podfile_module_yaml, "# 企业内部组件")
64
+ self.generate_module_yaml(podfile_third_party_yaml, "# 第三方维护组件")
65
+
66
+ # 读取yaml依赖
67
+ yaml_dependencies = {}
68
+ self.read_yaml_dependencies(podfile_third_party_yaml,false ,yaml_dependencies)
69
+ self.read_yaml_dependencies(podfile_module_yaml,false ,yaml_dependencies)
70
+ self.read_yaml_dependencies(podfile_local_yaml,true ,yaml_dependencies)
71
+
72
+ # 打印依赖
73
+ self.print_dependencies(yaml_dependencies)
74
+
75
+ # 为所有target生成依赖
76
+ targets_dependencies = {}
77
+ self.update_target_dependencies(targets, yaml_dependencies, targets_dependencies)
78
+
79
+ # 兼容老方式
80
+ if old
81
+ return targets_dependencies
82
+ end
83
+
84
+ # 存储所有依赖
85
+ self.store_dependencies(targets_dependencies, podfile)
86
+
87
+ end
88
+
89
+ def self.store_dependencies(targets, podfile)
90
+ # 存储所有的依赖
91
+ targets.each { |name, dependencies|
92
+ podfile.target name do
93
+ podfile.use_frameworks!
94
+ dependencies.each { |dependency|
95
+ if dependency.version
96
+ podfile.pod dependency.pod, dependency.version, dependency.option
97
+ else
98
+ podfile.pod dependency.pod, dependency.option
99
+ end
100
+ }
101
+ end
102
+ }
103
+ targets
104
+ end
105
+
106
+ # 检查方法调用的参数
107
+ def self.check_param(targets)
108
+ msg = "❌ 参数需要填写target名字, 参数类型是字符串格式的数组。例如[\"test1\", \"test2\"]"
109
+ unless targets.class == Array
110
+ puts msg
111
+ exit!
112
+ end
113
+
114
+ targets.each { |target|
115
+ unless target.class == String
116
+ puts msg
117
+ exit!
118
+ end
119
+ }
120
+ end
121
+
122
+ # 校验yaml文件写法是否正确
123
+ def self.yaml_content(yaml_name)
124
+ unless File.exist?(yaml_name)
125
+ puts "文件不存在:"+yaml_name
126
+ return nil
127
+ end
128
+
129
+ begin
130
+ yaml_content = YAML.load_file(yaml_name)
131
+ rescue Exception => e
132
+ puts e
133
+ puts yaml_name+'文件解析异常, 请检查 ⬆️'
134
+ exit!
135
+ end
136
+
137
+ prefix_message = "解析:"+yaml_name + "=> "
138
+ unless yaml_content.class == Hash
139
+ puts "#{prefix_message}共0个依赖(文件不是keyValue形式)"
140
+ return nil
141
+ end
142
+
143
+ unless yaml_content.key?('PODS')
144
+ puts "#{prefix_message}共0个依赖(文件内的key[PODS]不存在)"
145
+ return nil
146
+ end
147
+
148
+ unless yaml_content['PODS'].class == Array
149
+ puts "#{prefix_message}共0个依赖(文件配置的依赖PODS下边不是数组或数组为空)"
150
+ return nil
151
+ end
152
+
153
+ podfile_local_yaml = Constants::PODFILE_LOCAL_YAML
154
+ if yaml_name != podfile_local_yaml and (not yaml_content['SOURCE'] or yaml_content['SOURCE'].class != String)
155
+ puts "#{yaml_name}的SOURCE字段必须是字符串且不为空"
156
+ exit!
157
+ end
158
+
159
+ if yaml_name != podfile_local_yaml and (not yaml_content['BINARY_SOURCE'] or yaml_content['BINARY_SOURCE'].class != String)
160
+ puts "#{yaml_name}的BINARY_SOURCE字段必须是字符串且不为空"
161
+ exit!
162
+ end
163
+
164
+ return yaml_content
165
+
166
+ end
167
+
168
+ # 读取yaml依赖
169
+ def self.read_yaml_dependencies(yaml_name, can_cover, yaml_dependencies)
170
+
171
+ # 检查写法
172
+ yaml_content = self.yaml_content(yaml_name)
173
+
174
+ unless yaml_content
175
+ return
176
+ end
177
+
178
+ # 读取默认源码source
179
+ default_source_source = nil
180
+ if yaml_content.key?('SOURCE') and yaml_content['SOURCE'].class == String
181
+ default_source_source = yaml_content['SOURCE']
182
+ end
183
+
184
+ # 读取默认二进制source
185
+ default_binary_source = nil
186
+ if yaml_content.key?('BINARY_SOURCE') and yaml_content['BINARY_SOURCE'].class == String
187
+ default_binary_source = yaml_content['BINARY_SOURCE']
188
+ end
189
+
190
+ # 依赖列表
191
+ dependencies_pods = yaml_content['PODS']
192
+ puts "解析:#{yaml_name} => 共#{dependencies_pods.size.to_s}个依赖"
193
+
194
+ # 当前yaml文件的组件名字 用来校验本文件内是否重复
195
+ dependencies_name = []
196
+
197
+ # 遍历依赖库列表
198
+ dependencies_pods.each { |dependency|
199
+
200
+ # 不支持提醒
201
+ available_keys = %w[module pod subspecs path podspec version git tag branch configurations inhibit_warnings source binary]
202
+ dependency.each_key { |key|
203
+ unless available_keys.include?(key)
204
+ gem_name = "yaml_relies"
205
+ puts "❌ #{yaml_name}: 当前#{gem_name}版本(#{Yaml_relies::VERSION})不支持字段#{key}"
206
+ puts "请检查对应字段或尝试执行如下命令升级"
207
+ puts "gem uninstall #{gem_name} && gem install #{gem_name}"
208
+ exit!
209
+ end
210
+ }
211
+
212
+ # 校验字段
213
+ unless dependency['pod']
214
+ puts "#{yaml_name}: pod 字段(组件名字)必须存在,请检查:"
215
+ exit!
216
+ end
217
+
218
+ unless dependency['path'] or dependency['podspec'] or dependency['version'] or dependency['git'] or dependency['tag'] or dependency['branch']
219
+ puts "#{yaml_name} - #{dependency['pod']}: path/podspec/version/git/tag/branch 字段需至少有一个存在,请检查"
220
+ exit!
221
+ end
222
+
223
+ if dependency['tag'] and dependency['branch'] and not dependency['git']
224
+ puts "#{yaml_name} - #{dependency['pod']}: 请为此组件配置git字段"
225
+ exit!
226
+ end
227
+
228
+ # 检查数据类型
229
+ if dependency['configurations'] and dependency['configurations'].class != Array
230
+ puts "#{yaml_name} - #{dependency['pod']} - #{dependency['configurations']}: configurations字段必须是数组,例如:['Debug','Release']"
231
+ exit!
232
+ end
233
+
234
+ if dependency['subspecs'] and dependency['subspecs'].class != Array
235
+ puts "#{yaml_name} - #{dependency['pod']} - #{dependency['subspecs']}: subspecs字段必须是数组,例如:['A','B','C']"
236
+ exit!
237
+ end
238
+
239
+ # 校验自身文件重复
240
+ if dependencies_name.include?(dependency['pod'])
241
+ puts "❌ 发现#{yaml_name}内重复组件:#{dependency['pod']},请检查并删除重复依赖:"
242
+ exit!
243
+ else
244
+ dependencies_name << dependency['pod']
245
+ end
246
+ # 校验和总的依赖的重复
247
+ repeats = []
248
+ if yaml_dependencies.key?(dependency['pod']) and not can_cover
249
+ repeats << dependency['pod']
250
+ end
251
+ if repeats.size > 0
252
+ puts "❌ 发现重复组件如下,请检查并删除重复依赖:"
253
+ puts repeats
254
+ exit!
255
+ end
256
+
257
+ # 警告
258
+ podfile_local_yaml = Constants::PODFILE_LOCAL_YAML
259
+ if dependency['path'] and not can_cover
260
+ puts "⚠️ 组件#{dependency['pod']}使用path依赖方式应该写在#{podfile_local_yaml}"
261
+ end
262
+ if dependency['podspec'] and not can_cover
263
+ puts "⚠️ 组件#{dependency['pod']}使用podspec依赖方式应该写在#{podfile_local_yaml}"
264
+ end
265
+
266
+ # 记录覆盖
267
+ if yaml_dependencies.key?(dependency['pod']) and can_cover
268
+ puts "✅ #{dependency['pod']}被#{yaml_name}覆盖"
269
+ end
270
+
271
+ # 默认值
272
+ source = dependency['source']
273
+ unless source
274
+ source = dependency['binary'] ? default_binary_source : default_source_source
275
+ end
276
+ inhibit_warnings = dependency['inhibit_warnings'] ? !!dependency['inhibit_warnings'] : false
277
+ binary = dependency['binary'] ? !!dependency['binary'] : true
278
+ version = (dependency['path'] or dependency['podspec']) ? nil :dependency['version']
279
+
280
+ # 生成依赖对象
281
+ dependency = YamlRely.new(module_name = dependency['module'],
282
+ pod = dependency['pod'],
283
+ subspecs = dependency['subspecs'],
284
+ path = dependency['path'],
285
+ podspec = dependency['podspec'],
286
+ version = version,
287
+ git = dependency['git'],
288
+ tag = dependency['tag'],
289
+ branch = dependency['branch'],
290
+ configurations = dependency['configurations'],
291
+ inhibit_warnings = inhibit_warnings,
292
+ source = source,
293
+ binary = binary)
294
+ yaml_dependencies[dependency.pod] = dependency
295
+ }
296
+
297
+ end
298
+
299
+ # 生成传进来的target的依赖库列表
300
+ def self.update_target_dependencies(targets, yaml_dependencies, targets_dependencies)
301
+ temp_array = []
302
+ yaml_dependencies.each_value { |value|
303
+ temp_array << value
304
+ }
305
+
306
+ targets.each { |target|
307
+ targets_dependencies[target] = temp_array
308
+ }
309
+ end
310
+
311
+ def self.print_dependencies(yaml_dependencies)
312
+ puts "➡️ 解析依赖总数共计:#{yaml_dependencies.size}个\n\n"
313
+ puts '⬇️ 打印依赖'
314
+ yaml_dependencies.each_value { |dependency|
315
+ puts_result = "pod '#{dependency.pod}'"
316
+
317
+ if dependency.path #路径引用
318
+ puts_result += ", :path => '#{dependency.path}'"
319
+ elsif dependency.podspec #podspec引用
320
+ puts_result += ", :podspec => '#{dependency.podspec}'"
321
+ elsif dependency.version #版本号引用
322
+ puts_result += ", '#{dependency.version.to_s}'"
323
+ elsif dependency.git #git仓库引用
324
+ puts_result += ", :git => '#{dependency.git}'"
325
+ if dependency.tag
326
+ puts_result += ", :tag => '#{dependency.tag}'"
327
+ elsif dependency.branch
328
+ puts_result += ", :branch => '#{dependency.branch}'"
329
+ end
330
+ end
331
+
332
+ if dependency.configurations
333
+ puts_result += ", :configurations => ['#{dependency.configurations.join("','")}']"
334
+ end
335
+ if dependency.subspecs
336
+ puts_result += ", :subspecs => ['#{dependency.subspecs.join("','")}']"
337
+ end
338
+ if dependency.inhibit_warnings
339
+ puts_result += ", :inhibit_warnings => true"
340
+ end
341
+ if dependency.version and dependency.source
342
+ puts_result += ", :source => '#{dependency.source}'"
343
+ end
344
+
345
+ puts puts_result
346
+ }
347
+ puts "⬆️ 打印完毕"
348
+ end
349
+
350
+ # 是否需要快速编译
351
+ def self.quick_build
352
+
353
+ podfile_local_yaml = Constants::PODFILE_LOCAL_YAML
354
+
355
+ unless File.exist?(podfile_local_yaml)
356
+ puts "文件不存在:"+podfile_local_yaml
357
+ return false
358
+ end
359
+
360
+ begin
361
+ yaml_content = YAML.load_file(podfile_local_yaml)
362
+ rescue Exception => e
363
+ puts e
364
+ return false
365
+ end
366
+
367
+ yaml_content["QUICK"] == true ? true : false
368
+ end
369
+
370
+ # 生成local文件
371
+ def self.generate_local_yaml(podfile_local_yaml)
372
+ if File.exist?(podfile_local_yaml)
373
+ return
374
+ end
375
+ puts "生成#{podfile_local_yaml}文件"
376
+
377
+ content = ""
378
+ content = content + "# 1、本依赖配置文件优先级最高, 用来覆盖其他两个依赖的yaml文件中的组件。 尝试打开以下注释, 修改对应字段, 然后执行pod install\n"
379
+ content = content + "# 2、PODS下边的配置是数组形式, 如果有多个就写多个\n"
380
+ content = content + "# 3、本文件加入到忽略文件中\n\n"
381
+
382
+ # content = content + "# QUICK字段如果为true, 则表示会自动解析所有组件的依赖, 并删除不被使用的依赖库, 以达到开发时快速编译的目的\n"
383
+ # content = content + "QUICK: false\n\n"
384
+
385
+ content = content + "PODS:\n"
386
+
387
+ content = content + "\n"
388
+
389
+ content = content + "# - module: Masonry\n"
390
+ content = content + "# pod: Masonry\n"
391
+ content = content + "# subspecs: null\n"
392
+ content = content + "# path: ~/MasonryCodePath\n"
393
+
394
+ content = content + "\n"
395
+
396
+ content = content + "# - module: MJExtension\n"
397
+ content = content + "# pod: MJExtension\n"
398
+ content = content + "# subspecs: null\n"
399
+ content = content + "# path: ~/MJExtensionCodePath\n"
400
+
401
+ File.open(podfile_local_yaml, 'w') { |file|
402
+ file.write(content)
403
+ }
404
+ end
405
+
406
+ # 生成其他的yaml文件
407
+ def self.generate_module_yaml(yaml_name, prefix)
408
+ if File.exist?(yaml_name)
409
+ return
410
+ end
411
+ puts "生成#{yaml_name}文件"
412
+
413
+ content = ""
414
+ content = content + prefix
415
+ content = content + "\n"
416
+ content = content + "# 1、优先级:path > podspec > version > tag > branch)\n"
417
+ content = content + "# 2、path字段就是直接从对应的路径读取依赖\n"
418
+ content = content + "# 3、podspec字段就是直接从对应的路径读取podspec文件加载依赖\n"
419
+ content = content + "# 4、当version不为空时,会取source字段的repo获取组件,如果source字段为空,那么就取文件顶部配置的默认SOURCE\n"
420
+ content = content + "# 5、当tag字段或branch字段不为空时,会取git字段的地址获取代码\n"
421
+ content = content + "\n"
422
+ content = content + "# 如果 source = null && binary = false 则source默认使用这个\n"
423
+ content = content + "SOURCE: 这里替换成源码的source\n"
424
+ content = content + "\n"
425
+ content = content + "# 如果 source = null && binary = true 则source默认使用这个\n"
426
+ content = content + "BINARY_SOURCE: 这里替换成二进制的source\n"
427
+ content = content + "\n"
428
+ content = content + "PODS:\n"
429
+ content = content + "\n"
430
+ content = content + "# - module: XXX\n"
431
+ content = content + "# pod: XXX\n"
432
+ content = content + "# subspecs: null\n"
433
+ content = content + "# podspec: null\n"
434
+ content = content + "# version: 1.0.0\n"
435
+ content = content + "# git: null\n"
436
+ content = content + "# tag: null\n"
437
+ content = content + "# branch: null\n"
438
+ content = content + "# configurations: null\n"
439
+ content = content + "# inhibit_warnings: true\n"
440
+ content = content + "# source: null\n"
441
+ content = content + "# binary: true\n"
442
+
443
+ File.open(yaml_name, 'w') { |file|
444
+ file.write(content)
445
+ }
446
+ end
447
+
448
+ end
449
+ end