Class: Pod::YamlDep

Inherits:
Object
  • Object
show all
Defined in:
lib/podfileDep/yaml/yaml_dep.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeYamlDep

Returns a new instance of YamlDep.



32
33
34
35
36
37
38
39
40
41
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 32

def initialize
  super
  @targets = []
  @yaml_deps = {}
  @all_deps = {}
  @targets_dependencies = {}
  @podfile_local_yaml = MyConstants::PODFILE_LOCAL_YAML
  @podfile_module_yaml = MyConstants::PODFILE_MODULE_YAML
  @podfile_third_party_yaml = MyConstants::PODFILE_THIRD_PARTY_YAML
end

Instance Attribute Details

#all_depsString, [Pod:YamlPod]

解析后生成主工程里所有yaml文件定义的依赖

Returns:

  • (String, [Pod:YamlPod])


22
23
24
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 22

def all_deps
  @all_deps
end

#podfile_local_yamlObject

Returns the value of attribute podfile_local_yaml.



28
29
30
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 28

def podfile_local_yaml
  @podfile_local_yaml
end

#podfile_module_yamlObject

Returns the value of attribute podfile_module_yaml.



29
30
31
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 29

def podfile_module_yaml
  @podfile_module_yaml
end

#podfile_third_party_yamlObject

Returns the value of attribute podfile_third_party_yaml.



30
31
32
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 30

def podfile_third_party_yaml
  @podfile_third_party_yaml
end

#targetsString

主工程target列表

Returns:

  • (String)


14
15
16
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 14

def targets
  @targets
end

#targets_dependenciesString, [Pod:YamlPod]

所有的targets对应的依赖库列表

Returns:

  • (String, [Pod:YamlPod])


26
27
28
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 26

def targets_dependencies
  @targets_dependencies
end

#yaml_depsString, {String, [Pod:YamlPod]}

主工程里所有yaml文件定义的依赖

Returns:

  • (String, {String, [Pod:YamlPod]})


18
19
20
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 18

def yaml_deps
  @yaml_deps
end

Instance Method Details

#analysis_yaml_depObject

获取非扩展target定义在yaml文件的依赖

Returns:

  • targets_dependencies



71
72
73
74
75
76
77
78
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 71

def analysis_yaml_dep
  init_main_targets
  generate_yaml
  read_yaml_deps
  analyzing_yaml_deps
  print_yaml_deps
  resolve_targets_deps
end

#analyzing_yaml_depsObject

解析所有的依赖



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 99

def analyzing_yaml_deps
  yaml_deps.each do |yaml_name, deps|
    if yaml_name == podfile_local_yaml
      clean = false #记录只能清一次就够了
      deps.each { |name, dep|
        real_name = name.split("/")[0]
        # 有子模块 把之前的全部清空
        if Array(dep.subspecs).size > 0 or Array(dep.configurations).size > 0
          unless clean
            all_deps.delete_if{|pod_name|
              real_pod_name = pod_name.split("/")[0]
              if real_pod_name == real_name
                puts "#{pod_name} 被#{yaml_name}覆盖".green
              end
              real_pod_name == real_name
            }
            clean = true
          end
        end

        if all_deps.has_key?(name)
          puts "#{name} 被#{yaml_name}覆盖".green
        end

        all_deps[name] = dep
      }
    else
      @all_deps.merge!(deps)
    end

  end
  all_deps
end

#check_only_one_dep(dependency, key, current_type, yaml_name) ⇒ Object



302
303
304
305
306
307
308
309
310
311
312
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 302

def check_only_one_dep(dependency, key, current_type, yaml_name)
  if dependency[key]
    if current_type
      puts "#{yaml_name} - #{dependency['pod']}: #{current_type}字段和#{key}只能使用其中一个,请删除不需要的一个"
      exit!
    else
      return key
    end
  end
  current_type
end

#check_pod(dependency, yaml_name, dependencies_name) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 231

