cocoapods-kz 0.0.10 → 0.0.13

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cocoapods-kz/command/clean.rb +30 -23
  3. data/lib/cocoapods-kz/command/install.rb +13 -3
  4. data/lib/cocoapods-kz/command/update.rb +13 -3
  5. data/lib/cocoapods-kz/gem_version.rb +1 -1
  6. data/lib/cocoapods-kz/helpers/kz_framework_manager.rb +169 -1
  7. data/lib/cocoapods-kz/helpers/kz_generator.rb +370 -39
  8. data/lib/cocoapods-kz/helpers/kz_global_helper.rb +28 -1
  9. data/lib/cocoapods-kz/helpers/kz_log.rb +11 -0
  10. data/lib/cocoapods-kz/helpers/kz_pod_target.rb +26 -6
  11. data/lib/cocoapods-kz/native/dls.rb +10 -0
  12. data/lib/cocoapods-kz/native/dsl_spec.rb +7 -0
  13. data/lib/cocoapods-kz/native/file_accessor.rb +8 -3
  14. data/lib/cocoapods-kz/native/installer.rb +3 -0
  15. data/lib/cocoapods-kz/native/pod_target_installer.rb +23 -0
  16. data/lib/cocoapods-kz/native/pod_target_integrator.rb +62 -0
  17. data/lib/cocoapods-kz/native/target_installer_helper.rb +40 -0
  18. data/lib/cocoapods-kz/native/target_integrator.rb +34 -0
  19. data/lib/cocoapods-kz/native.rb +2 -0
  20. data/lib/cocoapods-kz/resources/arm64ToSimulator +0 -0
  21. data/lib/cocoapods-kz/resources/kz_generator_framework.sh +6 -2
  22. data/lib/cocoapods-kz/resources/kz_improve_custom_yaml.sh +25 -0
  23. data/lib/cocoapods-kz/resources/kz_refresh_pods_pbxproj.rb +10 -6
  24. data/lib/cocoapods-kz/resources/on_demand_resources/kz_complete_asset_pack_output_spec_plist.rb +26 -0
  25. data/lib/cocoapods-kz/resources/on_demand_resources/kz_create_asset_pack_manifest_plist.rb +44 -0
  26. data/lib/cocoapods-kz/resources/on_demand_resources/kz_create_on_demand_resources_plis.rb +26 -0
  27. data/lib/cocoapods-kz/resources/on_demand_resources/kz_on_demand_resources_xocde.sh +162 -0
  28. metadata +13 -3
@@ -8,6 +8,8 @@ module KZ
8
8
  def initialize(main_project)
9
9
  @all_kz_pod_targets = KZGlobalHelper.instance.kz_analyzer.all_kz_pod_targets
10
10
  @main_project = main_project
11
+ @installation_root = Pod::Config.instance.installation_root
12
+ @on_demand_resources_folder = KZ_POD_CONFIG_ROOT + "OnDemandResources"
11
13
  end
12
14
 
13
15
  def add_framework_generator_build_phase(native_target)
@@ -29,20 +31,27 @@ module KZ
29
31
  end
30
32
 
31
33
  xml_rule = new_build_rule(project, native_target, '[KZ] Custom Xml Build')
34
+ xml_rule.run_once_per_architecture = '0'
32
35
  xml_rule.file_type = 'text.xml'
33
36
  xml_rule.output_files = Array['${KZ_XML_FLEX_DIR}/${INPUT_FILE_BASE}.flex']
34
37
  xml_rule.script = KZ.deal_path_for_xcconfig(KZ_XML_BUILD_PATH, true)
35
38
  end
36
39
 
37
40
  def add_force_load_exe_path_build_phase(native_target, output_path)
38
- return if KZ::KZGlobalHelper.instance.disable_generate_framework
39
-
40
41
  build_phase = native_target.new_shell_script_build_phase('[KZ] Froce Load File Output Path')
41
42
  build_phase.show_env_vars_in_log = '0'
42
43
  build_phase.output_paths = [output_path]
43
44
  build_phase.shell_script = KZ.deal_path_for_xcconfig(KZ_FIX_FORCE_LOAD_EXE, true)
44
45
  end
45
46
 
47
+ def add_improve_yaml_build_phase(project, native_target, output_path)
48
+ build_phase = new_shell_script_build_phase(project, native_target, '[KZ] Improve Custom Yaml', true)
49
+ build_phase.show_env_vars_in_log = '0'
50
+ # build_phase.always_out_of_date = '1'
51
+ build_phase.output_paths = [output_path]
52
+ build_phase.shell_script = KZ.deal_path_for_xcconfig(KZ_IMPROVE_CUSTOM_YAML_PATH, true)
53
+ end
54
+
46
55
  def new_build_rule(project, native_target, name)
47
56
  new_rule = nil
48
57
  native_target.build_rules.each do |build_rule|
