cocoapods-mtxx-bin 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6a43466bec9d2783b0662dc91356c06bcff374abf6e16dce5247f77361497fd
4
- data.tar.gz: 2b29833245427d506a3ffe97ac9a556213e98ca3f17c01474961d8a092bbe532
3
+ metadata.gz: c18fc57de2d08c49e956f598907f2ff443b8fa45d678f3efe4d283f7b1e5d06a
4
+ data.tar.gz: 236bb2f1d892cc19704ca68c821e9953fd000f98e55bf54c6eb12de47af02fd6
5
5
  SHA512:
6
- metadata.gz: 8f9fa97150e04f2d8e15735ee3c0625c658cb87acee32e13a362859ef9fb3dd0fdc1e1686adefcc8ece5835d81eae853d124d2b332d2080884ecbc414a5185bc
7
- data.tar.gz: c3f6cc48d93c9917b9293f6b12d439038f22f38c53f09ec53942e99d8b5430d9407c62a26d1c41ea2ccb9a46a27f7bdaee15152a73fc2e729dad84da54eec04e
6
+ metadata.gz: f0e563796e362c9c8980a9d7ac161dfc38667bd4feddbab330de53b58a69c89868098abf69a8d5fb164c02bd7afcd888f1a8df456a57ca95d8323deec2e56599
7
+ data.tar.gz: bd6017ec3927a02aae59bd02a78fa488e14bd4a481b1e4b20dced50b74ef7d71f96b1fcd4d97794dabc52a4f1347208e7b81ac59d30cc5e0b91f7e7e33fa89c7
@@ -0,0 +1,310 @@
1
+ require 'cocoapods-mtxx-bin/helpers/buildAll/builder'
2
+ require 'cocoapods-mtxx-bin/helpers/buildAll/podspec_util'
3
+ require 'cocoapods-mtxx-bin/helpers/buildAll/zip_file_helper'
4
+ require 'cocoapods-mtxx-bin/helpers/buildAll/bin_helper'
5
+ require 'yaml'
6
+ require 'digest'
7
+
8
+ module Pod
9
+ class Command
10
+ class Bin < Command
11
+ class BuildAll < Bin
12
+ include CBin::BuildAll
13
+
14
+ CDN = 'https://cdn.cocoapods.org/'.freeze
15
+ MASTER_HTTP = 'https://github.com/CocoaPods/Specs.git'.freeze
16
+ MASTER_SSH = 'git@github.com:CocoaPods/Specs.git'.freeze
17
+ MT_REPO = 'techgit.meitu.com'.freeze
18
+
19
+ self.summary = '根据壳工程打包所有依赖组件为静态库(static framework)'
20
+ self.description = <<-DESC
21
+ #{self.summary}
22
+ DESC
23
+
24
+ def self.options
25
+ [
26
+ %w[--clean 删除编译临时目录],
27
+ %w[--repo-update 更新Podfile中指定的repo仓库],
28
+ %w[--full-build 是否全量打包]
29
+ ].concat(super).uniq
30
+ end
31
+
32
+ def initialize(argv)
33
+ @clean = argv.flag?('clean', false )
34
+ @repo_update = argv.flag?('repo-update', false )
35
+ @full_build = argv.flag?('full-build', false )
36
+ @base_dir = "#{Pathname.pwd}/build_pods"
37
+ super
38
+ end
39
+
40
+ def run
41
+ # 开始时间
42
+ @start_time = Time.now.to_i
43
+ # 读取配置文件
44
+ read_config
45
+ # 更新repo仓库
46
+ repo_update
47
+ # 执行pre_build命令
48
+ pre_build
49
+ # 分析依赖
50
+ @analyze_result = analyse
51
+ # 删除编译产物
52
+ clean_build_pods
53
+ # 编译所有pod_targets
54
+ results = build_pod_targets
55
+ # 执行post_build命令
56
+ post_build(results)
57
+ # 删除编译产物
58
+ clean_build_pods if @clean
59
+ # 计算耗时
60
+ show_cost_time
61
+ end
62
+
63
+ private
64
+
65
+ # 打印耗时
66
+ def show_cost_time
67
+ return if @start_time.nil?
68
+ UI.info "总耗时:#{Time.now.to_i - @start_time}s".green
69
+ end
70
+
71
+ # 读取配置文件
72
+ def read_config
73
+ UI.title "Read config from file `BinConfig.yaml`".green do
74
+ config_file = File.join(Dir.pwd, 'BinConfig.yaml')
75
+ return unless File.exist?(config_file)
76
+ config = YAML.load(File.open(config_file))
77
+ return if config.nil?
78
+ build_config = config['build_config']
79
+ return if build_config.nil?
80
+ @pre_build = build_config['pre_build']
81
+ @post_build = build_config['post_build']
82
+ @black_list = build_config['black_list']
83
+ @write_list = build_config['write_list']
84
+ end
85
+ end
86
+
87
+ # 更新repo仓库
88
+ def repo_update
89
+ UI.title "Repo update".green do
90
+ return if podfile.nil?
91
+ sources_manager = Pod::Config.instance.sources_manager
92
+ podfile.sources.uniq.map { |src|
93
+ # next if src.include?(CDN) || src.include?(MASTER_HTTP) || src.include?(MASTER_SSH)
94
+ next unless src.include?(MT_REPO)
95
+ UI.message "Update repo: #{src}"
96
+ source = sources_manager.source_with_name_or_url(src)
97
+ source.update(false )
98
+ }
99
+ end if @repo_update
100
+ end
101
+
102
+ # 执行pre build
103
+ def pre_build
104
+ UI.title "Execute the command of pre build".green do
105
+ system(@pre_build)
106
+ end if @pre_build
107
+ end
108
+
109
+ # 执行post build
110
+ def post_build(results)
111
+ UI.title "Execute the command of post build".green do
112
+ system(@post_build)
113
+ end if @post_build
114
+ end
115
+
116
+ # 获取 podfile
117
+ def podfile
118
+ @podfile ||= begin
119
+ podfile_path = File.join(Pathname.pwd,"Podfile")
120
+ raise "Podfile不存在" unless File.exist?(podfile_path)
121
+ sources_manager = Pod::Config.instance.sources_manager
122
+ podfile = Podfile.from_file(Pathname.new(podfile_path))
123
+ podfile_hash = podfile.to_hash
124
+ podfile_hash['sources'] = (podfile_hash['sources'] || []).concat(sources_manager.code_source_list.map(&:url))
125
+ podfile_hash['sources'] << sources_manager.binary_source.url
126
+ podfile_hash['sources'].uniq!
127
+ Podfile.from_hash(podfile_hash)
128
+ end
129
+ end
130
+
131
+ # 获取 podfile.lock
132
+ def lockfile
133
+ @lockfile ||= begin
134
+ lock_path = File.join(Pathname.pwd,"Podfile.lock")
135
+ raise "Podfile.lock不存在,请执行pod install" unless File.exist?(lock_path)
136
+ Lockfile.from_file(Pathname.new(lock_path))
137
+ end
138
+ end
139
+
140
+ # 获取 sandbox
141
+ def sandbox
142
+ @sandbox ||= begin
143
+ sandbox_path = File.join(Pathname.pwd, "Pods")
144
+ raise "Pods文件夹不存在,请执行pod install" unless File.exist?(sandbox_path)
145
+ Pod::Sandbox.new(sandbox_path)
146
+ end
147
+ end
148
+
149
+ # 根据podfile和podfile.lock分析依赖
150
+ def analyse
151
+ UI.title "Analyze dependencies".green do
152
+ analyzer = Pod::Installer::Analyzer.new(
153
+ sandbox,
154
+ podfile,
155
+ lockfile
156
+ )
157
+ analyzer.analyze(true )
158
+ end
159
+ end
160
+
161
+ # 删除编译产物
162
+ def clean_build_pods
163
+ UI.title "Clean build pods".green do
164
+ build_path = Dir.pwd + "/build"
165
+ FileUtils.rm_rf(build_path) if File.exist?(build_path)
166
+ build_pods_path = Dir.pwd + "/build_pods"
167
+ FileUtils.rm_rf(build_pods_path) if File.exist?(build_pods_path)
168
+ end
169
+ end
170
+
171
+ # 构建所有pod_targets
172
+ def build_pod_targets
173
+ UI.title "Build all pod targets(#{@full_build ? '全量打包' : '非全量打包'})".green do
174
+ pod_targets = @analyze_result.pod_targets.uniq
175
+ success_pods = []
176
+ fail_pods = []
177
+ local_pods = []
178
+ external_pods = []
179
+ binary_pods = []
180
+ created_pods = []
181
+ pod_targets.map do |pod_target|
182
+ begin
183
+ version = BinHelper.version(pod_target.pod_name, pod_target.root_spec.version.to_s, @analyze_result.specifications)
184
+ # 全量
185
+ if @full_build
186
+ # 黑名单
187
+ next if !@black_list.nil? && !@black_list.empty? && @black_list.include?(pod_target.pod_name)
188
+ else
189
+ # 白名单
190
+ next if !@write_list.nil? && !@write_list.empty? && !@write_list.include?(pod_target.pod_name)
191
+ end
192
+ # 本地库
193
+ if @sandbox.local?(pod_target.pod_name)
194
+ local_pods << pod_target.pod_name
195
+ show_skip_tip("#{pod_target.pod_name} 是本地库")
196
+ next
197
+ end
198
+ # 外部源(如 git)
199
+ if @sandbox.checkout_sources[pod_target.pod_name]
200
+ external_pods << pod_target.pod_name
201
+ show_skip_tip("#{pod_target.pod_name} 以external方式引入")
202
+ next
203
+ end
204
+ # 无源码
205
+ if !@sandbox.local?(pod_target.pod_name) && !pod_target.should_build?
206
+ binary_pods << pod_target.pod_name
207
+ show_skip_tip("#{pod_target.pod_name} 无需编译")
208
+ next
209
+ end
210
+ # 非全量编译、 不在白名单中且已经有相应的二进制版本
211
+ if has_created_binary?(pod_target.pod_name, version)
212
+ created_pods << pod_target.pod_name
213
+ show_skip_tip("#{pod_target.pod_name}(#{version}) 已经有二进制版本了")
214
+ next
215
+ end
216
+ # 是否跳过编译(黑名单)
217
+ next if skip_build?(pod_target)
218
+ # 构建产物
219
+ builder = Builder.new(pod_target, @sandbox.checkout_sources)
220
+ result = builder.build
221
+ fail_pods << pod_target.pod_name unless result
222
+ next unless result
223
+ builder.create_binary
224
+ # 压缩并上传zip
225
+ zip_helper = ZipFileHelper.new(pod_target, version, builder.product_dir, builder.build_as_framework)
226
+ result = zip_helper.zip_lib
227
+ fail_pods << pod_target.pod_name unless result
228
+ next unless result
229
+ result = zip_helper.upload_zip_lib
230
+ fail_pods << pod_target.pod_name unless result
231
+ next unless result
232
+ # 生成二进制podspec并上传
233
+ podspec_creator = PodspecUtil.new(pod_target, version, builder.build_as_framework)
234
+ bin_spec = podspec_creator.create_binary_podspec
235
+ bin_spec_file = podspec_creator.write_binary_podspec(bin_spec)
236
+ podspec_creator.push_binary_podspec(bin_spec_file)
237
+ success_pods << pod_target.pod_name
238
+ rescue Pod::StandardError => e
239
+ UI.info "#{pod_target} 编译失败,原因:#{e}".red
240
+ fail_pods << pod_target.pod_name
241
+ next
242
+ end
243
+ end
244
+ results = {
245
+ 'Total' => pod_targets,
246
+ 'Success' => success_pods,
247
+ 'Fail' => fail_pods,
248
+ 'Local' => local_pods,
249
+ 'External' => external_pods,
250
+ 'No Source File' => binary_pods,
251
+ 'Created Binary' => created_pods,
252
+ 'Black List' => @black_list || [],
253
+ 'Write List' => @write_list || []
254
+ }
255
+ show_results(results)
256
+ results
257
+ end
258
+ end
259
+
260
+ def show_skip_tip(title)
261
+ UI.info title.yellow
262
+ end
263
+
264
+ # 是否跳过编译
265
+ def skip_build?(pod_target)
266
+ !@black_list.nil? && !@black_list.empty? && @black_list.include?(pod_target.pod_name)
267
+ end
268
+
269
+ # 展示结果
270
+ def show_results(results)
271
+ UI.title "打包结果:".green do
272
+ UI.info "——————————————————————————————————".green
273
+ UI.info "|#{"Type".center(20)}|#{"Count".center(11)}|".green
274
+ UI.info "——————————————————————————————————".green
275
+ results.each do |key, value|
276
+ UI.info "|#{key.center(20)}|#{value.size.to_s.center(11)}|".green
277
+ end
278
+ UI.info "——————————————————————————————————".green
279
+
280
+ # 打印出失败的 target
281
+ unless results['Fail'].empty?
282
+ UI.info "\n打包失败的库:#{results['Fail']}".red
283
+ end
284
+ end
285
+ end
286
+
287
+ # 是否已经有二进制版本了
288
+ def has_created_binary?(pod_name, version)
289
+ # name 或 version 为nil
290
+ return false if pod_name.nil? || version.nil?
291
+ # 是否全量打包
292
+ return false if @full_build
293
+ # 是否在白名单中
294
+ return false if !@write_list.nil? && !@write_list.empty? && @write_list.include?(pod_name)
295
+ sources_manager = Config.instance.sources_manager
296
+ binary_source = sources_manager.binary_source
297
+ result = false
298
+ begin
299
+ specification = binary_source.specification(pod_name, version)
300
+ result = true unless specification.nil?
301
+ rescue Pod::StandardError => e
302
+ result = false
303
+ end
304
+ result
305
+ end
306
+
307
+ end
308
+ end
309
+ end
310
+ end
@@ -84,6 +84,8 @@ module Pod
84
84
 