def check_pod(dependency, yaml_name, dependencies_name)
  # 不支持提醒
  available_keys = %w[module pod subspecs path podspec version git tag branch configurations inhibit_warnings source binary]
  dependency.each_key { |key|
    unless available_keys.include?(key)
      gem_name = "podfileDep"
      puts "❌ #{yaml_name}: 当前#{gem_name}版本(#{PodfileDep::VERSION})不支持字段#{key}".red
      puts "请检查对应字段或尝试执行如下命令升级"
      puts "gem uninstall #{gem_name} && gem install #{gem_name}"
      exit!
    end
  }

  # 校验字段
  unless dependency['pod']
    puts "#{yaml_name}: pod 字段(组件名字)必须存在,请检查:"
    exit!
  end

  current_type = nil
  current_type = check_only_one_dep(dependency, "path", current_type, yaml_name)
  current_type = check_only_one_dep(dependency, "podspec", current_type, yaml_name)
  current_type = check_only_one_dep(dependency, "version", current_type, yaml_name)
  current_type = check_only_one_dep(dependency, "tag", current_type, yaml_name)
  current_type = check_only_one_dep(dependency, "branch", current_type, yaml_name)

  unless current_type
    puts "#{yaml_name} - #{dependency['pod']}: path/podspec/version/git/tag/branch 字段请指定其中一个"
    exit!
  end

  unless dependency['git']
    if dependency['tag']
      puts "#{yaml_name} - #{dependency['pod']}: 你指定了tag,但未配置git地址,请为此组件配置git字段"
      exit!
    end
    if dependency['branch']
      puts "#{yaml_name} - #{dependency['pod']}: 你指定了branch,但未配置git地址,请为此组件配置git字段"
      exit!
    end
  end

  #  检查数据类型
  if dependency['configurations'] and dependency['configurations'].class != Array
    puts "#{yaml_name} - #{dependency['pod']} - #{dependency['configurations']}: configurations字段必须是数组,例如:['Debug','Release']"
    exit!
  end

  if dependency['subspecs'] and dependency['subspecs'].class != Array
    puts "#{yaml_name} - #{dependency['pod']} - #{dependency['subspecs']}: subspecs字段必须是数组,例如:['A','B','C']"
    exit!
  end

  # 校验自身文件重复
  if dependencies_name.include?(dependency['pod'])
    puts "❌ 发现#{yaml_name}内重复组件:#{dependency['pod']},请检查并删除重复依赖:".red
    exit!
  else
    dependencies_name << dependency['pod']
  end

  # 警告
  if dependency['path'] and yaml_name != podfile_local_yaml
    warn "⚠️  组件#{dependency['pod']}使用path依赖方式应该写在#{podfile_local_yaml}".yellow
  end
  if dependency['podspec'] and yaml_name != podfile_local_yaml
    warn "⚠️  组件#{dependency['pod']}使用podspec依赖方式应该写在#{podfile_local_yaml}".yellow
  end

end

#disable_check_podspecObject

是否禁用检查podspec文件



542
543
544
545
546
547
548
549
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 542

def disable_check_podspec
  yaml_content = read_yaml_content(podfile_local_yaml)
  disable_check_podspec = yaml_content ? !!(yaml_content["DISABLE_CHECK_PODSPEC"]) : false
  if disable_check_podspec
    puts "已关闭podspec文件检查,如需开启,请在#{podfile_local_yaml}里设置DISABLE_CHECK_PODSPEC为false"
  end
  disable_check_podspec
end

#generate_local_yaml(podfile_local_yaml) ⇒ Object



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 409

