podfileDep 1.1.4 → 2.0.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/CHANGELOG.md +11 -1
- data/lib/cocoapods_plugin.rb +44 -0
- data/lib/old/podfileDep.rb +1408 -0
- data/lib/podfileDep/check/dep.rb +183 -0
- data/lib/podfileDep/check/import.rb +159 -0
- data/lib/podfileDep/check/item.rb +11 -0
- data/lib/podfileDep/check/module.rb +178 -0
- data/lib/podfileDep/check/xcodeproj.rb +310 -0
- data/lib/podfileDep/constants.rb +13 -0
- data/lib/podfileDep/indirect/indirect.rb +37 -0
- data/lib/podfileDep/modify/modify_code.rb +52 -0
- data/lib/podfileDep/podfilelock.rb +17 -0
- data/lib/podfileDep/reference/project.rb +72 -0
- data/lib/podfileDep/reference/unused.rb +141 -0
- data/lib/podfileDep/version.rb +1 -1
- data/lib/podfileDep/yaml/yaml_dep.rb +449 -0
- data/lib/podfileDep.rb +14 -816
- data/podfileDep.gemspec +6 -5
- metadata +50 -10
- data/Gemfile.lock +0 -19
- data/sig/podfileDep.rbs +0 -4
data/lib/podfileDep.rb
CHANGED
@@ -1,828 +1,26 @@
|
|
1
|
-
|
2
|
-
require 'yaml'
|
1
|
+
require_relative 'podfileDep/yaml/yaml_dep'
|
3
2
|
|
4
|
-
module PodfileDep
|
5
|
-
|
6
|
-
$podfile_thirdParty = 'PodfileThirdParty.yaml'
|
7
|
-
$podfile_module = 'PodfileModule.yaml'
|
8
|
-
$podfile_local = 'PodfileLocal.yaml'
|
9
|
-
$podfile_lock = 'Podfile.lock'
|
10
|
-
|
11
|
-
|
12
|
-
class PodDependency
|
13
|
-
attr_reader :pod, :version, :git, :tag, :branch, :podspec, :configurations, :path, :inhibit_warnings, :source, :binary
|
14
|
-
def initialize(module_name, pod, version, git, tag, branch, podspec, configurations, path, inhibit_warnings, source, binary)
|
15
|
-
@module_name = module_name
|
16
|
-
@pod = pod
|
17
|
-
@version = version
|
18
|
-
@git = git
|
19
|
-
@tag = tag
|
20
|
-
@branch = branch
|
21
|
-
@podspec = podspec
|
22
|
-
@configurations = configurations
|
23
|
-
@path = path
|
24
|
-
@inhibit_warnings = inhibit_warnings
|
25
|
-
@source = source
|
26
|
-
@binary = binary
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def PodfileDep.setup(targets)
|
31
|
-
|
32
|
-
PodfileDep.checkFile()
|
33
|
-
PodfileDep.checkParam(targets)
|
34
|
-
|
35
|
-
PodfileDep.generateLocal()
|
36
|
-
PodfileDep.generateModule($podfile_module, "企业内部组件", "TestPodName")
|
37
|
-
PodfileDep.generateModule($podfile_thirdParty, "第三方组件", "Masonry")
|
38
|
-
|
39
|
-
# 读取依赖
|
40
|
-
lock_dependencies = PodfileDep.lockDeps()
|
41
|
-
|
42
|
-
all_dependencies = {}
|
43
|
-
PodfileDep.readYamlDep(all_dependencies, $podfile_thirdParty, false)
|
44
|
-
PodfileDep.readYamlDep(all_dependencies, $podfile_module, false)
|
45
|
-
PodfileDep.readYamlDep(all_dependencies, $podfile_local, true)
|
46
|
-
|
47
|
-
PodfileDep.logDeps(all_dependencies)
|
48
|
-
|
49
|
-
result = PodfileDep.generateTargetsDep(targets, all_dependencies)
|
50
|
-
|
51
|
-
PodfileDep.logChangedDep(all_dependencies, lock_dependencies)
|
52
|
-
|
53
|
-
return result
|
54
|
-
end
|
55
|
-
|
56
|
-
def PodfileDep.checkFile()
|
57
|
-
unless File.exist?("Podfile") then
|
58
|
-
puts "本脚本文件必须和Podfile文件同级目录"
|
59
|
-
exit!
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def PodfileDep.checkParam(targets)
|
64
|
-
msg = "❌ setup里参数需要填写target名字, 参数类型是字符串格式的数组。例如[\"test1\", \"test2\"]"
|
65
|
-
unless targets.class == Array
|
66
|
-
puts msg
|
67
|
-
exit!
|
68
|
-
end
|
69
|
-
|
70
|
-
targets.each { |target|
|
71
|
-
unless target.class == String
|
72
|
-
puts msg
|
73
|
-
exit!
|
74
|
-
end
|
75
|
-
}
|
76
|
-
end
|
77
|
-
|
78
|
-
def PodfileDep.lockDeps()
|
79
|
-
result = {}
|
80
|
-
|
81
|
-
unless File.exist?($podfile_lock)
|
82
|
-
return result
|
83
|
-
end
|
84
|
-
|
85
|
-
dependencies_yaml = YAML.load_file($podfile_lock)
|
86
|
-
if dependencies_yaml.key?('DEPENDENCIES')
|
87
|
-
temp_dependencies = dependencies_yaml['DEPENDENCIES']
|
88
|
-
temp_dependencies.each { |item|
|
89
|
-
old_dependency = item.split(' (')
|
90
|
-
result[old_dependency[0]] = old_dependency[1]
|
91
|
-
}
|
92
|
-
end
|
93
|
-
return result
|
94
|
-
end
|
95
|
-
|
96
|
-
def PodfileDep.generateLocal()
|
97
|
-
if File.exist?($podfile_local) then
|
98
|
-
return
|
99
|
-
end
|
100
|
-
content = "
|
101
|
-
# 1、本依赖配置文件优先级最高, 用来覆盖其他两个依赖的yaml文件中的组件。 尝试打开以下注释, 修改对应字段, 然后执行pod install
|
102
|
-
# 2、PODS下边的配置是数组形式, 如果有多个就写多个
|
103
|
-
# 3、请将本文件加入到忽略文件中
|
104
|
-
|
105
|
-
PODS:
|
106
|
-
|
107
|
-
# - module: Masonry
|
108
|
-
# pod: Masonry
|
109
|
-
# path: ~/CodePath
|
110
|
-
|
111
|
-
"
|
112
|
-
File.open($podfile_local, 'w') { |file|
|
113
|
-
file.write(content)
|
114
|
-
}
|
115
|
-
end
|
116
|
-
|
117
|
-
def PodfileDep.generateModule(yaml_module, prefix, pod_name)
|
118
|
-
if File.exist?(yaml_module) then
|
119
|
-
return
|
120
|
-
end
|
121
|
-
|
122
|
-
content = "
|
123
|
-
# #{prefix}
|
124
|
-
# 1、优先级:path > podspec > version > tag > branch (git字段是tag字段或branch字段不为空时用到, source字段是version不为空时用到, path字段就是直接从对应的路径读取依赖)
|
125
|
-
# 2、为方便查看, 建议将本文件拖入壳工程引用
|
126
|
-
|
127
|
-
# 如果 source = null && binary = false 则source默认使用这个
|
128
|
-
SOURCE: 这里替换成源码的source
|
129
|
-
|
130
|
-
# 如果 source = null && binary = true 则source默认使用这个
|
131
|
-
BINARY_SOURCE: 这里替换成二进制的source
|
132
|
-
|
133
|
-
PODS:
|
134
|
-
|
135
|
-
# - module: #{pod_name}
|
136
|
-
# pod: #{pod_name}
|
137
|
-
# path: null
|
138
|
-
# podspec: null
|
139
|
-
# version: 1.1.0
|
140
|
-
# git: null
|
141
|
-
# tag: null
|
142
|
-
# branch: null
|
143
|
-
# configurations: null
|
144
|
-
# inhibit_warnings: true
|
145
|
-
# source: null
|
146
|
-
# binary: true
|
147
|
-
"
|
148
|
-
File.open(yaml_module, 'w') { |file|
|
149
|
-
file.write(content)
|
150
|
-
}
|
151
|
-
end
|
152
|
-
|
153
|
-
def PodfileDep.readYamlDep(all_dependencies, yamlName, canCover)
|
154
|
-
unless File.exist?(yamlName)
|
155
|
-
puts "文件不存在:"+yamlName
|
156
|
-
return
|
157
|
-
end
|
158
|
-
|
159
|
-
begin
|
160
|
-
dependencies_yaml = YAML.load_file(yamlName)
|
161
|
-
rescue Exception => e
|
162
|
-
puts e
|
163
|
-
puts yamlName+'文件解析异常, 请检查 ⬆️'
|
164
|
-
exit!
|
165
|
-
end
|
166
|
-
|
167
|
-
unless dependencies_yaml.class == Hash
|
168
|
-
puts "文件不是keyValue形式:"+yamlName
|
169
|
-
return
|
170
|
-
end
|
171
|
-
|
172
|
-
unless dependencies_yaml.key?('PODS')
|
173
|
-
puts "文件内的key[PODS]不存在:"+yamlName
|
174
|
-
return
|
175
|
-
end
|
176
|
-
|
177
|
-
unless dependencies_yaml['PODS'].class == Array
|
178
|
-
puts "文件配置的依赖PODS下边不是数组形式:"+yamlName
|
179
|
-
return
|
180
|
-
end
|
181
|
-
|
182
|
-
# 读取默认源码source
|
183
|
-
default_source = nil
|
184
|
-
if dependencies_yaml.key?('SOURCE') and dependencies_yaml['SOURCE'].class == String
|
185
|
-
default_source = dependencies_yaml['SOURCE']
|
186
|
-
end
|
187
|
-
|
188
|
-
# 读取默认二进制source
|
189
|
-
default_binary_source = nil
|
190
|
-
if dependencies_yaml.key?('BINARY_SOURCE') and dependencies_yaml['BINARY_SOURCE'].class == String
|
191
|
-
default_binary_source = dependencies_yaml['BINARY_SOURCE']
|
192
|
-
end
|
193
|
-
|
194
|
-
dependencies = dependencies_yaml['PODS']
|
195
|
-
puts "解析:"+yamlName + " 共"+dependencies.size.to_s + "个依赖"
|
196
|
-
|
197
|
-
# 遍历依赖库列表
|
198
|
-
dependencies.each { |dependency|
|
199
|
-
|
200
|
-
# 不能覆盖,有重复依赖
|
201
|
-
if all_dependencies.key?(dependency['pod'])
|
202
|
-
# 能被覆盖
|
203
|
-
if canCover
|
204
|
-
puts '✅ 已经存在: ' + dependency['pod'] + ', 该依赖被'+yamlName+'中依赖替换'
|
205
|
-
else
|
206
|
-
puts '❌ 发现重复的组件依赖: [' + dependency['pod'] + '],请检查依赖文件,删除重复依赖'
|
207
|
-
exit!
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
# 如果source不存在, 则使用默认的
|
212
|
-
unless dependency['source']
|
213
|
-
dependency['source'] = dependency['binary'] ? default_binary_source : default_source
|
214
|
-
end
|
215
|
-
|
216
|
-
# 校验
|
217
|
-
if not dependency['path'] and not dependency['podspec'] and not dependency['source'] and dependency['version']
|
218
|
-
puts '❌ 请为组件'+dependency['pod']+'配置source字段或在'+ yamlName+'顶层设置默认source(字段:SOURCE和BINARY_SOURCE)'
|
219
|
-
exit!
|
220
|
-
end
|
221
|
-
|
222
|
-
# 警告
|
223
|
-
if dependency['path'] and not canCover
|
224
|
-
puts '⚠️ 组件'+dependency['pod']+'使用path依赖方式应该写在'+ $podfile_local
|
225
|
-
end
|
226
|
-
|
227
|
-
if dependency['podspec'] and not canCover
|
228
|
-
puts '⚠️ 组件'+dependency['pod']+'使用podspec依赖方式应该写在'+ $podfile_local
|
229
|
-
end
|
230
|
-
|
231
|
-
# 生成依赖对象
|
232
|
-
module_name = dependency['module']
|
233
|
-
pod = dependency['pod']
|
234
|
-
version = dependency['version']
|
235
|
-
git = dependency['git']
|
236
|
-
tag = dependency['tag']
|
237
|
-
branch = dependency['branch']
|
238
|
-
podspec = dependency['podspec']
|
239
|
-
configurations = dependency['configurations']
|
240
|
-
path = dependency['path']
|
241
|
-
inhibit_warnings = dependency['inhibit_warnings'] ? dependency['inhibit_warnings'] : false
|
242
|
-
source = dependency['source']
|
243
|
-
binary = dependency['binary']
|
244
|
-
|
245
|
-
unless pod then
|
246
|
-
puts yamlName + ': pod 字段(pod组件名字)必须存在,请检查'
|
247
|
-
exit!
|
248
|
-
end
|
249
|
-
|
250
|
-
unless path or podspec or version or git or tag or branch then
|
251
|
-
puts yamlName + ': path/podspec/version/git/tag/branch 字段需至少有一个存在,请检查'
|
252
|
-
exit!
|
253
|
-
end
|
254
|
-
|
255
|
-
pod_dependency = PodDependency.new(module_name, pod, version, git, tag, branch, podspec, configurations, path, inhibit_warnings, source, binary);
|
256
|
-
|
257
|
-
# 加入全部的依赖map中
|
258
|
-
all_dependencies[dependency['pod']] = pod_dependency
|
259
|
-
|
260
|
-
}
|
261
|
-
end
|
262
|
-
|
263
|
-
def PodfileDep.logDeps(all_dependencies)
|
264
|
-
puts "\n➡️ 解析依赖总数共计:#{all_dependencies.size}个"
|
265
|
-
puts '⬇️ 按照 Podfile 格式打印一遍'
|
266
|
-
all_dependencies.each_value { |dependency|
|
267
|
-
|
268
|
-
# 执行打印
|
269
|
-
if dependency.path #路径引用
|
270
|
-
puts_result = 'pod \'' + dependency.pod + '\''
|
271
|
-
puts_result += ', :path => \'' + dependency.path + '\''
|
272
|
-
if dependency.configurations
|
273
|
-
puts_result += ', :configurations => [\'' + dependency.configurations.join('\', \'') + '\']'
|
274
|
-
end
|
275
|
-
if dependency.inhibit_warnings
|
276
|
-
puts_result += ', :inhibit_warnings => true'
|
277
|
-
end
|
278
|
-
puts puts_result
|
279
|
-
elsif dependency.podspec #podspec引用
|
280
|
-
puts_result = 'pod \'' + dependency.pod + '\''
|
281
|
-
if dependency.podspec
|
282
|
-
puts_result += ', :podspec => \'' + dependency.podspec + '\''
|
283
|
-
end
|
284
|
-
if dependency.configurations
|
285
|
-
puts_result += ', :configurations => [\'' + dependency.configurations.join('\', \'') + '\']'
|
286
|
-
end
|
287
|
-
if dependency.inhibit_warnings
|
288
|
-
puts_result += ', :inhibit_warnings => true'
|
289
|
-
end
|
290
|
-
puts puts_result
|
291
|
-
elsif dependency.version #版本号引用
|
292
|
-
puts_result = 'pod \'' + dependency.pod + '\', \'' + dependency.version.to_s + '\''
|
293
|
-
if dependency.configurations
|
294
|
-
puts_result += ', :configurations => [\'' + dependency.configurations.join('\', \'') + '\']'
|
295
|
-
end
|
296
|
-
if dependency.inhibit_warnings
|
297
|
-
puts_result += ', :inhibit_warnings => true'
|
298
|
-
end
|
299
|
-
if dependency.source
|
300
|
-
puts_result += ', :source => \'' + dependency.source + '\''
|
301
|
-
end
|
302
|
-
puts puts_result
|
303
|
-
elsif dependency.git #git仓库引用
|
304
|
-
puts_result = 'pod \'' + dependency.pod + '\''
|
305
|
-
if dependency.git
|
306
|
-
puts_result += ', :git => \'' + dependency.git + '\''
|
307
|
-
end
|
308
|
-
if dependency.tag
|
309
|
-
puts_result += ', :tag => \'' + dependency.tag + '\''
|
310
|
-
elsif dependency.branch
|
311
|
-
puts_result += ', :branch => \'' + dependency.branch + '\''
|
312
|
-
end
|
313
|
-
if dependency.configurations
|
314
|
-
puts_result += ', :configurations => [\'' + dependency.configurations.join('\', \'') + '\']'
|
315
|
-
end
|
316
|
-
if dependency.inhibit_warnings
|
317
|
-
puts_result += ', :inhibit_warnings => true'
|
318
|
-
end
|
319
|
-
puts puts_result
|
320
|
-
else # 路径 版本号 git地址 podspec 均未指定 去指定的source中找(source不会为空)
|
321
|
-
puts_result = 'pod \'' + dependency.pod + '\''
|
322
|
-
if dependency.configurations
|
323
|
-
puts_result += ', :configurations => [\'' + dependency.configurations.join('\', \'') + '\']'
|
324
|
-
end
|
325
|
-
if dependency.inhibit_warnings
|
326
|
-
puts_result += ', :inhibit_warnings => true'
|
327
|
-
end
|
328
|
-
if dependency.source
|
329
|
-
puts_result += ', :source => \'' + dependency.source + '\''
|
330
|
-
end
|
331
|
-
puts puts_result
|
332
|
-
end
|
333
|
-
}
|
334
|
-
puts '⬆️ 打印完毕'
|
335
|
-
end
|
336
|
-
|
337
|
-
def PodfileDep.generateTargetsDep(targets, all_dependencies)
|
338
|
-
|
339
|
-
tempArray = []
|
340
|
-
all_dependencies.each_value { |value|
|
341
|
-
tempArray << value
|
342
|
-
}
|
343
|
-
|
344
|
-
result = {}
|
345
|
-
targets.each { |target|
|
346
|
-
result[target] = tempArray
|
347
|
-
}
|
348
|
-
return result
|
349
|
-
end
|
350
|
-
|
351
|
-
def PodfileDep.logNewDependency(lock_dependencies, new_dependency)
|
352
|
-
new_add = true
|
353
|
-
lock_dependencies.each_key { |old_dependency|
|
354
|
-
if old_dependency == new_dependency
|
355
|
-
new_add = false
|
356
|
-
break
|
357
|
-
end
|
358
|
-
}
|
359
|
-
|
360
|
-
if new_add == true
|
361
|
-
puts '🈶 新增依赖: ' + new_dependency
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
def PodfileDep.logRemoveDependency(new_dependencies, old_dependency)
|
366
|
-
|
367
|
-
old_remove = true
|
368
|
-
new_dependencies.each { |new_dependency|
|
369
|
-
if old_dependency == new_dependency
|
370
|
-
old_remove = false
|
371
|
-
break
|
372
|
-
end
|
373
|
-
}
|
374
|
-
|
375
|
-
if old_remove == true
|
376
|
-
puts '🈚️ 删除依赖: ' + old_dependency
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
def PodfileDep.podfilePod()
|
381
|
-
work_dir = FileUtils.pwd()
|
382
|
-
podfile_path = work_dir + '/Podfile'
|
383
|
-
res = Array.new()
|
384
|
-
unless File.exist?(podfile_path) then
|
385
|
-
return res
|
386
|
-
end
|
387
|
-
lineArr = IO.readlines(podfile_path)
|
388
|
-
lineArr.each { |line|
|
389
|
-
line = line.gsub(" ", "")
|
390
|
-
if line.start_with?("pod\'")
|
391
|
-
arr = line.split("\'")
|
392
|
-
if arr.size>1 then
|
393
|
-
res << arr[1]
|
394
|
-
end
|
395
|
-
end
|
396
|
-
}
|
397
|
-
return res
|
398
|
-
end
|
399
|
-
|
400
|
-
def PodfileDep.logChangedDep(all_dependencies, lock_dependencies)
|
401
|
-
new_dependencies = PodfileDep.podfilePod()
|
402
|
-
|
403
|
-
all_dependencies.each_key { |key|
|
404
|
-
new_dependencies << key
|
405
|
-
}
|
406
|
-
|
407
|
-
new_dependencies.each { |item|
|
408
|
-
PodfileDep.logNewDependency(lock_dependencies, item)
|
409
|
-
}
|
410
|
-
|
411
|
-
lock_dependencies.each_key { |old_dependency|
|
412
|
-
PodfileDep.logRemoveDependency(new_dependencies, old_dependency)
|
413
|
-
}
|
414
|
-
end
|
415
|
-
|
416
|
-
def PodfileDep.logIndirectDependencies()
|
417
|
-
|
418
|
-
# 判断yaml文件是否存在
|
419
|
-
unless File.exist?($podfile_lock)
|
420
|
-
return
|
421
|
-
end
|
422
|
-
|
423
|
-
# 内容读取
|
424
|
-
dependencies_lock = YAML.load_file($podfile_lock)
|
425
|
-
|
426
|
-
dependencies = dependencies_lock['DEPENDENCIES']
|
427
|
-
unless dependencies
|
428
|
-
return
|
429
|
-
end
|
430
|
-
|
431
|
-
check_sums = dependencies_lock['SPEC CHECKSUMS']
|
432
|
-
unless check_sums
|
433
|
-
return
|
434
|
-
end
|
435
|
-
|
436
|
-
# 数组处理
|
437
|
-
checkValues = dependencies.collect! {|item|
|
438
|
-
item.split(' (')[0]
|
439
|
-
}
|
440
|
-
checkValues = dependencies.collect! {|item|
|
441
|
-
item.split('/')[0]
|
442
|
-
}
|
443
|
-
|
444
|
-
puts ''
|
445
|
-
check_sums.each{ |array|
|
446
|
-
beCheckValue = array[0]
|
447
|
-
unless checkValues.include?(beCheckValue)
|
448
|
-
puts '↪️ 间接依赖: '+ beCheckValue
|
449
|
-
end
|
450
|
-
}
|
451
|
-
end
|
452
3
|
|
453
|
-
|
4
|
+
module Pod
|
5
|
+
class Podfile
|
6
|
+
def yaml_dep!
|
454
7
|
|
455
|
-
|
456
|
-
|
457
|
-
return
|
458
|
-
end
|
459
|
-
|
460
|
-
# 内容读取
|
461
|
-
dependencies_lock = YAML.load_file($podfile_lock)
|
462
|
-
|
463
|
-
dependencies = dependencies_lock['PODS']
|
464
|
-
unless dependencies
|
465
|
-
return
|
466
|
-
end
|
467
|
-
|
468
|
-
# 数组处理
|
469
|
-
checkValues = Array.new
|
470
|
-
allValues = Array.new
|
471
|
-
dependencies.each {|item|
|
472
|
-
if item.class == Hash then
|
473
|
-
item.each { |key, value|
|
474
|
-
item = key
|
475
|
-
allValues.concat(value)
|
476
|
-
}
|
477
|
-
end
|
478
|
-
item.split(' (')[0]
|
479
|
-
checkValues << item
|
480
|
-
}
|
481
|
-
|
482
|
-
# 数组处理
|
483
|
-
checkValues.collect! { |value|
|
484
|
-
value.split(' (')[0]
|
485
|
-
}
|
486
|
-
allValues.collect! { |value|
|
487
|
-
value.split(' (')[0]
|
488
|
-
}
|
489
|
-
|
490
|
-
# 处理有的只依赖了子仓库
|
491
|
-
allValues1 = allValues + []
|
492
|
-
allValues1.collect! { |value|
|
493
|
-
value.split('/')[0]
|
494
|
-
}
|
495
|
-
|
8
|
+
# 加入插件
|
9
|
+
plugin("podfileDep")
|
496
10
|
|
497
|
-
|
498
|
-
|
499
|
-
main_path = PathUtil.expandPath(main_path)
|
11
|
+
# 解析依赖
|
12
|
+
Pod::YamlRelies.analysis_yaml(self, false)
|
500
13
|
|
501
|
-
checkValues.each { |item|
|
502
|
-
if not allValues.include?(item) and not allValues1.include?(item)
|
503
|
-
res = PodfileDep.checkUnuseInMain(item, main_path)
|
504
|
-
if res
|
505
|
-
puts "可能未使用的组件: " + item
|
506
|
-
end
|
507
|
-
end
|
508
|
-
}
|
509
|
-
end
|
510
|
-
|
511
|
-
def PodfileDep.checkUnuseInMain(item, main_path)
|
512
|
-
unless File.exist?(main_path)then
|
513
|
-
return true
|
514
14
|
end
|
515
|
-
lineArr = IO.readlines(main_path)
|
516
|
-
lineArr.each_with_index { |line, index|
|
517
|
-
if line.start_with?("#import <#{item}")
|
518
|
-
return false
|
519
|
-
end
|
520
|
-
}
|
521
|
-
|
522
|
-
return true
|
523
15
|
end
|
524
|
-
|
525
16
|
end
|
526
17
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
@fileNameArray = fileNameArray
|
534
|
-
@filePathArray = filePathArray
|
535
|
-
end
|
536
|
-
end
|
537
|
-
|
538
|
-
class Import
|
539
|
-
attr_reader :content, :importName, :moduleItem, :fileName, :lineIndex, :pod
|
540
|
-
def initialize(content, importName, moduleItem, fileName, lineIndex, pod)
|
541
|
-
@content = content
|
542
|
-
@importName = importName
|
543
|
-
@moduleItem = moduleItem
|
544
|
-
@fileName = fileName
|
545
|
-
@lineIndex = lineIndex
|
546
|
-
@pod = pod
|
547
|
-
end
|
548
|
-
def setPod=(pod)
|
549
|
-
@pod = pod
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
def ImportCheck.check()
|
554
|
-
puts "import规范检查中..."
|
555
|
-
start = (Time.now.to_f * 1000).to_i
|
556
|
-
|
557
|
-
# 需要检查的模块
|
558
|
-
checkModules = []
|
559
|
-
ImportCheck.findCheckModules(checkModules, $podfile_module)
|
560
|
-
ImportCheck.findCheckModules(checkModules, $podfile_local)
|
561
|
-
|
562
|
-
# 白名单
|
563
|
-
whiteListName = "importCheckWhite.txt"
|
564
|
-
whiteList = ImportCheck.WhiteList(whiteListName)
|
565
|
-
|
566
|
-
# 有问题的import
|
567
|
-
badImportArray = []
|
568
|
-
|
569
|
-
# 计数
|
570
|
-
checkCount = 0
|
571
|
-
checkModules.each { |moduleItem|
|
572
|
-
modulePath = moduleItem.modulePath
|
573
|
-
|
574
|
-
# 需要检查的文件
|
575
|
-
filePathArray = []
|
576
|
-
fileNameArray = []
|
577
|
-
ImportCheck.findCodeFile(modulePath, filePathArray, fileNameArray, false)
|
578
|
-
|
579
|
-
filePathArray.each { |filePath|
|
580
|
-
ImportCheck.findBadQuoteImport(filePath, fileNameArray, badImportArray, moduleItem, whiteList)
|
581
|
-
}
|
582
|
-
checkCount += fileNameArray.size
|
583
|
-
}
|
584
|
-
|
585
|
-
allModuleArray = ImportCheck.findModules()
|
586
|
-
allModuleArray = allModuleArray + checkModules
|
587
|
-
|
588
|
-
tiplog = false
|
589
|
-
badImportArray.collect { |import|
|
590
|
-
moduleName = ImportCheck.findPodModule(allModuleArray, import.importName)
|
591
|
-
import.setPod = moduleName
|
592
|
-
result = moduleName ? "#import <#{moduleName}/#{import.importName}>" : "<>形式导入"
|
593
|
-
puts "⚠️ <#{import.moduleItem.moduleName}> #{import.fileName} #{import.lineIndex}行 #{import.content} => #{result}"
|
594
|
-
tiplog = true
|
595
|
-
}
|
596
|
-
|
597
|
-
# 生成白名单文件
|
598
|
-
ImportCheck.generateWhite(whiteListName)
|
599
|
-
|
600
|
-
if tiplog then
|
601
|
-
puts "\nimport规范检查白名单文件: #{whiteListName}"
|
602
|
-
end
|
603
|
-
|
604
|
-
duration = ((Time.now.to_f * 1000).to_i - start)*0.001
|
605
|
-
puts "import规范检查完毕! 共检查#{checkCount}个文件 耗时:#{duration.round(2)}秒"
|
606
|
-
end
|
607
|
-
|
608
|
-
def ImportCheck.WhiteList(whiteListName)
|
609
|
-
unless File.exist?(whiteListName) then
|
610
|
-
return []
|
611
|
-
end
|
612
|
-
|
613
|
-
array = []
|
614
|
-
lineArr = IO.readlines(whiteListName)
|
615
|
-
lineArr.each { |line|
|
616
|
-
unless line.start_with?("#import \"")
|
617
|
-
next
|
618
|
-
end
|
619
|
-
array << line
|
620
|
-
}
|
621
|
-
return array
|
622
|
-
end
|
623
|
-
|
624
|
-
def ImportCheck.generateWhite(whiteListName)
|
625
|
-
if File.exist?(whiteListName) then
|
626
|
-
return
|
627
|
-
end
|
628
|
-
|
629
|
-
content = "import不规范检查, 这里配置白名单, 每个一行(加入白名单的不会被检查是否规范)。 示例
|
630
|
-
#import \"libxx.h\"
|
631
|
-
#import \"libxxx.h\"
|
632
|
-
-----------请在下边按示例加白名单---------
|
633
|
-
"
|
634
|
-
File.open(whiteListName, 'w') { |file|
|
635
|
-
file.write(content)
|
636
|
-
}
|
637
|
-
end
|
638
|
-
|
639
|
-
def ImportCheck.findPodModule(moduleArray, importName)
|
640
|
-
moduleArray.each { |item|
|
641
|
-
item.fileNameArray.each { |fileName|
|
642
|
-
if fileName == importName
|
643
|
-
return item.moduleName
|
644
|
-
end
|
645
|
-
}
|
646
|
-
}
|
647
|
-
return nil
|
648
|
-
end
|
649
|
-
|
650
|
-
def ImportCheck.findModules()
|
651
|
-
pods_dir = FileUtils.pwd() + "/Pods"
|
652
|
-
|
653
|
-
moduleArray = []
|
654
|
-
|
655
|
-
Dir.foreach(pods_dir) { |moduleName|
|
656
|
-
if moduleName.include?(".") or moduleName == "Target Support Files" or moduleName == "Headers"
|
657
|
-
next
|
658
|
-
end
|
659
|
-
modulePath = pods_dir + "/" + moduleName
|
660
|
-
filePathArray = []
|
661
|
-
fileNameArray = []
|
662
|
-
ImportCheck.findCodeFile(modulePath, filePathArray, fileNameArray, true)
|
663
|
-
moduleArray << Module.new(moduleName, modulePath, fileNameArray, filePathArray)
|
664
|
-
}
|
665
|
-
|
666
|
-
return moduleArray
|
667
|
-
end
|
668
|
-
|
669
|
-
# 根据路径获取所有的代码文件
|
670
|
-
def ImportCheck.findCodeFile(des_path, filePathArray, fileNameArray, onlyDotH)
|
671
|
-
|
672
|
-
if not File.directory?(des_path)
|
673
|
-
puts "非文件夹, 请检查: #{des_path}"
|
674
|
-
return
|
675
|
-
end
|
676
|
-
|
677
|
-
Dir.foreach(des_path) { |fileName|
|
678
|
-
sub_path = des_path + "/" + fileName
|
679
|
-
if fileName.start_with?(".")
|
680
|
-
next
|
681
|
-
end
|
682
|
-
if File.directory?(sub_path)
|
683
|
-
ImportCheck.findCodeFile(sub_path, filePathArray, fileNameArray, onlyDotH)
|
684
|
-
else
|
685
|
-
|
686
|
-
onlyDotHCheck = (fileName.end_with?(".h") or fileName.end_with?(".pch"))
|
687
|
-
notOnlyDotHCheck = (fileName.end_with?(".h") or
|
688
|
-
fileName.end_with?(".m") or
|
689
|
-
fileName.end_with?(".pch") or
|
690
|
-
fileName.end_with?(".mm") or
|
691
|
-
fileName.end_with?(".hpp") or
|
692
|
-
fileName.end_with?(".cpp") or
|
693
|
-
fileName.end_with?(".c") or
|
694
|
-
fileName.end_with?(".cc"))
|
695
|
-
isCodeFile = onlyDotH ? onlyDotHCheck : notOnlyDotHCheck
|
696
|
-
if isCodeFile
|
697
|
-
filePath = des_path + "/" + fileName
|
698
|
-
filePathArray << filePath
|
699
|
-
fileNameArray << fileName
|
700
|
-
end
|
701
|
-
end
|
702
|
-
}
|
703
|
-
end
|
704
|
-
|
705
|
-
# 查找不在当前模块内的 #import "xx"
|
706
|
-
def ImportCheck.findBadQuoteImport(filePath, fileNameArray, badImportArray, moduleItem, whiteList)
|
707
|
-
lineArr = IO.readlines(filePath)
|
708
|
-
lineArr.each_with_index { |line, index|
|
709
|
-
unless line.start_with?("#import \"")
|
710
|
-
next
|
711
|
-
end
|
712
|
-
|
713
|
-
lineSplitArr = line.split("\"")
|
714
|
-
if lineSplitArr.size < 2
|
715
|
-
next
|
716
|
-
end
|
717
|
-
|
718
|
-
content = line.gsub("\n", "")
|
719
|
-
importName = lineSplitArr.size >=2 ? lineSplitArr[1].gsub("\n", "") : content
|
720
|
-
|
721
|
-
if ImportCheck.importInWihte(importName, whiteList)
|
722
|
-
next
|
723
|
-
end
|
724
|
-
|
725
|
-
if fileNameArray.include?(importName)
|
726
|
-
next
|
727
|
-
end
|
728
|
-
|
729
|
-
fileName = File.basename(filePath)
|
730
|
-
lineIndex = index+1
|
731
|
-
pod = nil
|
732
|
-
|
733
|
-
badImportArray << Import.new(content, importName, moduleItem, fileName, lineIndex, pod)
|
734
|
-
}
|
735
|
-
end
|
736
|
-
|
737
|
-
def ImportCheck.importInWihte(importName, whiteList)
|
738
|
-
whiteList.each {|whiteItem|
|
739
|
-
if whiteItem.include?(importName)
|
740
|
-
return true
|
741
|
-
end
|
742
|
-
}
|
743
|
-
return false
|
744
|
-
end
|
745
|
-
|
746
|
-
def ImportCheck.findCheckModules(checkModules, yaml_module)
|
747
|
-
|
748
|
-
unless File.exist?(yaml_module)
|
749
|
-
return
|
750
|
-
end
|
751
|
-
|
752
|
-
# 内容读取
|
753
|
-
dependencies_local = YAML.load_file(yaml_module)
|
754
|
-
|
755
|
-
unless dependencies_local.class == Hash
|
756
|
-
return
|
757
|
-
end
|
758
|
-
|
759
|
-
dependencies = dependencies_local['PODS']
|
760
|
-
unless dependencies
|
761
|
-
return
|
762
|
-
end
|
763
|
-
|
764
|
-
dependencies.each { |dependency|
|
765
|
-
dependencyPath = dependency["path"]
|
766
|
-
if dependencyPath and dependencyPath != "null" and dependencyPath.gsub(" ", "").length>0 then
|
767
|
-
moduleName = dependency["pod"]
|
768
|
-
modulePath = PathUtil.expandPath(dependencyPath)
|
769
|
-
fileNameArray = []
|
770
|
-
filePathArray = []
|
771
|
-
ImportCheck.findCodeFile(modulePath, filePathArray, fileNameArray, true)
|
772
|
-
checkModules << Module.new(moduleName, modulePath, fileNameArray, filePathArray)
|
773
|
-
end
|
774
|
-
}
|
775
|
-
|
776
|
-
end
|
777
|
-
|
778
|
-
end
|
779
|
-
|
780
|
-
class PathUtil
|
781
|
-
|
782
|
-
def PathUtil.expandPath(des_path)
|
783
|
-
return File.expand_path(des_path).gsub("\n", "")
|
784
|
-
end
|
785
|
-
|
786
|
-
def PathUtil.replaceStr(file_path, findstr, replacestr)
|
787
|
-
unless File.exist?(file_path)
|
788
|
-
return
|
789
|
-
end
|
790
|
-
|
791
|
-
FileUtils.chmod("+w", file_path)
|
792
|
-
text = File.read(file_path)
|
793
|
-
replace = text.gsub(findstr, replacestr)
|
794
|
-
if text != replace
|
795
|
-
File.open(file_path, "w") { |file| file.puts replace }
|
796
|
-
STDOUT.flush
|
797
|
-
file_name = File.basename(file_path)
|
798
|
-
puts "代码替换: #{file_name} (#{findstr} => #{replacestr})"
|
799
|
-
end
|
18
|
+
# 兼容旧的方式
|
19
|
+
module PodfileDep
|
20
|
+
def PodfileDep.setup(targets)
|
21
|
+
res = Pod::YamlRelies.analysis_yaml(nil, true)
|
22
|
+
warn "\n⚠️ [PodfileDep.setup方法已过期],请使用新的方式, 参考:https://gitee.com/sourceiOS/podfileDepDemo/blob/master/Podfile\n"
|
23
|
+
res
|
800
24
|
end
|
801
25
|
|
802
26
|
end
|
803
|
-
|
804
|
-
module SpecialDeal
|
805
|
-
def SpecialDeal.FBRetainCycleDetector()
|
806
|
-
PathUtil.replaceStr("Pods/FBRetainCycleDetector/FBRetainCycleDetector/Layout/Classes/FBClassStrongLayout.mm", "layoutCache[currentClass] = ivars;", "layoutCache[(id<NSCopying>)currentClass] = ivars;")
|
807
|
-
PathUtil.replaceStr("Pods/FBRetainCycleDetector/fishhook/fishhook.c", "indirect_symbol_bindings[i] = cur->rebindings[j].replacement;", "if(i < (sizeof(indirect_symbol_bindings) /sizeof(indirect_symbol_bindings[0]))) {indirect_symbol_bindings[i]=cur->rebindings[j].replacement;}")
|
808
|
-
|
809
|
-
newStr = "#import <objc/runtime.h>
|
810
|
-
#import <malloc/malloc.h>"
|
811
|
-
PathUtil.replaceStr("Pods/FBRetainCycleDetector/FBRetainCycleDetector/Graph/FBObjectiveCGraphElement.mm", "#import <objc/runtime.h>", newStr)
|
812
|
-
|
813
|
-
newStr = "malloc_zone_t *zone = malloc_zone_from_ptr((__bridge void *)object); if (zone) { Class aCls=object_getClass(object);"
|
814
|
-
PathUtil.replaceStr("Pods/FBRetainCycleDetector/FBRetainCycleDetector/Graph/FBObjectiveCGraphElement.mm", "Class aCls = object_getClass(object);", newStr)
|
815
|
-
|
816
|
-
newStr = "}
|
817
|
-
# endif"
|
818
|
-
PathUtil.replaceStr("Pods/FBRetainCycleDetector/FBRetainCycleDetector/Graph/FBObjectiveCGraphElement.mm", "#endif", newStr)
|
819
|
-
|
820
|
-
end
|
821
|
-
end
|
822
|
-
|
823
|
-
END {
|
824
|
-
SpecialDeal.FBRetainCycleDetector()
|
825
|
-
ImportCheck.check()
|
826
|
-
PodfileDep.logIndirectDependencies()
|
827
|
-
PodfileDep.logUnusedDependencies()
|
828
|
-
}
|