@@ -59,6 +68,27 @@ module KZ
59
68
  new_rule
60
69
  end
61
70
 
71
+ def new_shell_script_build_phase(project, native_target, name, before_compile = false)
72
+ new_build_phase = project.new(Xcodeproj::Project::PBXShellScriptBuildPhase)
73
+ new_build_phase.name = name
74
+ if before_compile
75
+ find_compile = false
76
+ native_target.build_phases.each_with_index do |build_phase, index|
77
+ if build_phase.is_a?(Xcodeproj::Project::PBXSourcesBuildPhase)
78
+ find_compile = true
79
+ native_target.build_phases.insert(index, new_build_phase)
80
+ break
81
+ end
82
+ end
83
+ unless find_compile
84
+ native_target.build_phases << new_build_phase
85
+ end
86
+ else
87
+ native_target.build_phases << new_build_phase
88
+ end
89
+ new_build_phase
90
+ end
91
+
62
92
  def create_hamp
63
93
  # 创建壳工程hmap
64
94
  main_sources_path = @main_project.project_dir + @main_project.root_object.display_name
@@ -108,18 +138,33 @@ module KZ
108
138
 
109
139
  if all_repair_hmap_info.count > 0
110
140
  hmap_cache_path = kz_pod_target.pod_config_cache_path(false)
141
+ FileUtils.mkdir_p(hmap_cache_path) unless File.exist?(hmap_cache_path)
142
+
111
143
  save_hmap_file(all_repair_hmap_info, hmap_cache_path, target_name + '_repair')
112
144
  kz_pod_target.repair_header_search_path = hmap_cache_path + "#{target_name}_repair.hmap"
113
145
  end
114
146
 
115
147
  # 添加私有头文件引用
116
148
  if kz_pod_target.current_should_build?
117
- private_hamp_info = private_hmap_info(kz_pod_target)
118
- if private_hamp_info.count > 0
149
+ pod_hamp_info = pod_hmap_info(kz_pod_target)
150
+ if pod_hamp_info.count > 0
119
151
  hmap_cache_path = kz_pod_target.pod_config_cache_path(false)
120
- save_hmap_file(private_hamp_info, hmap_cache_path, target_name)
152
+ FileUtils.mkdir_p(hmap_cache_path) unless File.exist?(hmap_cache_path)
153
+
154
+ save_hmap_file(pod_hamp_info, hmap_cache_path, target_name)
121
155
  kz_pod_target.private_header_search_path = hmap_cache_path + "#{target_name}.hmap"
122
156
  end
157
+
158
+ pod_yaml_info = pod_yaml_info(kz_pod_target)
159
+ if pod_yaml_info.count > 0
160
+ yaml_cache_path = kz_pod_target.pod_config_cache_path(false)
161
+ FileUtils.mkdir_p(yaml_cache_path) unless File.exist?(yaml_cache_path)
162
+
163
+ yaml_name = "#{target_name}_origin.yaml"
164
+ save_yaml_file(pod_yaml_info, yaml_cache_path + yaml_name)
165
+ kz_pod_target.custom_origin_yaml_path = yaml_cache_path + yaml_name
166
+ kz_pod_target.custom_yaml_path = yaml_cache_path + "#{target_name}.yaml"
167
+ end
123
168
  end
124
169
  end
125
170
  end
@@ -141,13 +186,14 @@ module KZ
141
186
 
142
187
  def clean_hmap_cache(kz_pod_target)
143
188
  hmap_cache_path = kz_pod_target.pod_config_cache_path(false)
189
+
144
190
  Dir.foreach(hmap_cache_path) do |file_name|
145
191
  next if file_name == '.' || file_name == '..' || file_name == '.DS_Store'
146
192
 
147
- if file_name.end_with?(".hmap", ".json")
193
+ if file_name.end_with?(".hmap", ".json", "yaml")
148
194
  FileUtils.rm(hmap_cache_path + file_name) if File.exist?(hmap_cache_path + file_name)
149
195
  end
150
- end
196
+ end if File.exist?(hmap_cache_path)
151
197
  end
152
198
 
153
199
  def repair_hmap_info(kz_pod_target)
@@ -175,50 +221,105 @@ module KZ
175
221
  end
176
222
  end
177
223
 