def generate_local_yaml(podfile_local_yaml)
  if File.exist?(podfile_local_yaml)
    return
  end
  puts "生成#{podfile_local_yaml}文件"

  content = ""
  content = content + "# 1、本依赖配置文件优先级最高, 用来覆盖其他两个依赖的yaml文件中的组件。 尝试打开以下注释, 修改对应字段, 然后执行pod install\n"
  content = content + "# 2、PODS下边的配置是数组形式, 如果有多个就写多个(subspecs需要数组)\n"
  content = content + "# 3、本文件加入到忽略文件中\n\n"

  content = content + "# QUICK_BUILD字段如果为true, 则表示会自动解析所有组件的依赖, 并删除不被使用的依赖库, 以达到开发时快速编译的目的\n"
  content = content + "QUICK_BUILD: false\n\n"

  content = content + "PODS:\n"

  content = content + "\n"

  content = content + "# - module: Masonry\n"
  content = content + "#   pod: Masonry\n"
  content = content + "#   subspecs: null\n"
  content = content + "#   path: ~/MasonryCodePath\n"

  content = content + "\n"

  content = content + "# - module: MJExtension\n"
  content = content + "#   pod: MJExtension\n"
  content = content + "#   subspecs: null\n"
  content = content + "#   path: ~/MJExtensionCodePath\n"

  File.open(podfile_local_yaml, 'w') { |file|
    file.write(content)
  }
end

#generate_module_yaml(yaml_name, prefix) ⇒ Object



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 444

def generate_module_yaml(yaml_name, prefix)
  if File.exist?(yaml_name)
    return
  end
  puts "生成#{yaml_name}文件"

  content = ""
  content = content + prefix
  content = content + "\n"
  content = content + "# 1、优先级:path > podspec > version > tag > branch\n"
  content = content + "# 2、path字段就是直接从对应的路径读取依赖\n"
  content = content + "# 3、podspec字段就是直接从对应的路径读取podspec文件加载依赖\n"
  content = content + "# 4、当version不为空时,会取source字段的repo获取组件,如果source字段为空,那么就取文件顶部配置的默认SOURCE\n"
  content = content + "# 5、当tag字段或branch字段不为空时,会取git字段的地址获取代码\n"
  content = content + "\n"
  content = content + "# 如果 source = null && binary = false 则source默认使用SOURCE\n"
  content = content + "# 如果 source = null && binary = true  则source默认使用BINARY_SOURCE\n"
  content = content + "SOURCE: 这里替换成源码的source\n"
  content = content + "BINARY_SOURCE: 这里替换成二进制的source\n"
  content = content + "\n"
  content = content + "PODS:\n"
  content = content + "\n"
  content = content + "# - module: XXX\n"
  content = content + "#   pod: XXX\n"
  content = content + "#   subspecs: null\n"
  content = content + "#   podspec: null\n"
  content = content + "#   version: 1.0.0\n"
  content = content + "#   git: null\n"
  content = content + "#   tag: null\n"
  content = content + "#   branch: null\n"
  content = content + "#   configurations: null\n"
  content = content + "#   inhibit_warnings: true\n"
  content = content + "#   source: null\n"
  content = content + "#   binary: true\n"

  File.open(yaml_name, 'w') { |file|
    file.write(content)
  }
end

#generate_yamlObject

生成默认yaml文件



403
404
405
406
407
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 403

def generate_yaml
  generate_local_yaml(podfile_local_yaml)
  generate_module_yaml(podfile_module_yaml, "# 企业内部组件")
  generate_module_yaml(podfile_third_party_yaml, "# 第三方维护组件")
end

#init_main_targetsObject

读取主工程target列表



527
528
529
530
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 527

def init_main_targets
  project_manager = XCProject::XcodeprojManager.share_manager
  @targets = project_manager.get_app_targets
end

#install_dependencies(targets_dependencies, podfile) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 51

def install_dependencies(targets_dependencies, podfile)
  # 存储所有的依赖
  targets_dependencies.each { |target_obj, dependencies|
    target_name = target_obj.name
    podfile.target target_name do
      dependencies.each { |dependency|
        if dependency.version
          podfile.pod dependency.pod, dependency.version, dependency.option
        else
          podfile.pod dependency.pod, dependency.option
        end
      }
      yield(target_name) if block_given?
    end
  }
  targets
end

#install_yaml_dep(podfile) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 43

def install_yaml_dep(podfile)
  analysis_yaml_dep

  install_dependencies(targets_dependencies, podfile) do|name|
    yield(name) if block_given?
  end
end


336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 336