85
85
  find_dependency = find_dependency(name)
86
86
 
87
+ raise "未找到 #{name} 的依赖" if find_dependency.nil?
88
+
87
89
  spec = fetch_external_source(find_dependency, @config.podfile,@config.lockfile, @config.sandbox,true )
88
90
 
89
91
  download_request = Pod::Downloader::Request.new(:name => name, :spec => spec)
@@ -163,7 +165,7 @@ module Pod
163
165
  lib_path = File.join(dir,lib_name)
164
166
 
165
167
  unless File.exist?(lib_path)
166
- lib_path = File.join(dir.children.first,lib_name)
168
+ lib_path = File.join(dir.children.first, name)
167
169
  end
168
170
 
169
171
  lib_path
@@ -9,105 +9,78 @@ module Pod
9
9
  class Push < Repo
10
10
  self.summary = '发布组件'
11
11
  self.description = <<-DESC
12
- 发布二进制组件 / 源码组件
12
+ #{self.summary}
13
+ 跳过lint过程
13
14
  DESC
14
15
 
15
16
  self.arguments = [
17
+ CLAide::Argument.new('REPO', true ),
16
18
  CLAide::Argument.new('NAME.podspec', false )
17
19
  ]
18
20
 
19
21
  def self.options
20
- [
21
- ['--binary', '发布组件的二进制版本'],
22
- ['--template-podspec=A.binary-template.podspec', '生成拥有 subspec 的二进制 spec 需要的模版 podspec, 插件会更改 version 和 source'],
23
- ['--reserve-created-spec', '保留生成的二进制 spec 文件'],
24
- ['--code-dependencies', '使用源码依赖进行 lint'],
25
- ['--loose-options', '添加宽松的 options, 包括 --use-libraries (可能会造成 entry point (start) undefined)'],
26
- ['--allow-prerelease', '允许使用 prerelease 的版本 lint']
27
- ].concat(Pod::Command::Repo::Push.options).concat(super).uniq
22
+ [].concat(Pod::Command::Repo::Push.options).concat(super).uniq
28
23
  end