178
- def private_hmap_info(kz_pod_target)
179
- header_paths = kz_pod_target.all_headers
180
- # 更新Headers
181
- if kz_pod_target.is_dev_pod
182
- header_paths.each do |header_pathname|
183
- symlink_path = kz_pod_target.local_private_headers_path + header_pathname.basename
184
- File.symlink(header_pathname, symlink_path) unless File.symlink?(symlink_path) || File.exist?(symlink_path)
185
- end
186
- kz_pod_target.use_local_private_headers_path = true
224
+ def pod_hmap_info(kz_pod_target)
225
+ pod_hmap_info = {}
226
+ module_name = kz_pod_target.kz_module_name
227
+
228
+ # public headers
229
+ public_headers = kz_pod_target.public_headers
230
+ public_headers.each do |header_pathname|
231
+ header_pathname_basename = header_pathname.basename.to_s
232
+
233
+ header_hmap_value_quotes = {}
234
+ header_hmap_value_quotes['suffix'] = header_pathname_basename
235
+ header_hmap_value_quotes['prefix'] = module_name + '/'
236
+ pod_hmap_info[header_pathname_basename] = header_hmap_value_quotes
237
+ pod_hmap_info[module_name + '/' + header_pathname_basename] = header_hmap_value_quotes
187
238
  end
188
- header_paths.each_with_object({}) do |header_pathname, hmap_info|
239
+
240
+ # private headers
241
+ all_headers = kz_pod_target.all_headers
242
+ (all_headers - public_headers).each do |header_pathname|
189
243
  header_pathname_basename = header_pathname.basename.to_s
190
244
 
191
245
  header_hmap_value_quotes = {}
192
246
  header_hmap_value_quotes['suffix'] = header_pathname_basename
193
247
  header_hmap_value_quotes['prefix'] = header_pathname.dirname.to_s + '/'
194
- hmap_info[header_pathname_basename] = header_hmap_value_quotes
248
+ pod_hmap_info[header_pathname_basename] = header_hmap_value_quotes
249
+ end
195
250
 
196
- # pch
197
- pchfile_path = kz_pod_target.prefix_header_path
198
- if pchfile_path.exist?
199
- suffix = pchfile_path.basename.to_s
200
- hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{pchfile_path.dirname.to_s}/" }
201
- end
251
+ # pch
252
+ pchfile_path = kz_pod_target.prefix_header_path
253
+ if pchfile_path.exist?
254
+ suffix = pchfile_path.basename.to_s
255
+ pod_hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{pchfile_path.dirname.to_s}/" }
256
+ end
202
257
 
203
- unless kz_pod_target.is_dev_pod
204
- # 个别第三方在使用自己组件文件时,会使用#import <xx/xx.h>的方式
205
- hmap_info[kz_pod_target.product_basename + '/' + header_pathname_basename] = header_hmap_value_quotes
206
- end
258
+ # umbrella
259
+ umbrella_path = kz_pod_target.umbrella_header_path
260
+ if umbrella_path.exist?
261
+ suffix = umbrella_path.basename.to_s
262
+ pod_hmap_info[suffix] = { 'suffix' => suffix, 'prefix' => "#{module_name}/" }
263
+ end
207
264
 
208
- if kz_pod_target.current_uses_swift? && kz_pod_target.is_dev_pod
209
- # 修改SPBoss-Swift.h文件的导入方式
210
- swift_bridge_file_name = "#{kz_pod_target.name}-Swift.h"
211
- hmap_info[swift_bridge_file_name] = { 'suffix' => swift_bridge_file_name, 'prefix' => "#{kz_pod_target.name}/" }
265
+ if kz_pod_target.current_uses_swift? && kz_pod_target.is_dev_pod
266
+ # 修改SPBoss-Swift.h文件的导入方式
267
+ swift_bridge_file_name = "#{module_name}-Swift.h"
268
+ pod_hmap_info[swift_bridge_file_name] = { 'suffix' => swift_bridge_file_name, 'prefix' => "#{module_name}/" }
269
+ end
212
270
 
213
- # 以SPBoss为例,在混编模式中,SPBoss-Swift.h会使用#import <SPBoss/SPBoss.h>方式导入swift需要使用的OC头文件
214
- # SPBoss中头文件会存在当前组件与framework的Headers中,有两份。SPBoss-Swift.h只在framework中
215
- # 编译默认从SPBoss-Swift.h找SPBoss.h,然后找SPBoss.h中的头文件也都会在framework中寻在,会造成与当前组件头文件重复
216
- # 需要重新将#import <SPBoss/SPBoss.h>方式修复为寻找当前组件中的SPBoss.h文件,而不是framework中的SPBoss.h
217
- if header_pathname_basename == "#{kz_pod_target.name}.h"
218
- hmap_info[kz_pod_target.name + '/' + header_pathname_basename] = header_hmap_value_quotes
219
- end
271
+ # 另存一份Headers,用于创建文件与import时的提示信息
272
+ if kz_pod_target.is_dev_pod
273
+ all_headers.each do |header_pathname|
274
+ symlink_path = kz_pod_target.local_private_headers_path + header_pathname.basename
275
+ File.symlink(header_pathname, symlink_path) unless File.symlink?(symlink_path) || File.exist?(symlink_path)
220
276
  end
277
+ kz_pod_target.use_local_private_headers_path = true
221
278
  end