def print_yaml_deps
  yaml_deps.each do |yaml_name, deps|
    puts "读取#{yaml_name} => #{deps.size}个"
  end
  puts "➡️  解析后依赖总数共计:#{all_deps.size}个\n"

  sort_deps = all_deps.sort do |arr1, arr2|
    dep1 = arr1[1]
    dep2 = arr2[1]
    if dep1.type != dep2.type
      dep1.type < dep2.type ? 1 : -1
    else
      dep1.pod.downcase <=> dep2.pod.downcase
    end
  end

  puts '⬇️  打印依赖'
  current_dir = Dir.pwd
  sort_deps.each { |sort_dep|
    dependency = sort_dep[1]
    puts_result = "pod '#{dependency.pod}'"

    if dependency.path #路径引用
      puts_result += ", :path => '#{dependency.path}'"
    elsif dependency.podspec #podspec引用
      puts_result += ", :podspec => '#{dependency.podspec}'"
    elsif dependency.version #版本号引用
      puts_result += ", '#{dependency.version.to_s}'"
    elsif dependency.git #git仓库引用
      puts_result += ", :git => '#{dependency.git}'"
      if dependency.tag
        puts_result += ", :tag => '#{dependency.tag}'"
      elsif dependency.branch
        puts_result += ", :branch => '#{dependency.branch}'"
      end
    end

    if dependency.configurations
      puts_result += ", :configurations => ['#{dependency.configurations.join("','")}']"
    end
    if dependency.subspecs
      puts_result += ", :subspecs => ['#{dependency.subspecs.join("','")}']"
    end
    if dependency.inhibit_warnings
      puts_result += ", :inhibit_warnings => true"
    end
    if dependency.version and dependency.source
      puts_result += ", :source => '#{dependency.source}'"
    end

    if dependency.path
      branch = repo_branch(dependency.path)
      modify = repo_modify(dependency.path)
      puts puts_result.cyan + branch.magenta + modify.magenta

    elsif dependency.branch
      puts puts_result.yellow
    else
      puts puts_result
    end

  }
  Dir.chdir(current_dir)
  puts "⬆️  打印完毕"
end

#quick_buildObject

是否开启了编译优化开关



533
534
535
536
537
538
539
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 533

def quick_build
  yaml_content = read_yaml_content(podfile_local_yaml)
  if $quick_build != nil
    return $quick_build
  end
  yaml_content ? !!(yaml_content["QUICK_BUILD"]) : false
end

#read_yaml_content(yaml_name) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 314

def read_yaml_content(yaml_name)
  unless File.exist?(yaml_name)
    puts "文件不存在:"+yaml_name
    return nil
  end

  begin
    yaml_content = YAML.load_file(yaml_name)
  rescue Exception => e
    puts e
    puts yaml_name+'文件解析异常, 请检查 ⬆️'
    exit!
  end

  unless yaml_content.class == Hash
    puts "#{yaml_name} => (文件不是keyValue形式)"
    return nil
  end

  yaml_content
end

#read_yaml_depsObject

读取yaml文件的依赖



92
93
94
95
96
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 92

def read_yaml_deps
  read_yaml_deps_file(podfile_third_party_yaml)
  read_yaml_deps_file(podfile_module_yaml)
  read_yaml_deps_file(podfile_local_yaml)
end

#read_yaml_deps_file(yaml_name) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 133