29
24
 
30
25
  def initialize(argv)
26
+ @repo = argv.shift_argument
31
27
  @podspec = argv.shift_argument
32
- @binary = argv.flag?('binary')
33
- @loose_options = argv.flag?('loose-options')
34
- @code_dependencies = argv.flag?('code-dependencies')
35
- @sources = argv.option('sources') || []
36
- @reserve_created_spec = argv.flag?('reserve-created-spec')
37
- @template_podspec = argv.option('template-podspec')
38
- @allow_prerelease = argv.flag?('allow-prerelease')
39
28
  super
40
29
 
41
30
  @additional_args = argv.remainder!
42
31
  end
43
32
 
44
33
  def run
45
- Podfile.execute_with_bin_plugin do
46
- Podfile.execute_with_allow_prerelease(@allow_prerelease) do
47
- Podfile.execute_with_use_binaries(!@code_dependencies) do
48
- argvs = [
49
- repo,
50
- "--sources=#{sources_option(@code_dependencies, @sources)}",
51
- *@additional_args
52
- ]
34
+ argvs = [
35
+ @repo,
36
+ *@additional_args
37
+ ]
53
38
 
54
- argvs << spec_file if spec_file
55
-
56
- if @loose_options
57
- argvs += ['--allow-warnings', '--use-json']
58
- # if code_spec&.all_dependencies&.any?
59
- # argvs << '--use-libraries'
60
- # end
61
- end
62
-
63
- push = Pod::Command::Repo::Push.new(CLAide::ARGV.new(argvs))
64
- push.validate!
65
- push.run
66
- end
67
- end
68
- end
39
+ push = Pod::Command::Repo::Push.new(CLAide::ARGV.new(argvs))
40
+ push.validate!
41
+ push.run
69
42
  ensure