279
+ pod_hmap_info
280
+ end
281
+
282
+ def pod_yaml_info(kz_pod_target)
283
+ built_products_dir = "__built_products_dir__/"
284
+
285
+ pod_yaml_info = {}
286
+ pod_yaml_info["case-sensitive"] = "false"
287
+ pod_yaml_info["version"] = "0"
288
+
289
+ yaml_roots = []
290
+ pod_yaml_info["roots"] = yaml_roots
291
+
292
+ yaml_header_info = {}
293
+ yaml_header_info["type"] = "directory"
294
+ yaml_header_info["name"] = built_products_dir + "#{kz_pod_target.product_name}/Headers"
295
+ yaml_roots.append(yaml_header_info)
296
+
297
+ public_headers = kz_pod_target.public_headers
298
+ yaml_header_contents = []
299
+ yaml_header_info["contents"] = yaml_header_contents
300
+ public_headers.each do |header_pathname|
301
+ yaml_header_content = {}
302
+ yaml_header_content["type"] = "file"
303
+ yaml_header_content["name"] = header_pathname.basename.to_s
304
+ yaml_header_content["external-contents"] = header_pathname.to_s
305
+ yaml_header_contents.append(yaml_header_content)
306
+ end
307
+
308
+ yaml_modulemap_info = {}
309
+ yaml_modulemap_info["type"] = "directory"
310
+ yaml_modulemap_info["name"] = built_products_dir + "#{kz_pod_target.product_name}/Modules"
311
+ yaml_roots.append(yaml_modulemap_info)
312
+
313
+ yaml_modulemap_contents = []
314
+ yaml_modulemap_info["contents"] = yaml_modulemap_contents
315
+
316
+ yaml_modulemap_content = {}
317
+ yaml_modulemap_content["type"] = "file"
318
+ yaml_modulemap_content["name"] = "module.modulemap"
319
+ yaml_modulemap_content["external-contents"] = built_products_dir + "#{kz_pod_target.product_name}/Modules/module.modulemap"
320
+ yaml_modulemap_contents.append(yaml_modulemap_content)
321
+
322
+ pod_yaml_info
222
323
  end
223
324
 
224
325
  def save_hmap_file(hmap_hash, save_path, file_name)
@@ -229,10 +330,240 @@ module KZ
229
330
  return unless json_file
230
331
 
231
332
  json_file.syswrite(hmap_json)
333
+ json_file.close
334
+
232
335
  system "#{HMAP_EXECUTE_PATH} convert #{hmap_json_path} #{hmap_path}"
233
336
 
234
337
  FileUtils.rm(hmap_json_path) unless KZ::KZGlobalHelper.instance.debug
235
338
  end
236
339
 