def read_yaml_deps_file(yaml_name)

  yaml_content = read_yaml_content(yaml_name)

  unless yaml_content
    return
  end

  if yaml_name != podfile_local_yaml
    if not yaml_content["SOURCE"] or yaml_content["SOURCE"].class != String
      puts "#{yaml_name}的SOURCE字段必须是字符串且不为空"
      exit!
    end
    if yaml_name != podfile_local_yaml and not yaml_content["BINARY_SOURCE"] or yaml_content["BINARY_SOURCE"].class != String
      puts "#{yaml_name}的BINARY_SOURCE字段必须是字符串且不为空"
      exit!
    end
  end

  unless yaml_content["PODS"]
    puts "#{yaml_name}共0个依赖(文件内的key[PODS]不存在)"
    return
  end

  if yaml_content["PODS"].class != Array
    puts "#{yaml_name}共0个依赖(文件配置的依赖PODS项不是数组或数组为空)"
    return
  end

  # 读取默认源码source
  default_source_source = yaml_content['SOURCE']

  # 读取默认二进制source
  default_binary_source = yaml_content['BINARY_SOURCE']

  # 依赖列表
  dependencies_pods = yaml_content['PODS']

  # 当前yaml文件的组件名字 用来校验本文件内是否重复
  dependencies_name = []

  yaml_dependencies = {}

  # 遍历依赖库列表
  dependencies_pods.each { |dependency|

    check_pod(dependency, yaml_name, dependencies_name)

    # 默认值
    source = dependency['source']
    unless source
      source = dependency['binary'] ? default_binary_source : default_source_source
    end
    inhibit_warnings = dependency['inhibit_warnings'] ? !!dependency['inhibit_warnings'] : false
    binary = dependency['binary'] ? !!dependency['binary'] : true

    # configurations和subspecs cocoapods不能同时支持,所以要展开
    if Array(dependency['subspecs']).size > 0 and Array(dependency['configurations']).size > 0
      dependency['subspecs'].each {|subspec|
        dep = YamlPod.new(pod = "#{dependency['pod']}/#{subspec}")
        dep.module_name = dependency['module']
        dep.subspecs = nil
        dep.path = dependency['path']
        dep.podspec = dependency['podspec']
        dep.version = dependency['version']
        dep.git = dependency['git']
        dep.tag = dependency['tag']
        dep.branch = dependency['branch']
        dep.configurations = dependency['configurations']
        dep.inhibit_warnings = inhibit_warnings
        dep.source = source
        dep.binary = binary
        yaml_dependencies[dep.pod] = dep
      }

    else
      dep = YamlPod.new(pod = dependency['pod'])
      dep.module_name = dependency['module']
      dep.subspecs = dependency['subspecs']
      dep.path = dependency['path']
      dep.podspec = dependency['podspec']
      dep.version = dependency['version']
      dep.git = dependency['git']
      dep.tag = dependency['tag']
      dep.branch = dependency['branch']
      dep.configurations = dependency['configurations']
      dep.inhibit_warnings = inhibit_warnings
      dep.source = source
      dep.binary = binary
      yaml_dependencies[dep.pod] = dep
    end
  }

  yaml_deps[yaml_name] = yaml_dependencies

  yaml_dependencies
end

#repo_branch(path) ⇒ Object

获取某个目录下的当前分支



485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 485

def repo_branch(path)
  full_path = File.expand_path(path)
  git_path = "#{full_path}/.git"
  unless Dir.exist?(git_path)
    return ""
  end
  head_path = "#{git_path}/HEAD"
  unless File.exist?(head_path)
    return ""
  end

  content = File.read(head_path)
  content = content.gsub("\n", "")

  branch_key_word = "ref: refs/heads/"
  if content.include?(branch_key_word)
    branch = content.gsub(branch_key_word, "")
    return "(#{branch})"
  end

  if content.size >= 8
    short_sha = content.slice(0, 7)
    return "(#{short_sha})"
  end

  " #(#{content})"
end

#repo_modify(path) ⇒ Object

获取仓库状态是否有修改



514
515
516
517
518
519
520
521
522
523
524
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 514

def repo_modify(path)
  full_path = File.expand_path(path)
  git_path = "#{full_path}/.git"
  unless Dir.exist?(git_path)
    return ""
  end

  Dir.chdir(full_path)
  status = %x(git status -suno)
  status.size > 0 ? "[modified]" : ""
end

#resolve_targets_depsObject



80
81
82
83
84
85
86
87
88
89
# File 'lib/podfileDep/yaml/yaml_dep.rb', line 80

def resolve_targets_deps
  targets.each { |target|
    if target.product_type.end_with?(".application")
      targets_dependencies[target] = all_deps.values
    else
      targets_dependencies[target] = []
    end
  }
  targets_dependencies
end