70
43
  clear_binary_spec_file_if_needed unless @reserve_created_spec
71
44
  end
72
45
 
73
46
  private
74
47
 
75
- def template_spec_file
76
- @template_spec_file ||= begin
77
- if @template_podspec
78
- find_spec_file(@template_podspec)
79
- else
80
- binary_template_spec_file
81
- end
82
- end
83
- end
84
-
85
- def spec_file
86
- @spec_file ||= begin
87
- if @podspec
88
- find_spec_file(@podspec)
89
- else
90
- if code_spec_files.empty?
91
- raise Informative, '当前目录下没有找到可用源码 podspec.'
92
- end
93
-
94
- spec_file = if @binary
95
- code_spec = Pod::Specification.from_file(code_spec_files.first)
96
- if template_spec_file
97
- template_spec = Pod::Specification.from_file(template_spec_file)
98
- end
99
- create_binary_spec_file(code_spec, template_spec)
100
- else
101
- code_spec_files.first
102
- end
103
- spec_file
104
- end
105
- end
106
- end
107
-
108
- def repo
109
- @binary ? binary_source.name : code_source_list.first.name
110
- end
48
+ # def template_spec_file
49
+ # @template_spec_file ||= begin
50
+ # if @template_podspec
51
+ # find_spec_file(@template_podspec)
52
+ # else
53
+ # binary_template_spec_file
54
+ # end
55
+ # end
56
+ # end
57
+ #
58
+ # def spec_file
59
+ # @spec_file ||= begin
60
+ # if @podspec
61
+ # find_spec_file(@podspec)
62
+ # else
63
+ # if code_spec_files.empty?
64
+ # raise Informative, '当前目录下没有找到可用源码 podspec.'
65
+ # end
66
+ #
67
+ # spec_file = if @binary
68
+ # code_spec = Pod::Specification.from_file(code_spec_files.first)
69
+ # if template_spec_file
70
+ # template_spec = Pod::Specification.from_file(template_spec_file)
71
+ # end
72
+ # create_binary_spec_file(code_spec, template_spec)
73
+ # else
74
+ # code_spec_files.first
75
+ # end
76
+ # spec_file
77
+ # end
78
+ # end
79
+ # end
80
+ #
81
+ # def repo
82
+ # @binary ? binary_source.name : code_source_list.first.name
83
+ # end
111
84
  end