340
+ def save_yaml_file(yaml_hash, save_path)
341
+ yaml_json = JSON.pretty_generate(yaml_hash)
342
+ json_file = File.new(save_path, 'w')
343
+ return unless json_file
344
+
345
+ json_file.syswrite(yaml_json)
346
+ json_file.close
347
+ end
348
+
349
+ def create_on_demand_resources
350
+ # 清除历史配置
351
+ FileUtils.rm_r(@on_demand_resources_folder) if File.exist?(@on_demand_resources_folder)
352
+ FileUtils.mkdir_p(@on_demand_resources_folder)
353
+
354
+ # 汇总所有配置文件,用于代码中加载资源
355
+ on_demand_resources_all_config = {}
356
+ @all_kz_pod_targets.each do |target_name, kz_pod_target|
357
+ if kz_pod_target.is_dev_pod
358
+ # 寻找配置文件KZOnDemandResourcesConfig.plist
359
+ kz_pod_target.native_pod_target.file_accessors.each do |file_accessor|
360
+ file_accessor.resource_bundles.map do |bundle_name, paths|
361
+ paths.each do |path|
362
+ if path.basename.to_s == "KZOnDemandResourcesConfig.plist"
363
+ plist_hash = Xcodeproj::Plist.read_from_path(path)
364
+ if plist_hash.size > 0
365
+ on_demand_resources_all_config[kz_pod_target.name] = plist_hash
366
+ analyze_on_demand_resources_config_plist(plist_hash, kz_pod_target, paths)
367
+ kz_pod_target.add_on_demand_resources(path)
368
+ end
369
+ end
370
+ end
371
+ end
372
+ end
373
+ end
374
+ end
375
+
376
+ if on_demand_resources_all_config.size > 0
377
+ use_for_code_plist_path = @on_demand_resources_folder + "KZOnDemandResourcesAllConfig.plist"
378
+ Xcodeproj::Plist.write_to_path(on_demand_resources_all_config, use_for_code_plist_path)
379
+ end
380
+ end
381
+
382
+ def analyze_on_demand_resources_config_plist(plist_hash, kz_pod_target, all_resources_paths)
383
+ resources_path = @on_demand_resources_folder + "Bundles/#{kz_pod_target.name}"
384
+ FileUtils.mkdir_p(resources_path)
385
+
386
+ # 生成AssetPackOutputSpecifications.plist,用于Images.xcassets编译
387
+ asset_pack_output_specifications_resources = []
388
+
389
+ # 用于生成OnDemandResources.plist文件,放到main bundle中标记按需加载资源
390
+ on_demand_resources_plist = {}
391
+ bundle_resource_request_tags = {}
392
+ on_demand_resources_plist["NSBundleResourceRequestTags"] = bundle_resource_request_tags
393
+ bundle_resource_request_asset_packs = {}
394
+ on_demand_resources_plist["NSBundleResourceRequestAssetPacks"] = bundle_resource_request_asset_packs
395
+
396
+ # 统计所有的xcassets资源
397
+ have_config_xcassets = false
398
+
399
+ # 从配置plist中读取'Initial Install Tags'资源
400
+ initial_plist_hash = plist_hash["Initial Install Tags"]
401
+ on_deman_resources_from_plist(initial_plist_hash, kz_pod_target, 1, all_resources_paths, resources_path) do |tag, bundle_id, bundle_path, normal_file_names, have_xcassets_paths|
402
+ # 如有配置中有.xcassets资源,需要先标记,等待编译时单独再单独编译
403
+ if have_xcassets_paths
404
+ have_config_xcassets = true
405
+
406
+ resource_item = {}
407
+ resource_item["bundle-id"] = bundle_id
408
+ resource_item["bundle-path"] = bundle_path
409
+ resource_item["tags"] = [tag]
410
+ asset_pack_output_specifications_resources << resource_item
411
+ end
412
+
413
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
414
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
415
+ end
416
+
417
+ # Prefetched Tag Order
418
+ prefetched_plist_hash = plist_hash["Prefetched Tag Order"]
419
+ on_deman_resources_from_plist(prefetched_plist_hash, kz_pod_target, 0.5, all_resources_paths, resources_path) do |tag, bundle_id, bunlde_path, normal_file_names, have_xcassets_paths|
420
+ if have_xcassets_paths
421
+ have_config_xcassets = true
422
+
423
+ resource_item = {}
424
+ resource_item["bundle-id"] = bundle_id
425
+ resource_item["bundle-path"] = bunlde_path
426
+ resource_item["tags"] = [tag]
427
+ asset_pack_output_specifications_resources << resource_item
428
+ end
429
+
430
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
431
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
432
+ end
433
+
434
+ # Download Only On Demand
435
+ download_plist_hash = plist_hash["Download Only On Demand"]
436
+ on_deman_resources_from_plist(download_plist_hash, kz_pod_target, 0, all_resources_paths, resources_path) do |tag, bundle_id, bunlde_path, normal_file_names, have_xcassets_paths|
437
+ if have_xcassets_paths
438
+ have_config_xcassets = true
439
+
440
+ resource_item = {}
441
+ resource_item["bundle-id"] = bundle_id
442
+ resource_item["bundle-path"] = bunlde_path
443
+ resource_item["tags"] = [tag]
444
+ asset_pack_output_specifications_resources << resource_item
445
+ end
446
+
447
+ bundle_resource_request_tags[tag] = { "NSAssetPacks" => [bundle_id] }
448
+ bundle_resource_request_asset_packs[bundle_id] = normal_file_names if normal_file_names.size > 0
449
+ end
450
+
451
+ if asset_pack_output_specifications_resources.size > 0
452
+ write_to_path(asset_pack_output_specifications_resources, resources_path + "AssetPackOutputSpecifications.plist")
453
+ end
454
+
455
+ if bundle_resource_request_tags.size > 0 || bundle_resource_request_asset_packs.size > 0
456
+ Xcodeproj::Plist.write_to_path(on_demand_resources_plist, resources_path + "OnDemandResources.plist")
457
+ end
458
+
459
+ # 一个组件可能有多个xcassets,只要其中一个有配置on demand resources,所有xcassets都需要单独编译
460
+ all_xcassets_paths = []
461
+ if have_config_xcassets
462
+ all_resources_paths.each do |path|
463
+ if path.extname == ".xcassets"
464
+ all_xcassets_paths << path
465
+ end
466
+ end
467
+ end
468
+
469
+ target_bundle_info = {}
470
+ target_bundle_info["name"] = kz_pod_target.name
471
+ target_bundle_info["xcassets_paths"] = all_xcassets_paths
472
+ Xcodeproj::Plist.write_to_path(target_bundle_info, resources_path + "TargetBundleInfo.plist")
473
+
474
+ end
475
+
476
+ def on_deman_resources_from_plist(plist_hash, kz_pod_target, priority, all_resources_paths, resources_path)
477
+ return unless (!plist_hash.nil? && plist_hash.size > 0)
478
+
479
+ plist_hash.each do |tag, file_paths|
480
+ normal_file_names = []
481
+ normal_file_paths = []
482
+ have_xcassets_paths = false
483
+ file_paths.each do |rel_file_path|
484
+ file_path = @installation_root + rel_file_path.strip
485
+ next unless file_path.exist?
486
+
487
+ if file_path.extname == ".imageset"
488
+ # imageset文件配置
489
+ xcassets_path = find_xcassets_path(file_path)
490
+ if all_resources_paths.include?(xcassets_path)
491
+ kz_pod_target.add_on_demand_resources(xcassets_path)
492
+ have_xcassets_paths = true
493
+ end
494
+
495
+ content_json_path = file_path + "Contents.json"
496
+ content_json = JSON.parse(File.read(file_path + "Contents.json"))
497
+ content_json["properties"] = { "on-demand-resource-tags" => [tag] }
498
+ content_json_file = File.new(content_json_path, 'w')
499
+ content_json_file.syswrite(JSON.pretty_generate(content_json))
500
+ else
501
+ # 普通文件配置
502
+ if all_resources_paths.include?(file_path)
503
+ kz_pod_target.add_on_demand_resources(file_path)
504
+ normal_file_paths << file_path
505
+ normal_file_names << file_path.basename
506
+ end
507
+ end
508
+ end
509
+
510
+ create_bundle_info_plist(tag, priority, normal_file_paths, resources_path) do |bundle_id, bundle_path|
511
+ yield(tag, bundle_id, bundle_path, normal_file_names, have_xcassets_paths)
512
+ end
513
+ end
514
+ end
515
+
516
+ def find_xcassets_path(path)
517
+ return "" if path.root?
518
+
519
+ if path.extname == ".xcassets"
520
+ path
521
+ else
522
+ find_xcassets_path(path + "..")
523
+ end
524
+ end
525
+
526
+ def create_bundle_info_plist(tag, priority, normal_file_paths, resource_path)
527
+ # project bundle identifier
528
+ project_bundle_identifier = KZGlobalHelper.instance.on_demand_resources_bundle_id
529
+ tag_md5 = md5_sign(tag)
530
+ # bundle folder
531
+ demand_bundle_folder_name = "#{project_bundle_identifier}.#{tag}-#{tag_md5}.assetpack"
532
+ demand_bundle_folder = resource_path + "OnDemandResources/#{demand_bundle_folder_name}"
533
+ # create bundle folder
534
+ FileUtils.mkdir_p(demand_bundle_folder) unless FileTest::exist?(demand_bundle_folder)
535
+ # copy file
536
+ normal_file_paths.each do |file|
537
+ FileUtils.cp(file, demand_bundle_folder)
538
+ end
539
+
540
+ bundle_info_plist = {}
541
+ bundle_info_plist["Priority"] = priority if priority > 0
542
+ bundle_info_plist["Tags"] = [tag]
543
+ demand_bundle_id = "#{project_bundle_identifier}.asset-pack-#{tag_md5}"
544
+ bundle_info_plist["CFBundleIdentifier"] = demand_bundle_id
545
+ Xcodeproj::Plist.write_to_path(bundle_info_plist, demand_bundle_folder + "Info.plist")
546
+
547
+ yield(demand_bundle_id, demand_bundle_folder_name)
548
+ end
549
+
550
+ def md5_sign(key)
551
+ OpenSSL::Digest::MD5.hexdigest(key)
552
+ end
553
+
554
+ # Xcodeproj::Plist.write_to_path只支持hash,如果是数组需要重写write方法
555
+ def write_to_path(hash, path)
556
+ unless path.is_a?(String) || path.is_a?(Pathname)
557
+ raise TypeError, "The given `#{path}` must be a string or 'pathname'."
558
+ end
559
+ path = path.to_s
560
+ raise IOError, 'Empty path.' if path.empty?
561
+
562
+ File.open(path, 'w') do |f|
563
+ plist = Nanaimo::Plist.new(hash, :xml)
564
+ Nanaimo::Writer::XMLWriter.new(plist, :pretty => true, :output => f, :strict => false).write
565
+ end
566
+ end
567
+
237
568
  end
