cocoapods-meitu-bin 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +56 -0
  4. data/lib/cocoapods-meitu-bin/command/bin/archive.rb +206 -0
  5. data/lib/cocoapods-meitu-bin/command/bin/auto.rb +212 -0
  6. data/lib/cocoapods-meitu-bin/command/bin/build_all.rb +345 -0
  7. data/lib/cocoapods-meitu-bin/command/bin/header_files_specifications.rb +262 -0
  8. data/lib/cocoapods-meitu-bin/command/bin/init.rb +72 -0
  9. data/lib/cocoapods-meitu-bin/command/bin/install.rb +44 -0
  10. data/lib/cocoapods-meitu-bin/command/bin/lib/lint.rb +67 -0
  11. data/lib/cocoapods-meitu-bin/command/bin/lock/dependency.rb +89 -0
  12. data/lib/cocoapods-meitu-bin/command/bin/lock/spec_repo.rb +105 -0
  13. data/lib/cocoapods-meitu-bin/command/bin/lock/version.rb +68 -0
  14. data/lib/cocoapods-meitu-bin/command/bin/lock.rb +36 -0
  15. data/lib/cocoapods-meitu-bin/command/bin/output_source.rb +146 -0
  16. data/lib/cocoapods-meitu-bin/command/bin/repo/push.rb +88 -0
  17. data/lib/cocoapods-meitu-bin/command/bin/repo/update.rb +42 -0
  18. data/lib/cocoapods-meitu-bin/command/bin/repo.rb +14 -0
  19. data/lib/cocoapods-meitu-bin/command/bin/source/add.rb +148 -0
  20. data/lib/cocoapods-meitu-bin/command/bin/source/delete.rb +59 -0
  21. data/lib/cocoapods-meitu-bin/command/bin/source/list.rb +46 -0
  22. data/lib/cocoapods-meitu-bin/command/bin/source.rb +30 -0
  23. data/lib/cocoapods-meitu-bin/command/bin/spec/create.rb +73 -0
  24. data/lib/cocoapods-meitu-bin/command/bin/spec/lint.rb +109 -0
  25. data/lib/cocoapods-meitu-bin/command/bin/spec.rb +13 -0
  26. data/lib/cocoapods-meitu-bin/command/bin/update.rb +154 -0
  27. data/lib/cocoapods-meitu-bin/command/bin/upload.rb +175 -0
  28. data/lib/cocoapods-meitu-bin/command/bin.rb +69 -0
  29. data/lib/cocoapods-meitu-bin/command.rb +1 -0
  30. data/lib/cocoapods-meitu-bin/config/config.rb +149 -0
  31. data/lib/cocoapods-meitu-bin/config/config_asker.rb +57 -0
  32. data/lib/cocoapods-meitu-bin/config/config_builder.rb +216 -0
  33. data/lib/cocoapods-meitu-bin/gem_version.rb +9 -0
  34. data/lib/cocoapods-meitu-bin/helpers/Info.plist +0 -0
  35. data/lib/cocoapods-meitu-bin/helpers/buildAll/bin_helper.rb +97 -0
  36. data/lib/cocoapods-meitu-bin/helpers/buildAll/builder.rb +434 -0
  37. data/lib/cocoapods-meitu-bin/helpers/buildAll/podspec_util.rb +140 -0
  38. data/lib/cocoapods-meitu-bin/helpers/buildAll/zip_file_helper.rb +87 -0
  39. data/lib/cocoapods-meitu-bin/helpers/build_helper.rb +167 -0
  40. data/lib/cocoapods-meitu-bin/helpers/build_utils.rb +64 -0
  41. data/lib/cocoapods-meitu-bin/helpers/framework.rb +86 -0
  42. data/lib/cocoapods-meitu-bin/helpers/framework_builder.rb +551 -0
  43. data/lib/cocoapods-meitu-bin/helpers/library.rb +54 -0
  44. data/lib/cocoapods-meitu-bin/helpers/library_builder.rb +90 -0
  45. data/lib/cocoapods-meitu-bin/helpers/pod_size_helper.rb +54 -0
  46. data/lib/cocoapods-meitu-bin/helpers/sources_helper.rb +35 -0
  47. data/lib/cocoapods-meitu-bin/helpers/spec_creator.rb +170 -0
  48. data/lib/cocoapods-meitu-bin/helpers/spec_files_helper.rb +80 -0
  49. data/lib/cocoapods-meitu-bin/helpers/spec_source_creator.rb +304 -0
  50. data/lib/cocoapods-meitu-bin/helpers/upload_helper.rb +104 -0
  51. data/lib/cocoapods-meitu-bin/helpers.rb +5 -0
  52. data/lib/cocoapods-meitu-bin/native/acknowledgements.rb +27 -0
  53. data/lib/cocoapods-meitu-bin/native/analyzer.rb +109 -0
  54. data/lib/cocoapods-meitu-bin/native/file_accessor.rb +28 -0
  55. data/lib/cocoapods-meitu-bin/native/gen.rb +79 -0
  56. data/lib/cocoapods-meitu-bin/native/installation_options.rb +28 -0
  57. data/lib/cocoapods-meitu-bin/native/installer.rb +259 -0
  58. data/lib/cocoapods-meitu-bin/native/linter.rb +26 -0
  59. data/lib/cocoapods-meitu-bin/native/lockfile.rb +85 -0
  60. data/lib/cocoapods-meitu-bin/native/path_source.rb +33 -0
  61. data/lib/cocoapods-meitu-bin/native/pod_source_installer.rb +19 -0
  62. data/lib/cocoapods-meitu-bin/native/pod_target_installer.rb +87 -0
  63. data/lib/cocoapods-meitu-bin/native/podfile.rb +99 -0
  64. data/lib/cocoapods-meitu-bin/native/podfile_env.rb +38 -0
  65. data/lib/cocoapods-meitu-bin/native/podfile_generator.rb +201 -0
  66. data/lib/cocoapods-meitu-bin/native/podspec_finder.rb +25 -0
  67. data/lib/cocoapods-meitu-bin/native/resolver.rb +299 -0
  68. data/lib/cocoapods-meitu-bin/native/sandbox_analyzer.rb +34 -0
  69. data/lib/cocoapods-meitu-bin/native/source.rb +35 -0
  70. data/lib/cocoapods-meitu-bin/native/sources_manager.rb +21 -0
  71. data/lib/cocoapods-meitu-bin/native/specification.rb +31 -0
  72. data/lib/cocoapods-meitu-bin/native/target_validator.rb +41 -0
  73. data/lib/cocoapods-meitu-bin/native/validator.rb +40 -0
  74. data/lib/cocoapods-meitu-bin/native.rb +26 -0
  75. data/lib/cocoapods-meitu-bin/source_provider_hook.rb +68 -0
  76. data/lib/cocoapods-meitu-bin.rb +2 -0
  77. data/lib/cocoapods_plugin.rb +11 -0
  78. data/spec/command/bin_spec.rb +12 -0
  79. data/spec/spec_helper.rb +50 -0
  80. metadata +201 -0
