cocoapods-mtxx-bin 0.0.1 → 0.0.3
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/lib/cocoapods-mtxx-bin/command/bin/buildAll.rb +310 -0
- data/lib/cocoapods-mtxx-bin/command/bin/code.rb +3 -1
- data/lib/cocoapods-mtxx-bin/command/bin/repo/push.rb +48 -75
- data/lib/cocoapods-mtxx-bin/command/bin.rb +1 -0
- data/lib/cocoapods-mtxx-bin/config/config.rb +0 -2
- data/lib/cocoapods-mtxx-bin/gem_version.rb +1 -1
- data/lib/cocoapods-mtxx-bin/helpers/buildAll/bin_helper.rb +19 -0
- data/lib/cocoapods-mtxx-bin/helpers/buildAll/builder.rb +381 -0
- data/lib/cocoapods-mtxx-bin/helpers/buildAll/podspec_util.rb +137 -0
- data/lib/cocoapods-mtxx-bin/helpers/buildAll/zip_file_helper.rb +81 -0
- data/lib/cocoapods-mtxx-bin/native/analyzer.rb +4 -0
- data/lib/cocoapods-mtxx-bin/native/resolver.rb +69 -10
- data/lib/cocoapods-mtxx-bin/native/sources_manager.rb +1 -0
- data/lib/cocoapods-mtxx-bin/source_provider_hook.rb +16 -4
- data/lib/cocoapods_plugin.rb +9 -0
- metadata +7 -2
@@ -0,0 +1,381 @@
|
|
1
|
+
|
2
|
+
module CBin
|
3
|
+
module BuildAll
|
4
|
+
class Builder
|
5
|
+
include Pod
|
6
|
+
|
7
|
+
def initialize(pod_target, checkout_sources)
|
8
|
+
@pod_target = pod_target
|
9
|
+
@checkout_sources = checkout_sources
|
10
|
+
@file_accessors = pod_target.file_accessors unless pod_target.nil?
|
11
|
+
@base_dir = "#{Pathname.pwd}/build_pods"
|
12
|
+
end
|
13
|
+
|
14
|
+
# 构建
|
15
|
+
def build
|
16
|
+
UI.info "编译#{@pod_target}".yellow
|
17
|
+
dir = result_product_dir
|
18
|
+
FileUtils.rm_rf(dir) if File.exist?(dir)
|
19
|
+
# 编译模拟器
|
20
|
+
result = build_pod_target
|
21
|
+
return false unless result
|
22
|
+
# 编译真机
|
23
|
+
build_pod_target(false )
|
24
|
+
end
|
25
|
+
|
26
|
+
# 创建binary
|
27
|
+
def create_binary
|
28
|
+
UI.info "创建#{@pod_target}.framework".yellow
|
29
|
+
# 如果是framework需要先copy
|
30
|
+
if build_as_framework
|
31
|
+
copy_framework
|
32
|
+
else
|
33
|
+
create_framework_dir
|
34
|
+
end
|
35
|
+
# 合并真机模拟器
|
36
|
+
merge_device_sim
|
37
|
+
# 如果是lib需要拷贝头文件
|
38
|
+
unless build_as_framework
|
39
|
+
copy_headers
|
40
|
+
copy_headers(false )
|
41
|
+
generate_umbrella_header
|
42
|
+
generate_module_map
|
43
|
+
compile_resources
|
44
|
+
if @pod_target.uses_swift?
|
45
|
+
copy_swiftmodules
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# 拷贝资源文件
|
49
|
+
copy_resources
|
50
|
+
# 拷贝 vendored_frameworks 和 vendored_libraries
|
51
|
+
copy_vendored_frameworks
|
52
|
+
copy_vendored_libraries
|
53
|
+
end
|
54
|
+
|
55
|
+
# 是否以framework形式构建
|
56
|
+
def build_as_framework
|
57
|
+
path = "#{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target.framework_name}"
|
58
|
+
File.exist?(path)
|
59
|
+
end
|
60
|
+
|
61
|
+
# xxx.framework/Modules
|
62
|
+
def modules_dir
|
63
|
+
"#{result_product_dir}/Modules"
|
64
|
+
end
|
65
|
+
|
66
|
+
# xxx.framework/Headers
|
67
|
+
def headers_dir
|
68
|
+
"#{result_product_dir}/Headers"
|
69
|
+
end
|
70
|
+
|
71
|
+
# xxx.framework/PrivateHeaders
|
72
|
+
def private_headers_dir
|
73
|
+
"#{result_product_dir}/PrivateHeaders"
|
74
|
+
end
|
75
|
+
|
76
|
+
# xxx.framework/resources
|
77
|
+
def resources_dir
|
78
|
+
"#{result_product_dir}/resources"
|
79
|
+
end
|
80
|
+
|
81
|
+
# xxx.framework
|
82
|
+
def result_product_dir
|
83
|
+
"#{product_dir}/#{@pod_target.framework_name}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# xxx.framework 所在目录
|
87
|
+
def product_dir
|
88
|
+
@product_dir = "#{@base_dir}/#{@pod_target}/Products"
|
89
|
+
@product_dir
|
90
|
+
end
|
91
|
+
|
92
|
+
# 构建临时产物目录
|
93
|
+
def temp_dir
|
94
|
+
"#{@base_dir}/#{@pod_target}/Temp"
|
95
|
+
end
|
96
|
+
|
97
|
+
def iphoneos
|
98
|
+
"Release-iphoneos"
|
99
|
+
end
|
100
|
+
|
101
|
+
def iphonesimulator
|
102
|
+
"Release-iphonesimulator"
|
103
|
+
end
|
104
|
+
|
105
|
+
# 需要排除的资源文件后缀
|
106
|
+
def reject_resource_ext
|
107
|
+
%w[.xcdatamodeld .xcdatamodel .xcmappingmodel .xib .storyboard]
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# 构建单个pod
|
113
|
+
def build_pod_target(simulator = true)
|
114
|
+
sdk = simulator ? 'iphonesimulator' : 'iphoneos'
|
115
|
+
archs = simulator ? 'x86_64' : 'arm64'
|
116
|
+
product_dir = product_dir()
|
117
|
+
temp_dir = temp_dir()
|
118
|
+
pod_project_path = Dir.pwd + "/Pods/#{@pod_target}.xcodeproj"
|
119
|
+
if File.exist?(pod_project_path)
|
120
|
+
project = "./Pods/#{@pod_target}.xcodeproj"
|
121
|
+
else
|
122
|
+
project = "./Pods/Pods.xcodeproj"
|
123
|
+
end
|
124
|
+
command = <<-BUILD
|
125
|
+
xcodebuild GCC_PREPROCESSOR_DEFINITIONS='$(inherited)' \
|
126
|
+
GCC_WARN_INHIBIT_ALL_WARNINGS=YES \
|
127
|
+
-sdk #{sdk} \
|
128
|
+
ARCHS=#{archs} \
|
129
|
+
CONFIGURATION_TEMP_DIR=#{temp_dir} \
|
130
|
+
BUILD_ROOT=#{product_dir} \
|
131
|
+
BUILD_DIR=#{product_dir} \
|
132
|
+
clean build \
|
133
|
+
-configuration Release \
|
134
|
+
-target #{@pod_target} \
|
135
|
+
-project #{project}
|
136
|
+
BUILD
|
137
|
+
UI.info "#{command}"
|
138
|
+
`#{command}`
|
139
|
+
if $CHILD_STATUS.exitstatus != 0
|
140
|
+
UI.info "#{@pod_target}(#{sdk}) 编译失败!".red
|
141
|
+
return false
|
142
|
+
end
|
143
|
+
return true
|
144
|
+
end
|
145
|
+
|
146
|
+
# 合并真机模拟器
|
147
|
+
def merge_device_sim
|
148
|
+
if build_as_framework
|
149
|
+
device_lib_dir = "#{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target.framework_name}/#{@pod_target.product_module_name}"
|
150
|
+
sim_lib_dir = "#{product_dir}/#{iphonesimulator}/#{@pod_target}/#{@pod_target.framework_name}/#{@pod_target.product_module_name}"
|
151
|
+
else
|
152
|
+
device_lib_dir = "#{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target.static_library_name}"
|
153
|
+
sim_lib_dir = "#{product_dir}/#{iphonesimulator}/#{@pod_target}/#{@pod_target.static_library_name}"
|
154
|
+
end
|
155
|
+
output = "#{result_product_dir}/#{@pod_target.product_module_name}"
|
156
|
+
libs = [device_lib_dir, sim_lib_dir]
|
157
|
+
FileUtils.mkdir(result_product_dir) unless File.exist?(result_product_dir)
|
158
|
+
`lipo -create -output #{output} #{libs.join(' ')}` unless libs.empty?
|
159
|
+
end
|
160
|
+
|
161
|
+
# 创建 xxx.framework 文件夹
|
162
|
+
def create_framework_dir
|
163
|
+
fwk_path = "#{product_dir}/#{@pod_target.product_module_name}.framework"
|
164
|
+
FileUtils.rm_rf(fwk_path) if File.exist?(fwk_path)
|
165
|
+
FileUtils.mkdir(fwk_path)
|
166
|
+
end
|
167
|
+
|
168
|
+
# -------------------------- 编译需要编译的资源 --------------------------------
|
169
|
+
|
170
|
+
# 需要编译的资源
|
171
|
+
def need_compile_resources
|
172
|
+
return [] if @file_accessors.nil?
|
173
|
+
resources = @file_accessors.flat_map(&:resources)
|
174
|
+
return [] if resources.nil? || resources.size == 0
|
175
|
+
resources.compact.select { |res| reject_resource_ext.include?(res.extname) }.map(&:to_s)
|
176
|
+
end
|
177
|
+
|
178
|
+
# 编译需要编译的资源
|
179
|
+
def compile_resources
|
180
|
+
resources = need_compile_resources
|
181
|
+
resources.map { |res| compile_resource(res) }
|
182
|
+
end
|
183
|
+
|
184
|
+
# 编译单个资源
|
185
|
+
def compile_resource(resource)
|
186
|
+
return unless File.exist?(resource)
|
187
|
+
case File.extname(resource)
|
188
|
+
when '.storyboard', '.xib'
|
189
|
+
compile_storyboard_xib(resource)
|
190
|
+
when '.xcdatamodeld', '.xcdatamodel'
|
191
|
+
compile_xcdatamodel(resource)
|
192
|
+
when '.xcmappingmodel'
|
193
|
+
compile_xcmappingmodel(resource)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# 编译storyboard、xib
|
198
|
+
def compile_storyboard_xib(resource)
|
199
|
+
file_ext = File.extname(resource)
|
200
|
+
file_name = File.basename(resource, file_ext)
|
201
|
+
command = <<-COMMAND
|
202
|
+
ibtool \
|
203
|
+
--reference-external-strings-file \
|
204
|
+
--errors --warnings \
|
205
|
+
--notices \
|
206
|
+
--output-format human-readable-text \
|
207
|
+
--compile #{result_product_dir}/#{file_name}.#{file_ext == '.storyboard' ? 'storyboardc' : 'nib'} #{resource} \
|
208
|
+
--target-device ipad --target-device iphone
|
209
|
+
COMMAND
|
210
|
+
`#{command}`
|
211
|
+
end
|
212
|
+
|
213
|
+
# 编译xcdatamodel、xcdatamodeld
|
214
|
+
def compile_xcdatamodel(resource)
|
215
|
+
file_ext = File.extname(resource)
|
216
|
+
file_name = File.basename(resource, file_ext)
|
217
|
+
`xcrun momc #{resource} #{result_product_dir}/#{file_name}.#{file_ext == 'xcdatamodeld' ? 'momd' : 'mom'}`
|
218
|
+
end
|
219
|
+
|
220
|
+
# 编译xcmappingmodel
|
221
|
+
def compile_xcmappingmodel(resource)
|
222
|
+
file_ext = File.extname(resource)
|
223
|
+
file_name = File.basename(resource, file_ext)
|
224
|
+
`xcrun mapc #{resource} #{result_product_dir}/#{file_name}.cdm`
|
225
|
+
end
|
226
|
+
|
227
|
+
# -------------------------- 拷贝头文件、资源等 --------------------------------
|
228
|
+
|
229
|
+
# 拷贝头文件
|
230
|
+
def copy_headers(public = true)
|
231
|
+
if public
|
232
|
+
headers = @file_accessors.map(&:public_headers).flatten.compact.uniq
|
233
|
+
header_dir = headers_dir
|
234
|
+
if @pod_target.uses_swift?
|
235
|
+
umbrella_header = "#{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target}-umbrella.h"
|
236
|
+
swift_header = "#{product_dir}/#{iphoneos}/#{@pod_target}/Swift\\ Compatibility\\ Header/#{@pod_target.product_module_name}-Swift.h"
|
237
|
+
headers.concat([umbrella_header, swift_header])
|
238
|
+
end
|
239
|
+
else
|
240
|
+
headers = @file_accessors.map(&:private_headers).flatten.compact.uniq
|
241
|
+
header_dir = private_headers_dir
|
242
|
+
end
|
243
|
+
return if headers.empty?
|
244
|
+
FileUtils.mkdir(header_dir) unless File.exist?(header_dir)
|
245
|
+
headers.map do |header|
|
246
|
+
header_path = header
|
247
|
+
if header.is_a?(String)
|
248
|
+
header_path = header.gsub(/ /, '\ ') if header.include?(' ')
|
249
|
+
elsif header.is_a?(Pathname)
|
250
|
+
header_path = header.to_s.gsub(/ /, '\ ') if header.to_s.include?(' ')
|
251
|
+
end
|
252
|
+
`cp -f #{header_path} #{header_dir}`
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# 获取podspec中的resource_bundles
|
257
|
+
def resource_bundles
|
258
|
+
return [] if @file_accessors.nil?
|
259
|
+
resource_bundles = @file_accessors.flat_map(&:resource_bundles)
|
260
|
+
return [] if resource_bundles.nil? || resource_bundles.size == 0
|
261
|
+
resource_bundles.compact.flat_map(&:keys).map { |key| "#{product_dir}/#{iphoneos}/#{@pod_target}/#{key}.bundle" }
|
262
|
+
end
|
263
|
+
|
264
|
+
# 获取podspec中resource/resources
|
265
|
+
def other_resources
|
266
|
+
return [] if @file_accessors.nil?
|
267
|
+
resources = @file_accessors.flat_map(&:resources)
|
268
|
+
return [] if resources.nil? || resources.size == 0
|
269
|
+
resources.compact.reject { |res| reject_resource_ext.include?(res.extname) }.map(&:to_s)
|
270
|
+
end
|
271
|
+
|
272
|
+
# 拷贝资源文件
|
273
|
+
def copy_resources
|
274
|
+
resources = resource_bundles + other_resources
|
275
|
+
return if resources.empty?
|
276
|
+
resources_dir = "#{result_product_dir}/resources"
|
277
|
+
FileUtils.mkdir(resources_dir) unless File.exist?(resources_dir)
|
278
|
+
resources.uniq.map do |resource|
|
279
|
+
`rsync -av #{resource} #{resources_dir}`
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# 拷贝 vendored_libraries
|
284
|
+
def copy_vendored_libraries
|
285
|
+
libs = @pod_target.file_accessors.map(&:vendored_libraries).flatten.compact.uniq
|
286
|
+
return if libs.empty?
|
287
|
+
libs_dir = "#{result_product_dir}/libs"
|
288
|
+
FileUtils.mkdir(libs_dir) unless File.exist?(libs_dir)
|
289
|
+
libs.map do |lib|
|
290
|
+
`rsync -av #{lib} #{libs_dir}`
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# 拷贝 vendored_frameworks
|
295
|
+
def copy_vendored_frameworks
|
296
|
+
fwks = @pod_target.file_accessors.map(&:vendored_frameworks).flatten.compact.uniq
|
297
|
+
return if fwks.empty?
|
298
|
+
fwks_dir = "#{result_product_dir}/fwks"
|
299
|
+
FileUtils.mkdir(fwks_dir) unless File.exist?(fwks_dir)
|
300
|
+
fwks.map do |fwk|
|
301
|
+
`rsync -av #{fwk} #{fwks_dir}`
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# 拷贝 framework
|
306
|
+
def copy_framework
|
307
|
+
source_path = "#{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target.framework_name}"
|
308
|
+
if File.exist?(source_path)
|
309
|
+
`rsync -av #{source_path} #{product_dir}`
|
310
|
+
end
|
311
|
+
# 如果包含Swift代码,需要copy swiftmodules
|
312
|
+
if @pod_target.uses_swift?
|
313
|
+
copy_swiftmodules
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# 拷贝swiftmodule
|
318
|
+
def copy_swiftmodules
|
319
|
+
if build_as_framework
|
320
|
+
swift_module = "#{modules_dir}/#{@pod_target.product_module_name}.swiftmodule"
|
321
|
+
src_swift = "#{product_dir}/#{iphonesimulator}/#{@pod_target}/#{@pod_target.framework_name}/Modules/#{@pod_target.product_module_name}.swiftmodule"
|
322
|
+
else
|
323
|
+
FileUtils.mkdir(modules_dir) unless File.exist?(modules_dir)
|
324
|
+
`cp -rf #{product_dir}/#{iphoneos}/#{@pod_target}/#{@pod_target.product_module_name}.swiftmodule #{modules_dir}`
|
325
|
+
swift_module = "#{modules_dir}/#{@pod_target.product_module_name}.swiftmodule"
|
326
|
+
src_swift = "#{product_dir}/#{iphonesimulator}/#{@pod_target}/#{@pod_target.product_module_name}.swiftmodule"
|
327
|
+
end
|
328
|
+
if File.exist?(swift_module)
|
329
|
+
`cp -af #{src_swift}/* #{swift_module}`
|
330
|
+
`cp -af #{src_swift}/Project/* #{swift_module}/Project`
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# -------------------------- LLVM module --------------------------------
|
335
|
+
|
336
|
+
# 生成 module map
|
337
|
+
def generate_module_map
|
338
|
+
module_map = "#{modules_dir}/module.modulemap"
|
339
|
+
FileUtils.mkdir(modules_dir) unless File.exist?(modules_dir)
|
340
|
+
FileUtils.rm_f(module_map) if File.exist?(module_map)
|
341
|
+
File.open(module_map, "w+") do |f|
|
342
|
+
content = <<-MODULEMAP
|
343
|
+
framework module #{@pod_target.product_module_name} {
|
344
|
+
umbrella header "#{@pod_target}-umbrella.h"
|
345
|
+
|
346
|
+
export *
|
347
|
+
module * { export * }
|
348
|
+
}
|
349
|
+
MODULEMAP
|
350
|
+
# 有Swift代码
|
351
|
+
if @pod_target.uses_swift?
|
352
|
+
content += <<-SWIFT
|
353
|
+
|
354
|
+
module #{@pod_target.product_module_name}.Swift {
|
355
|
+
header "#{@pod_target.product_module_name}-Swift.h"
|
356
|
+
requires objc
|
357
|
+
}
|
358
|
+
SWIFT
|
359
|
+
end
|
360
|
+
f.write(content)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
# 生成 umbrella header
|
365
|
+
def generate_umbrella_header
|
366
|
+
umbrella_header_path = "#{headers_dir}/#{@pod_target}-umbrella.h"
|
367
|
+
return if File.exist?(umbrella_header_path)
|
368
|
+
|
369
|
+
umbrella_header = Pod::Generator::UmbrellaHeader.new(@pod_target)
|
370
|
+
# 需要导入的头文件
|
371
|
+
umbrella_header.imports = @file_accessors.flat_map(&:public_headers).compact.uniq.map { |header| header.basename }
|
372
|
+
FileUtils.mkdir(headers_dir) unless File.exist?(headers_dir)
|
373
|
+
result = umbrella_header.generate
|
374
|
+
File.open(umbrella_header_path, "w+") do |f|
|
375
|
+
f.write(result)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
|
2
|
+
module CBin
|
3
|
+
module BuildAll
|
4
|
+
class PodspecUtil
|
5
|
+
include Pod
|
6
|
+
|
7
|
+
def initialize(pod_target, version, build_as_framework = false )
|
8
|
+
@pod_target = pod_target
|
9
|
+
@version = version
|
10
|
+
@build_as_framework = build_as_framework
|
11
|
+
end
|
12
|
+
|
13
|
+
# 创建二进制podspec
|
14
|
+
def create_binary_podspec
|
15
|
+
UI.info "创建二进制podspec:#{@pod_target}".yellow
|
16
|
+
spec = @pod_target.root_spec.to_hash
|
17
|
+
root_dir = @pod_target.framework_name
|
18
|
+
# 处理版本号
|
19
|
+
spec['version'] = version
|
20
|
+
# 处理source
|
21
|
+
spec['source'] = source
|
22
|
+
# 处理头文件
|
23
|
+
spec['source_files'] = "#{root_dir}/Headers/*.h"
|
24
|
+
spec['public_header_files'] = "#{root_dir}/Headers/*.h"
|
25
|
+
spec['private_header_files'] = "#{root_dir}/PrivateHeaders/*.h"
|
26
|
+
# 处理vendored_libraries和vendored_frameworks
|
27
|
+
spec['vendored_libraries'] = "#{root_dir}/libs/*.a"
|
28
|
+
spec['vendored_frameworks'] = %W[#{root_dir} #{root_dir}/fwks/*.framework]
|
29
|
+
# 处理资源
|
30
|
+
resources = %W[#{root_dir}/*.{#{special_resource_exts.join(',')}} #{root_dir}/resources/*]
|
31
|
+
spec['resources'] = resources
|
32
|
+
# 删除无用的字段
|
33
|
+
delete_unused(spec)
|
34
|
+
# 处理subspecs
|
35
|
+
handle_subspecs(spec)
|
36
|
+
# 生成二进制podspec
|
37
|
+
bin_spec = Pod::Specification.from_hash(spec)
|
38
|
+
bin_spec.description = <<-EOF
|
39
|
+
「converted automatically by plugin cocoapods-mtxx-bin @美图 - zys」
|
40
|
+
#{bin_spec.description}
|
41
|
+
EOF
|
42
|
+
bin_spec
|
43
|
+
# puts bin_spec.to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
# podspec写入文件
|
47
|
+
def write_binary_podspec(spec)
|
48
|
+
UI.info "写入podspec:#{@pod_target}".yellow
|
49
|
+
podspec_dir = "#{Pathname.pwd}/build_pods/#{@pod_target}/Products/podspec"
|
50
|
+
FileUtils.mkdir(podspec_dir) unless File.exist?(podspec_dir)
|
51
|
+
file = "#{podspec_dir}/#{@pod_target.pod_name}.podspec.json"
|
52
|
+
FileUtils.rm_rf(file) if File.exist?(file)
|
53
|
+
|
54
|
+
File.open(file, "w+") do |f|
|
55
|
+
f.write(spec.to_pretty_json)
|
56
|
+
end
|
57
|
+
file
|
58
|
+
end
|
59
|
+
|
60
|
+
# 上传二进制podspec
|
61
|
+
def push_binary_podspec(binary_podsepc_json)
|
62
|
+
UI.info "推送podspec:#{@pod_target}".yellow
|
63
|
+
return unless File.exist?(binary_podsepc_json)
|
64
|
+
repo_name = Pod::Config.instance.sources_manager.binary_source.name
|
65
|
+
# repo_name = 'example-private-spec-bin'
|
66
|
+
argvs = %W[#{repo_name} #{binary_podsepc_json} --skip-import-validation --use-libraries --allow-warnings --verbose]
|
67
|
+
|
68
|
+
begin
|
69
|
+
push = Pod::Command::Repo::Push.new(CLAide::ARGV.new(argvs))
|
70
|
+
push.validate!
|
71
|
+
push.run
|
72
|
+
rescue Pod::StandardError => e
|
73
|
+
UI.info "推送podspec:#{@pod_target} 失败,#{e.to_s}".red
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# 删除无用的字段
|
80
|
+
def delete_unused(spec)
|
81
|
+
spec.delete('project_header_files')
|
82
|
+
spec.delete('resource_bundles')
|
83
|
+
spec.delete('exclude_files')
|
84
|
+
spec.delete('preserve_paths')
|
85
|
+
spec.delete('prepare_command')
|
86
|
+
end
|
87
|
+
|
88
|
+
# 处理subspecs
|
89
|
+
def handle_subspecs(spec)
|
90
|
+
spec['subspecs'].map do |subspec|
|
91
|
+
# 处理单个subspec
|
92
|
+
handle_single_subspec(subspec, spec)
|
93
|
+
# 递归处理subspec
|
94
|
+
recursive_handle_subspecs(subspec['subspecs'], spec)
|
95
|
+
end if spec && spec['subspecs']
|
96
|
+
end
|
97
|
+
|
98
|
+
# 递归处理subspecs
|
99
|
+
def recursive_handle_subspecs(subspecs, spec)
|
100
|
+
subspecs.map do |s|
|
101
|
+
# 处理单个subspec
|
102
|
+
handle_single_subspec(s, spec)
|
103
|
+
# 递归处理
|
104
|
+
recursive_handle_subspecs(s['subspecs'], spec)
|
105
|
+
end if subspecs
|
106
|
+
end
|
107
|
+
|
108
|
+
# 处理单个subspec
|
109
|
+
def handle_single_subspec(subspec, spec)
|
110
|
+
subspec['source_files'] = spec['source_files']
|
111
|
+
subspec['public_header_files'] = spec['public_header_files']
|
112
|
+
subspec['private_header_files'] = spec['private_header_files']
|
113
|
+
subspec['vendored_frameworks'] = spec['vendored_frameworks']
|
114
|
+
subspec['vendored_libraries'] = spec['vendored_libraries']
|
115
|
+
subspec['resources'] = spec['resources']
|
116
|
+
# 删除无用字段
|
117
|
+
delete_unused(subspec)
|
118
|
+
end
|
119
|
+
|
120
|
+
def source
|
121
|
+
# url = "http://localhost:8080/frameworks/#{@pod_target.root_spec.module_name}/#{version}/zip"
|
122
|
+
url = "#{CBin.config.binary_download_url_str}/#{@pod_target.root_spec.module_name}/#{version}/#{@pod_target.root_spec.module_name}.framework_#{version}.zip"
|
123
|
+
{ http: url, type: 'zip' }
|
124
|
+
end
|
125
|
+
|
126
|
+
def version
|
127
|
+
@version || @pod_target.root_spec.version
|
128
|
+
end
|
129
|
+
|
130
|
+
# 特殊的资源后缀
|
131
|
+
def special_resource_exts
|
132
|
+
%w[momd mom cdm nib storyboardc]
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module CBin
|
4
|
+
module BuildAll
|
5
|
+
class ZipFileHelper
|
6
|
+
include Pod
|
7
|
+
|
8
|
+
def initialize(pod_target, version, product_dir, build_as_framework = false)
|
9
|
+
@pod_target = pod_target
|
10
|
+
@version = version
|
11
|
+
@product_dir = product_dir
|
12
|
+
@build_as_framework = build_as_framework
|
13
|
+
end
|
14
|
+
|
15
|
+
# 上传静态库
|
16
|
+
def upload_zip_lib
|
17
|
+
Dir.chdir(@product_dir) do
|
18
|
+
zip_file = File.join(Dir.pwd, "#{zip_file_name}")
|
19
|
+
unless File.exist?(zip_file)
|
20
|
+
UI.info "#{Dir.pwd}目录下无 #{zip_file_name} 文件".red
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
UI.info "Uploading binary zip file #{@pod_target.root_spec.name} (#{@version || @pod_target.root_spec.version})".yellow do
|
24
|
+
upload_url = CBin.config.binary_upload_url_str
|
25
|
+
# upload_url = "http://localhost:8080/frameworks"
|
26
|
+
command = "curl -F \"name=#{@pod_target.product_module_name}\" -F \"version=#{@version || @pod_target.root_spec.version}\" -F \"file=@#{zip_file}\" #{upload_url}"
|
27
|
+
UI.info "#{command}"
|
28
|
+
json = `#{command}`
|
29
|
+
UI.info json
|
30
|
+
begin
|
31
|
+
error_code = JSON.parse(json)["error_code"]
|
32
|
+
if error_code == 0
|
33
|
+
Pod::UI.info "#{@pod_target.root_spec.name} (#{@pod_target.root_spec.version}) 上传成功".green
|
34
|
+
return true
|
35
|
+
else
|
36
|
+
Pod::UI.info "#{@pod_target.root_spec.name} (#{@pod_target.root_spec.version}) 上传失败".red
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
rescue JSON::ParserError => e
|
40
|
+
Pod::UI.info "#{@pod_target.root_spec.name} (#{@pod_target.root_spec.version}) 上传失败".red
|
41
|
+
Pod::UI.info "#{e.to_s}".red
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# 压缩静态库
|
49
|
+
def zip_lib
|
50
|
+
Dir.chdir(@product_dir) do
|
51
|
+
input_library = "#{@pod_target.framework_name}"
|
52
|
+
output_library = File.join(Dir.pwd, zip_file_name)
|
53
|
+
FileUtils.rm_f(output_library) if File.exist?(output_library)
|
54
|
+
unless File.exist?(input_library)
|
55
|
+
UI.info "没有需要压缩的二进制文件:#{input_library}".red
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
UI.info "Compressing #{input_library} into #{zip_file_name}".yellow do
|
60
|
+
command = "zip --symlinks -r #{output_library} #{input_library}"
|
61
|
+
UI.info "#{command}"
|
62
|
+
`#{command}`
|
63
|
+
unless File.exist?(output_library)
|
64
|
+
UI.info "压缩 #{output_library} 失败".red
|
65
|
+
return false
|
66
|
+
end
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# zip文件名字
|
73
|
+
def zip_file_name
|
74
|
+
@zip_file_name ||= begin
|
75
|
+
"#{@pod_target.framework_name}_#{@version || @pod_target.root_spec.version}.zip"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -57,9 +57,13 @@ module Pod
|
|
57
57
|
:release => Set.new,
|
58
58
|
}
|
59
59
|
|
60
|
+
podfile = Pod::Config.instance.podfile
|
61
|
+
|
60
62
|
if !specs.empty? && !all_specs.empty?
|
61
63
|
specs.each do |s|
|
62
64
|
s.dependencies(platform).each do |dep|
|
65
|
+
# use_binary = podfile.use_binaries? && !podfile.use_source_pods.include?(dep.root_name)
|
66
|
+
# key = use_binary ? dep.root_name : dep.name
|
63
67
|
all_specs[dep.name].each do |spec|
|
64
68
|
if spec.non_library_specification?
|
65
69
|
if s.test_specification? && spec.name == s.consumer(platform).app_host_name && spec.app_specification?
|