238
569
  end
@@ -18,11 +18,16 @@ module KZ
18
18
 
19
19
  HMAP_EXECUTE_PATH = File.dirname(__FILE__) + '/../resources/hmap'
20
20
  FLEX_COMPLIER_PATH = KZ_POD_CONFIG_SUPPORT_FILES + 'FlexCompiler'
21
+ ARM64_TO_SIMULATOR_EXECUTE_PATH = File.dirname(__FILE__) + '/../resources/arm64ToSimulator'
21
22
  KZ_GENERATOR_FRAMEWORK_PATH = KZ_POD_CONFIG_SUPPORT_FILES + 'kz_generator_framework.sh'
22
23
  KZ_XML_BUILD_PATH = KZ_POD_CONFIG_SUPPORT_FILES + 'kz_xml_build.sh'
23
24
  KZ_LOCK_FILE_PATH = KZ_POD_CONFIG_ROOT + 'KZConfigLock'
24
25
  KZ_FIX_FORCE_LOAD_EXE = KZ_POD_CONFIG_SUPPORT_FILES + 'kz_fix_force_load_exe.sh'
25
26
  KZ_FEFRESH_PODS_PBXPROJ = KZ_POD_CONFIG_SUPPORT_FILES + 'kz_refresh_pods_pbxproj.rb'