@@ -0,0 +1,345 @@
1
+ require 'cocoapods-meitu-bin/helpers/buildAll/builder'
2
+ require 'cocoapods-meitu-bin/helpers/buildAll/podspec_util'
3
+ require 'cocoapods-meitu-bin/helpers/buildAll/zip_file_helper'
4
+ require 'cocoapods-meitu-bin/helpers/buildAll/bin_helper'
5
+ require 'cocoapods-meitu-bin/config/config'
6
+ require 'yaml'
7
+ require 'digest'
8
+
9
+ module Pod
10
+ class Command
11
+ class Bin < Command
12
+ class BuildAll < Bin
13
+ include CBin::BuildAll
14
+
15
+ CDN = 'https://cdn.cocoapods.org/'.freeze
16
+ MASTER_HTTP = 'https://github.com/CocoaPods/Specs.git'.freeze
17
+ MASTER_SSH = 'git@github.com:CocoaPods/Specs.git'.freeze
18
+
19
+ self.summary = '根据壳工程打包所有依赖组件为静态库(static framework)'
20
+ self.description = <<-DESC
21
+ #{summary},参数 PODS 可选,如果添加 PODS 则只制作 PODS 包含的库,多个库中间用逗号分隔
22
+ DESC
23
+
24
+ self.arguments = [
25
+ CLAide::Argument.new('PODS', false)
26
+ ]
27
+
28
+ def self.options
29
+ [
30
+ %w[--clean 全部二进制包制作完成后删除编译临时目录],
31
+ %w[--clean-single 每制作完一个二进制包就删除该编译临时目录],
32
+ %w[--repo-update 更新Podfile中指定的repo仓库],
33
+ %w[--full-build 是否全量打包],
34
+ %w[--skip-simulator 跳过模拟器编译],
35
+ %w[--configuration=configName 在构建每个目标时使用configName指定构建配置,如:'Debug'、'Release'等]
36
+ ].concat(super).uniq
37
+ end
38
+
39
+ def initialize(argv)
40
+ @pods = argv.shift_argument
41
+ @clean = argv.flag?('clean', false)
42
+ @clean_single = argv.flag?('clean-single', false)
43
+ @repo_update = argv.flag?('repo-update', false)
44
+ @full_build = argv.flag?('full-build', false)
45
+ @skip_simulator = argv.flag?('skip-simulator', false)
46
+ @configuration = argv.option('configuration', 'Debug')
47
+ @base_dir = "#{Pathname.pwd}/build_pods"
48
+ @version_helper = BinHelper.new
49
+ super
50
+ end
51
+
52
+ def run
53
+ CBin.config.config_file_exist?
54
+ # 打印提示
55
+ print_tip
56
+ # 开始时间
57
+ @start_time = Time.now.to_i
58
+ # 读取配置文件
59
+ read_config
60
+ # 如果有传入要制作的pod库名
61
+ if @pods
62
+ @write_list = @pods.split(',').map(&:strip)
63
+ end
64
+ # 更新repo仓库
65
+ repo_update
66
+ # 执行pre_build命令
67
+ pre_build
68
+ # 分析依赖
69
+ @analyze_result = analyse
70
+ # 删除编译产物
71
+ clean_build_pods
72
+ # 编译所有pod_targets
73
+ results = build_pod_targets
74
+ # 执行post_build命令
75
+ post_build(results)
76
+ # 删除编译产物
77
+ clean_build_pods if @clean
78
+ # 计算耗时
79
+ show_cost_time
80
+ end
81
+
82
+ private
83
+
84
+ def print_tip
85
+ UI.info '——————————————————————————————————'.blue
86
+ UI.info "|#{' '.center(32)}|".blue
87
+ UI.info "|#{"Configuration:`#{@configuration}`".center(32)}|".blue
88
+ UI.info "|#{' '.center(32)}|".blue
89
+ UI.info '——————————————————————————————————'.blue
90
+ end
91
+
92
+ # 打印耗时
93
+ def show_cost_time
94
+ return if @start_time.nil?
95
+ UI.info "总耗时:#{Time.now.to_i - @start_time}s".green
96
+ end
97
+
98
+ # 读取配置文件
99
+ def read_config
100
+ UI.title 'Read config from file `BinConfig.yaml`'.green do
101
+ config_file = File.join(Pod::Config.instance.project_root, 'BinConfig.yaml')
102
+ return unless File.exist?(config_file)
103
+ config = YAML.safe_load(File.open(config_file))
104
+ return if config.nil?
105
+ build_config = config['build_config']
106
+ return if build_config.nil?
107
+ @pre_build = build_config['pre_build']
108
+ @post_build = build_config['post_build']
109
+ @black_list = build_config['black_list']
110
+ @write_list = build_config['write_list']
111
+ end
112
+ end
113
+
114
+ # 更新repo仓库
115
+ def repo_update
116
+ if @repo_update
117
+ UI.title 'Repo update'.green do
118
+ return if podfile.nil?
119
+ sources_manager = Pod::Config.instance.sources_manager
120
+ podfile.sources.uniq.map do |src|
121
+ UI.message "Update repo: #{src}"
122
+ source = sources_manager.source_with_name_or_url(src)
123
+ source.update(false)
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ # 执行pre build
130
+ def pre_build
131
+ if @pre_build
132
+ UI.title 'Execute the command of pre build'.green do
133
+ system(@pre_build)
134
+ end
135
+ end
136
+ end
137
+
138
+ # 执行post build
139
+ def post_build(_results)
140
+ if @post_build
141
+ UI.title 'Execute the command of post build'.green do
142
+ system(@post_build)
143
+ end
144
+ end
145
+ end
146
+
147
+ # 获取 podfile
148
+ def podfile
149
+ @podfile ||= begin
150
+ podfile_path = File.join(Pathname.pwd, 'Podfile')
151
+ raise Informative, 'Podfile不存在' unless File.exist?(podfile_path)
152
+ sources_manager = Pod::Config.instance.sources_manager
153
+ podfile = Podfile.from_file(Pathname.new(podfile_path))
154
+ podfile_hash = podfile.to_hash
155
+ podfile_hash['sources'] = (podfile_hash['sources'] || []).concat(sources_manager.code_source_list.map(&:url))
156
+ podfile_hash['sources'] << sources_manager.binary_source.url
157
+ podfile_hash['sources'].uniq!
158
+ Podfile.from_hash(podfile_hash)
159
+ end
160
+ end
161
+
162
+ # 获取 podfile.lock
163
+ def lockfile
164
+ @lockfile ||= begin
165
+ lock_path = File.join(Pathname.pwd, 'Podfile.lock')
166
+ raise Informative, 'Podfile.lock不存在,请执行pod install' unless File.exist?(lock_path)
167
+ Lockfile.from_file(Pathname.new(lock_path))
168
+ end
169
+ end
170
+
171
+ # 获取 sandbox
172
+ def sandbox
173
+ @sandbox ||= begin
174
+ sandbox_path = File.join(Pathname.pwd, 'Pods')
175
+ raise Informative, 'Pods文件夹不存在,请执行pod install' unless File.exist?(sandbox_path)
176
+ Pod::Sandbox.new(sandbox_path)
177
+ end
178
+ end
179
+
180
+ # 根据podfile和podfile.lock分析依赖
181
+ def analyse
182
+ UI.title 'Analyze dependencies'.green do
183
+ analyzer = Pod::Installer::Analyzer.new(
184
+ sandbox,
185
+ podfile,
186
+ lockfile
187
+ )
188
+ analyzer.analyze(true)
189
+ end
190
+ end
191
+
192
+ # 删除单个Pod的编译中间产物
193
+ def clean_single_build_pod(pod_target)
194
+ UI.title "Clean build pod: `#{pod_target}`".green do
195
+ build_pod_path = File.join(Dir.pwd, 'build_pods', "#{pod_target}")
196
+ FileUtils.rm_rf(build_pod_path) if File.exist?(build_pod_path)
197
+ end
198
+ end
199
+
200
+ # 删除编译产物
201
+ def clean_build_pods
202
+ UI.title 'Clean build pods'.green do
203
+ build_path = Dir.pwd + '/build'
204
+ FileUtils.rm_rf(build_path) if File.exist?(build_path)
205
+ build_pods_path = Dir.pwd + '/build_pods'
206
+ FileUtils.rm_rf(build_pods_path) if File.exist?(build_pods_path)
207
+ end
208
+ end
209
+
210
+ # 构建所有pod_targets
211
+ def build_pod_targets
212
+ UI.title "Build all pod targets(#{@full_build ? '全量打包' : '非全量打包'})".green do
213
+ pod_targets = @analyze_result.pod_targets.uniq
214
+ success_pods = []
215
+ fail_pods = []
216
+ local_pods = []
217
+ external_pods = []
218
+ binary_pods = []
219
+ created_pods = []
220
+ pod_targets.map do |pod_target|
221
+ begin
222
+ version = @version_helper.version(pod_target.pod_name, pod_target.root_spec.version.to_s, @analyze_result.specifications, @configuration)
223
+ # 黑名单(不分全量和非全量)
224
+ next if skip_build?(pod_target)
225
+ # 白名单(有白名单,只看白名单,不分全量和非全量)
226
+ next if !@write_list.nil? && !@write_list.empty? && !@write_list.include?(pod_target.pod_name)
227
+ # 本地库
228
+ if @sandbox.local?(pod_target.pod_name)
229
+ local_pods << pod_target.pod_name
230
+ show_skip_tip("#{pod_target.pod_name} 是本地库")
231
+ next
232
+ end
233
+ # 外部源(如 git)
234
+ if @sandbox.checkout_sources[pod_target.pod_name]
235
+ external_pods << pod_target.pod_name
236
+ show_skip_tip("#{pod_target.pod_name} 以external方式引入")
237
+ next
238
+ end
239
+ # 无源码
240
+ if !@sandbox.local?(pod_target.pod_name) && !pod_target.should_build?
241
+ binary_pods << pod_target.pod_name
242
+ show_skip_tip("#{pod_target.pod_name} 无需编译")
243
+ next
244
+ end
245
+ # 非全量编译、不在白名单中且已经有相应的二进制版本
246
+ if has_created_binary?(pod_target.pod_name, version)
247
+ created_pods << pod_target.pod_name
248
+ show_skip_tip("#{pod_target.pod_name}(#{version}) 已经有二进制版本了")
249
+ next
250
+ end
251
+ # 构建产物
252
+ builder = Builder.new(pod_target, @sandbox.checkout_sources, @skip_simulator, @configuration)
253
+ result = builder.build
254
+ fail_pods << pod_target.pod_name unless result
255
+ next unless result
256
+ builder.create_binary
257
+ # 压缩并上传zip
258
+ zip_helper = ZipFileHelper.new(pod_target, version, builder.product_dir, builder.build_as_framework?, @configuration)
259
+ result = zip_helper.zip_lib
260
+ fail_pods << pod_target.pod_name unless result
261
+ next unless result
262
+ result = zip_helper.upload_zip_lib
263
+ fail_pods << pod_target.pod_name unless result
264
+ next unless result
265
+ # 生成二进制podspec并上传
266
+ podspec_creator = PodspecUtil.new(pod_target, version, builder.build_as_framework?, @configuration)
267
+ bin_spec = podspec_creator.create_binary_podspec
268
+ bin_spec_file = podspec_creator.write_binary_podspec(bin_spec)
269
+ result = podspec_creator.push_binary_podspec(bin_spec_file)
270
+ fail_pods << pod_target.pod_name unless result
271
+ success_pods << pod_target.pod_name if result
272
+ rescue Pod::StandardError => e
273
+ UI.info "`#{pod_target}`编译失败,原因:#{e}".red
274
+ fail_pods << pod_target.pod_name
275
+ next
276
+ ensure
277
+ clean_single_build_pod(pod_target) if @clean_single
278
+ end
279
+ end
280
+ results = {
281
+ 'Total' => pod_targets,
282
+ 'Success' => success_pods,
283
+ 'Fail' => fail_pods,
284
+ 'Local' => local_pods,
285
+ 'External' => external_pods,
286
+ 'No Source File' => binary_pods,
287
+ 'Created Binary' => created_pods,
288
+ 'Black List' => @black_list || [],
289
+ 'Write List' => @write_list || []
290
+ }
291
+ show_results(results)
292
+ results
293
+ end
294
+ end
295
+
296
+ def show_skip_tip(title)
297
+ UI.info title.yellow
298
+ end
299
+
300
+ # 是否跳过编译
301
+ def skip_build?(pod_target)
302
+ !@black_list.nil? && !@black_list.empty? && @black_list.include?(pod_target.pod_name)
303
+ end
304
+
305
+ # 展示结果
306
+ def show_results(results)
307
+ UI.title '打包结果:'.green do
308
+ UI.info '——————————————————————————————————'.green
309
+ UI.info "|#{'Type'.center(20)}|#{'Count'.center(11)}|".green
310
+ UI.info '——————————————————————————————————'.green
311
+ results.each do |key, value|
312
+ UI.info "|#{key.center(20)}|#{value.size.to_s.center(11)}|".green
313
+ end
314
+ UI.info '——————————————————————————————————'.green
315
+
316
+ # 打印出失败的 target
317
+ unless results['Fail'].empty?
318
+ UI.info "\n打包失败的库:#{results['Fail']}".red
319
+ end
320
+ end
321
+ end
322
+
323
+ # 是否已经有二进制版本了
324
+ def has_created_binary?(pod_name, version)
325
+ # name 或 version 为nil
326
+ return false if pod_name.nil? || version.nil?
327
+ # 是否全量打包
328
+ return false if @full_build
329
+ # 是否在白名单中
330
+ return false if !@write_list.nil? && !@write_list.empty? && @write_list.include?(pod_name)
331
+ sources_manager = Config.instance.sources_manager
332
+ binary_source = sources_manager.binary_source
333
+ result = false
334
+ begin
335
+ specification = binary_source.specification(pod_name, version)
336
+ result = true unless specification.nil?
337
+ rescue Pod::StandardError => e
338
+ result = false
339
+ end
340
+ result
341
+ end
342
+ end
343
+ end
344
+ end
345
+ end
@@ -0,0 +1,262 @@
1
+ require 'cocoapods-meitu-bin/helpers/buildAll/builder'
2
+ require 'cocoapods-meitu-bin/helpers/buildAll/podspec_util'
3
+ require 'cocoapods-meitu-bin/helpers/buildAll/zip_file_helper'
4
+ require 'cocoapods-meitu-bin/helpers/buildAll/bin_helper'
5
+ require 'cocoapods-meitu-bin/config/config'
6
+ require 'xcodeproj'
7
+ require 'yaml'
8
+ require 'digest'
9
+
10
+ module Pod
11
+ class Command
12
+ class Bin < Command
13
+ class HeaderFilesSpecifications < Bin
14
+ self.summary = '规范组件在壳工程使用方式,非<>引入头文件会提示修改,同时会检查壳工程不在参与编译的文件并提示删除'
15
+ self.description = <<-DESC
16
+ #{summary}
17
+ DESC
18
+
19
+ def self.options
20
+ [
21
+ %w[--xcodeproj-path xcodeproj路径,默认会查找podfile同级目录下的xcodeproj_path],
22
+ %w[--classes-path 壳工程默认的代码文件路径,默认会查找podfile同级目录下的Classes目录],
23
+ %w[--error-del 提示不规范的组件头文件引入,并删除壳工程不参与编译的文件],
24
+ %w[--ignore-header header白名单设置,也可以在BinConfig.yml里配置,比如壳工程中的协议.h,或者纯.h文件,多个文件用;分割,例如CanvasProtocol.h;PainterProtocol.h]
25
+ ].concat(super).uniq
26
+ end
27
+
28
+ def initialize(argv)
29
+ @xcodeproj_path = argv.option('xcodeproj_path', "")
30
+ @classes_path = argv.option('classes_path', "")
31
+ @error_del = argv.flag?('error-del', false)
32
+ @ignore_header = argv.option('ignore-header', '')
33
+ super
34
+ end
35
+
36
+ def run
37
+ # 开始时间
38
+ @start_time = Time.now.to_i
39
+ # 读取配置文件
40
+ read_config
41
+ #xcodeproj_path为空字符串,默认获取当前目录下的xxx.xcodeproj
42
+ # 获取xcodeproj_path
43
+ if @xcodeproj_path.empty?
44
+ files = `ls`
45
+ file_list = files.split("\n")
46
+ xcodeproj = file_list.find_all { |n| n.include? ".xcodeproj" }[0]
47
+ scheme = xcodeproj.split(".")[0]
48
+ @xcodeproj_path = File.join(Pod::Config.instance.project_root, xcodeproj)
49
+ end
50
+
51
+ if !@xcodeproj_path.include? ".xcodeproj"
52
+ UI.info ".xcodeproj 路径不存在".red
53
+ return
54
+ end
55
+ # 获取xcodeproj 中的 Compile Sources 实际参与编译的文件
56
+ project = Xcodeproj::Project.open(@xcodeproj_path)
57
+ target = project.targets.select { |a_target| a_target.name.eql?(scheme) }[0]
58
+ files = target.source_build_phase.files
59
+ #获取 Compile Sources 中的所有文件名称
60
+ names = Array.new
61
+ files.each do |reference|
62
+ if reference.respond_to? 'file_ref' and reference.file_ref.respond_to? 'path'
63
+ names << reference.file_ref.path
64
+ else
65
+ puts reference
66
+ end
67
+ end
68
+ # puts names
69
+ #过滤出 .m 和 .mm 文件名
70
+ find_names = names.find_all { |n| (n.respond_to? 'include?' and (n.include? ".m" or n.include? ".mm")) }
71
+ find_swift_names = names.find_all { |n| (n.respond_to? 'include?' and n.include? ".swift") }
72
+ if @classes_path.empty?
73
+ @classes_path = File.join(Pod::Config.instance.project_root, "Classes")
74
+ end
75
+
76
+ if File.exist?(@classes_path)
77
+ files_h = `find #{@classes_path} -name "*.h"`
78
+ files_m = `find #{@classes_path} -name "*.m"`
79
+ files_swift = `find #{@classes_path} -name "*.swift"`
80
+ file_h_list = files_h.split("\n")
81
+ file_m_list = files_m.split("\n")
82
+ file_s_list = files_swift.split("\n")
83
+ del_h_path_list = Array.new
84
+ save_h_path_list = Array.new
85
+ del_m_path_list = Array.new
86
+ save_m_path_list = Array.new
87
+ del_s_path_list = Array.new
88
+ #获取在Compile Sources 的.h 和 本地路径下不在Compile Sources 的.h(需要删除的)
89
+ file_h_list.each do |file_h_path|
90
+ is_save = false
91
+ find_names.each { |name|
92
+ name_to = ''
93
+ if name.include? '.mm'
94
+ name_to = name.sub(".mm", ".h")
95
+ elsif name.include? '.m'
96
+ name_to = name.sub(".m", ".h")
97
+ else
98
+ puts "error:------#{name}"
99
+ end
100
+
101
+ if file_h_path.include? name_to
102
+ is_save = true
103
+ break
104
+ end
105
+ }
106
+ if is_save
107
+ save_h_path_list << file_h_path
108
+ else
109
+ del_h_path_list << file_h_path
110
+ end
111
+ end
112
+ #获取在Compile Sources 的.m .mm 和 本地路径下不在Compile Sources 的.m .mm(需要删除的)
113
+ file_m_list.each do |file_m_path|
114
+ is_save = false
115
+ find_names.each { |name|
116
+ if file_m_path.include? name
117
+ is_save = true
118
+ break
119
+ end
120
+ }
121
+ if is_save
122
+ save_m_path_list << file_m_path
123
+ else
124
+ del_m_path_list << file_m_path
125
+ end
126
+ end
127
+ #获取在Compile Sources 的.swift 和 本地路径下不在Compile Sources 的.swift(需要删除的)
128
+ file_s_list.each do |file_s_path|
129
+ is_save = false
130
+ find_swift_names.each { |name|
131
+ if file_s_path.include? name
132
+ is_save = true
133
+ break
134
+ end
135
+ }
136
+ if !is_save
137
+ del_s_path_list << file_s_path
138
+ end
139
+ end
140
+
141
+ # puts "del_h_path_list"
142
+ # puts del_h_path_list
143
+ # puts "save_h_path_list"
144
+ # puts save_h_path_list
145
+ # puts "del_m_path_list"
146
+ UI.title "提示: 壳工程不参与编译的文件,由于之前下层组件,删除引用并未删除代码文件或者其他分支又合入的不在使用或者已经下沉到组件的代码文件".green
147
+ del_m_path_list.each { |name| UI.info "- #{name}".red }
148
+ del_s_path_list.each { |name| UI.info "- #{name}".red }
149
+ # puts "save_m_path_list"
150
+ # puts save_m_path_list
151
+ if @error_del
152
+ del_m_path_list.each { |path|
153
+ h_path = path.gsub(".m", ".h")
154
+ if File.exist?(h_path)
155
+ `rm -rf #{h_path}`
156
+ end
157
+ `rm -rf #{path}`
158
+ }
159
+
160
+ del_s_path_list.each { |path|
161
+ `rm -rf #{path}`
162
+ }
163
+ end
164
+
165
+ header_path = save_h_path_list.join(sep = "#",)
166
+ all_header_list = Array.new
167
+ all_header_annotation_list = Array.new
168
+ save_h_path_list.each { |h_path|
169
+ list = `cat #{h_path} | grep '#import "' | awk -F ' ' '{print $2}'`
170
+ list_annotation = `cat #{h_path} | grep '//#import' | awk -F ' ' '{print $2}'`
171
+ #注释的头文件
172
+ list_annotation.split("\n").each { |name|
173
+ if !name.include? "-Swift.h\"" and name.include? ".h\""
174
+ all_header_annotation_list << name.gsub("\"", "")
175
+ end
176
+ }
177
+ list.split("\n").each { |name|
178
+ if !name.include? "-Swift.h\"" and name.include? ".h\""
179
+ all_header_list << name.gsub("\"", "")
180
+ end
181
+ }
182
+ }
183
+ save_m_path_list.each { |m_path|
184
+ list = `cat #{m_path} | grep '#import "' | awk -F ' ' '{print $2}'`
185
+ list_annotation = `cat #{m_path} | grep '//#import' | awk -F ' ' '{print $2}'`
186
+ list_annotation.split("\n").each { |name|
187
+ if !name.include? "-Swift.h\"" and name.include? ".h\""
188
+ all_header_annotation_list << name.gsub("\"", "")
189
+ end
190
+ }
191
+ list.split("\n").each { |name|
192
+ if !name.include? "-Swift.h\"" and name.include? ".h\""
193
+ all_header_list << name.gsub("\"", "")
194
+ end
195
+ }
196
+ }
197
+
198
+ modified_header_file_list = Array.new
199
+ all_header_annotation_list_to = all_header_annotation_list.uniq
200
+ all_header_list_to = all_header_list.uniq
201
+
202
+ all_header_del_list = Array.new
203
+
204
+ all_header_list_to.each { |name|
205
+ is_unsave = true
206
+ all_header_annotation_list_to.each { |name_to|
207
+ if name == name_to
208
+ is_unsave = false
209
+ break
210
+ end
211
+ }
212
+ if is_unsave
213
+ all_header_del_list << name
214
+ end
215
+ }
216
+
217
+ UI.title "提示: 使用方式需要调整为<>方式的头文件,请在壳工程代码搜索并修改".green
218
+ if !@ignore_header.empty?
219
+ @ignore_header.split(";").each { |name|
220
+ @ignore_header_list << name
221
+ }
222
+ end
223
+ @ignore_header_list.uniq
224
+ all_header_del_list.each { |name|
225
+ if !header_path.include? name and !@ignore_header_list.include? name
226
+ modified_header_file_list << name
227
+ UI.info "- #{name} 头文件不能在壳工程使用 #import \"#{name}\" 需要修改成#import <xxx/#{name}.h>".red
228
+ end
229
+ }
230
+
231
+ end
232
+
233
+ # 计算耗时
234
+ show_cost_time
235
+ end
236
+
237
+ private
238
+
239
+ # 读取配置文件
240
+ def read_config
241
+ UI.title 'Read config from file `BinConfig.yaml`'.green do
242
+ config_file = File.join(Pod::Config.instance.project_root, 'BinConfig.yaml')
243
+ return unless File.exist?(config_file)
244
+ config = YAML.safe_load(File.open(config_file))
245
+ return if config.nil?
246
+ build_config = config['build_config']
247
+ return if build_config.nil?
248
+ @ignore_header_list = build_config['ignore_header_list']
249
+ end
250
+ end
251
+
252
+ # 打印耗时
253
+ def show_cost_time
254
+ return if @start_time.nil?
255
+ UI.info "总耗时:#{Time.now.to_i - @start_time}s".green
256
+ end
257
+
258
+ end
259
+ end
260
+ end
261
+ end
262
+
@@ -0,0 +1,72 @@
1
+ require 'cocoapods-meitu-bin/config/config_asker'
2
+
3
+ module Pod
4
+ class Command
5
+ class Bin < Command
6
+ class Init < Bin
7
+ self.summary = '配置插件'
8
+ self.description = <<-DESC
9
+ 创建yml配置文件,保存插件需要的配置信息,如二进制podspec仓库、二进制下载地址等
10
+ DESC
11
+
12
+ def self.options
13
+ [
14
+ %w[--bin-url=URL 配置文件地址,直接从此地址下载配置文件]
15
+ ].concat(super)
16
+ end
17
+
18
+ def initialize(argv)
19
+ @bin_url = argv.option('bin-url')
20
+ super
21
+ end
22
+
23
+ def run
24
+ raise Informative, "当前目录下没有`Podfile`文件" unless File.exist?(File.join(Dir.pwd, "Podfile"))
25
+ raise Informative, "当前目录下已经存在配置文件" if File.exist?(CBin.config.config_file)
26
+ if @bin_url.nil?
27
+ config_with_asker
28
+ else
29
+ config_with_url(@bin_url)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # 从远端下载配置文件
36
+ def config_with_url(url)
37
+ require 'open-uri'
38
+
39
+ UI.puts "开始下载配置文件..."
40
+ file = open(url)
41
+ contents = YAML.safe_load(file.read)
42
+
43
+ UI.puts "开始同步配置文件..."
44
+ CBin.config.sync_config(contents.to_hash)
45
+ UI.puts "设置完成.".green
46
+ rescue Errno::ENOENT => e
47
+ raise Informative, "配置文件路径 #{url} 无效,请确认后重试."
48
+ end
49
+
50
+ # 询问用户相关的配置
51
+ def config_with_asker
52
+ asker = CBin::Config::Asker.new
53
+ asker.welcome_message
54
+
55
+ config = {}
56
+ template_hash = CBin.config.template_hash
57
+ template_hash.each do |k, v|
58
+ default = begin
59
+ CBin.config.send(k)
60
+ rescue StandardError
61
+ nil
62
+ end
63
+ config[k] = asker.ask_with_answer(v[:description], default, v[:selection])
64
+ end
65
+
66
+ CBin.config.sync_config(config)
67
+ asker.done_message
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end