112
85
  end
113
86
  end
@@ -8,6 +8,7 @@ require 'cocoapods-mtxx-bin/command/bin/install'
8
8
  # require 'cocoapods-mtxx-bin/command/bin/imy'
9
9
  require 'cocoapods-mtxx-bin/command/bin/repo'
10
10
  require 'cocoapods-mtxx-bin/command/bin/spec'
11
+ require 'cocoapods-mtxx-bin/command/bin/buildAll'
11
12
  require 'cocoapods-mtxx-bin/helpers'
12
13
  # require 'cocoapods-mtxx-bin/native'
13
14
 
@@ -122,8 +122,6 @@ module CBin
122
122
 
123
123
  def config
124
124
  @config ||= begin
125
- msg = "cocoapods-mtxx-bin #{CBin::VERSION} 版本"
126
- puts "\033[44m#{msg}\033[0m\n"
127
125
  @config = OpenStruct.new load_config
128
126
  validate!
129
127
  @config
@@ -1,5 +1,5 @@
1
1
  module CBin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
4
4
 
5
5
  module Pod
@@ -0,0 +1,19 @@
1
+ require 'digest'
2
+
3
+ module CBin
4
+ module BuildAll
5
+ class BinHelper
6
+ include Pod
7
+
8
+ # 二进制版本号(x.y.z.bin[md5前6位])
9
+ def self.version(pod_name, original_version, specifications)
10
+ specs = specifications.map(&:name).select { |spec|
11
+ spec.include?(pod_name) && !spec.include?('/Binary')
12
+ }.sort!
13
+ specs_str = specs.join('')
14
+ "#{original_version}.bin#{Digest::MD5.hexdigest(specs_str)[0,6]}"
15
+ end
16
+
17
+ end
18
+ end
19
+ end