27
+ KZ_IMPROVE_CUSTOM_YAML_PATH = KZ_POD_CONFIG_SUPPORT_FILES + 'kz_improve_custom_yaml.sh'
28
+
29
+ KZ_ON_DEMAND_RESOURCES = KZ_POD_CONFIG_SUPPORT_FILES + 'on_demand_resources'
30
+ KZ_ON_DEMAND_RESOURCES_SHELL = KZ_ON_DEMAND_RESOURCES + 'kz_on_demand_resources_xocde.sh'
26
31
 
27
32
  def self.deal_path_for_xcconfig(path, add_quotes = false)
28
33
  if path.is_a?(String)
@@ -48,6 +53,9 @@ module KZ
48
53
  attr_accessor :kz_config_lock
49
54
  attr_accessor :disable_generate_framework
50
55
  attr_accessor :generate_kz_pod_targets
56
+ attr_accessor :debug_shell_log_tag
57
+ attr_accessor :arm64_simulator
58
+ attr_accessor :on_demand_resources_bundle_id
51
59
 
52
60
  private_class_method :new
53
61
 
@@ -60,6 +68,15 @@ module KZ
60
68
  @disable_generate_framework = false
61
69
  @generate_kz_pod_targets = false
62
70
  @olde_lock_file_content = nil
71
+ @debug_shell_log_tag = "&> /dev/null"
72
+ @arm64_simulator = false
73
+ end
74
+
75
+ def debug=(value)
76
+ @debug = value
77
+ if debug
78
+ @debug_shell_log_tag = ""
79
+ end
63
80
  end
64
81
 
65
82
  @@instance = nil
@@ -76,7 +93,8 @@ module KZ
76
93
  end
77
94
  FileUtils.mkdir_p(KZ_POD_CONFIG_SUPPORT_FILES) unless File.exist?(KZ_POD_CONFIG_SUPPORT_FILES)
78
95
  FileUtils.mkdir_p(KZ_POD_CONFIG_POD_TARGETS) unless File.exist?(KZ_POD_CONFIG_POD_TARGETS)
79
- FileUtils.mkdir_p(KZ_POD_CONFIG_POD_TEMPDIR) unless File.exist?(KZ_POD_CONFIG_POD_TEMPDIR)
96
+ FileUtils.rm_rf(KZ_POD_CONFIG_POD_TEMPDIR) if File.exist?(KZ_POD_CONFIG_POD_TEMPDIR)
97
+ FileUtils.mkdir_p(KZ_POD_CONFIG_POD_TEMPDIR)
80
98
 
81
99
  FileUtils.rm(FLEX_COMPLIER_PATH) if File.exist?(FLEX_COMPLIER_PATH)
82
100
  FileUtils.cp_r(File.dirname(__FILE__) + '/../resources/FlexCompiler', FLEX_COMPLIER_PATH)
@@ -93,7 +111,16 @@ module KZ
93
111
 
94
112
  FileUtils.cp_r(File.dirname(__FILE__) + '/../resources/kz_refresh_pods_pbxproj.rb', KZ_FEFRESH_PODS_PBXPROJ)
95
113
 
114
+ FileUtils.cp_r(File.dirname(__FILE__) + '/../resources/kz_improve_custom_yaml.sh', KZ_IMPROVE_CUSTOM_YAML_PATH)
115
+ system("chmod +x #{KZ_IMPROVE_CUSTOM_YAML_PATH}")
116
+
96
117
  Pod::Config.instance.podfile.use_frameworks!(:linkage => :static)
118
+
119
+ if !@on_demand_resources_bundle_id.nil?
120
+ FileUtils.rm_r(KZ_ON_DEMAND_RESOURCES) if File.exist?(KZ_ON_DEMAND_RESOURCES)
121
+ FileUtils.cp_r(File.dirname(__FILE__) + '/../resources/on_demand_resources/', KZ_ON_DEMAND_RESOURCES)
122
+ system("chmod +x #{KZ_ON_DEMAND_RESOURCES_SHELL}")
123
+ end
97
124
  else
98
125
  @kz_pod_enable = false
99
126
  @generate_kz_pod_targets = false
@@ -0,0 +1,11 @@
1
+ module KZ
2
+
3
+ class KZLog
4
+ def self.log(logStr)
5
+ if KZGlobalHelper.instance.debug
6
+ puts logStr
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -26,6 +26,8 @@ module KZ
26
26
  # 用于临时保存hamp过程的配置
27
27
  attr_accessor :private_header_search_path
28
28
  attr_accessor :repair_header_search_path
29
+ attr_accessor :custom_yaml_path
30
+ attr_accessor :custom_origin_yaml_path
29
31
 
30
32
  attr_accessor :platform_name
31
33
  # target编译最终的产物名称
@@ -46,6 +48,8 @@ module KZ
46
48
 
47
49
  attr_accessor :use_modulemap
48
50
 
51
+ attr_accessor :disable_to_simulator_frameworks
52
+
49
53
  def initialize(native_pod_target)
50
54
  @native_pod_target = native_pod_target
51
55
  @name = native_pod_target.name
@@ -64,6 +68,9 @@ module KZ
64
68
  @use_local_private_headers_path = false
65
69
  @force_load = false
66
70
  @use_modulemap = true
71
+ @disable_to_simulator_frameworks = []
72
+ # 配置按需加载的资源,需要从bundle target中移除,然后手动进行配置
73
+ @on_demand_resources = []
67
74
 
68
75
  native_pod_target.file_accessors.each do |file_accessor|
69
76
  file_accessor.kz_pod_target = self
@@ -188,6 +195,8 @@ module KZ
188
195
 
189
196
  # 直接用于配置HEADER_SEARCH_PATHS
190
197
  def header_search_paths(custom_paths)
198
+ return '' unless current_should_build?
199
+
191
200
  header_search_paths = ''
192
201
  header_search_paths = KZ.deal_path_for_xcconfig(@private_header_search_path, true) if @private_header_search_path
193
202
  repair_header_search_paths = self.all_repair_header_search_paths.join(' ')
@@ -226,11 +235,11 @@ module KZ
226
235
  end
227
236
 
228
237
  # 获取target对应的配置根目录,部分文件需要依赖版本进行存储
229
- def pod_config_cache_path(concat_version)
230
- kz_target_framework_folder = KZ_POD_CONFIG_POD_TARGETS + @name
231
- kz_target_framework_folder += @version if concat_version
232
- FileUtils.mkdir_p(kz_target_framework_folder) unless File.exist?(kz_target_framework_folder) || concat_version
233
- kz_target_framework_folder
238
+ def pod_config_cache_path(concat_version, vendored_framework = false)
239
+ kz_target_config_folder = KZ_POD_CONFIG_POD_TARGETS + @name
240
+ kz_target_config_folder += @version if concat_version
241
+ kz_target_config_folder += "vendored_framework" if vendored_framework
242
+ kz_target_config_folder
234
243
  end
235
244
 
236
245
  # 获取target中的module name,默认为product_module_name与target.name也相同。
@@ -247,7 +256,7 @@ module KZ
247
256
  end
248
257
  end
249
258
  end
250
- return @native_pod_target.product_module_name
259
+ @native_pod_target.product_module_name
251
260
  end
252
261
 
253
262
  # 获取所有用于修复的modulemap路径,原因参考@repair_modulemap_path
@@ -275,6 +284,10 @@ module KZ
275
284
  @native_pod_target.prefix_header_path
276
285
  end
277
286
 
287
+ def umbrella_header_path
288
+ @native_pod_target.umbrella_header_path
289
+ end
290
+
278
291
  # 当前pod是否存在可编译的文件,配置framework后当前pod就不存在可编译文件
279
292
  def current_should_build?
280
293
  @native_pod_target.should_build?
@@ -328,5 +341,12 @@ module KZ
328
341
  @native_pod_target.configuration_build_dir
329
342
  end
330
343
 
344
+ def add_on_demand_resources(path)
345
+ @on_demand_resources.push(path).uniq!
346
+ end
347
+ def get_on_demand_resources
348
+ @on_demand_resources
349
+ end
350
+
331
351
  end
332
352
  end
@@ -40,6 +40,16 @@ module Pod
40
40
  KZ::KZGlobalHelper.instance.kz_pod_config.merge!(kz_pod_config)
41
41
  end
42
42
 
43
+ def kz_cocoapods_configure(*requirements)
44
+ configure = requirements.last
45
+ return false unless configure.is_a?(Hash)
46
+
47
+ on_demand_resources_bundle_id = configure.delete(:on_demand_resources_bundle_id)
48
+ if !on_demand_resources_bundle_id.nil? && on_demand_resources_bundle_id.is_a?(String)
49
+ KZ::KZGlobalHelper.instance.on_demand_resources_bundle_id = on_demand_resources_bundle_id
50
+ end
51
+ end
52
+
43
53
  end
44
54
  end
45
55
  end