pindo 5.12.2 → 5.13.2
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/pindo/base/git_handler.rb +692 -0
- data/lib/pindo/command/android/autobuild.rb +2 -2
- data/lib/pindo/command/android.rb +0 -1
- data/lib/pindo/command/appstore/adhocbuild.rb +258 -311
- data/lib/pindo/command/appstore/autobuild.rb +203 -0
- data/lib/pindo/command/appstore/autoresign.rb +35 -17
- data/lib/pindo/command/appstore/bundleid.rb +120 -0
- data/lib/pindo/command/appstore/cert.rb +212 -0
- data/lib/pindo/command/appstore/configproj.rb +81 -0
- data/lib/pindo/command/{deploy → appstore}/getitcinfo.rb +76 -91
- data/lib/pindo/command/appstore/iap.rb +788 -24
- data/lib/pindo/command/appstore/initconfig.rb +105 -0
- data/lib/pindo/command/appstore/itcapp.rb +95 -13
- data/lib/pindo/command/{deploy → appstore}/itcinfo.rb +90 -118
- data/lib/pindo/command/appstore/pem.rb +136 -0
- data/lib/pindo/command/appstore/pullconfig.rb +99 -0
- data/lib/pindo/command/appstore/quswark.rb +87 -0
- data/lib/pindo/command/appstore/quswauth.rb +67 -0
- data/lib/pindo/command/appstore/tag.rb +77 -0
- data/lib/pindo/command/appstore.rb +13 -1
- data/lib/pindo/command/env/quarkenv.rb +11 -13
- data/lib/pindo/command/env/swarkenv.rb +11 -16
- data/lib/pindo/command/ios/autobuild.rb +64 -43
- data/lib/pindo/command/ios/autoresign.rb +34 -19
- data/lib/pindo/command/ios/build.rb +10 -7
- data/lib/pindo/command/ios/cert.rb +27 -20
- data/lib/pindo/command/jps/upload.rb +3 -3
- data/lib/pindo/command/unity/autobuild.rb +2 -2
- data/lib/pindo/command/utils/clearcert.rb +2 -17
- data/lib/pindo/command/{deploy → utils}/fabric.rb +13 -13
- data/lib/pindo/command/utils/renewcert.rb +62 -38
- data/lib/pindo/command/utils/renewproj.rb +0 -3
- data/lib/pindo/command/{deploy → utils}/updateconfig.rb +6 -7
- data/lib/pindo/command/utils.rb +2 -0
- data/lib/pindo/command/web/autobuild.rb +2 -2
- data/lib/pindo/command.rb +30 -3
- data/lib/pindo/config/build_info_manager.rb +176 -0
- data/lib/pindo/config/ios_config_parser.rb +404 -0
- data/lib/pindo/module/android/android_build_helper.rb +110 -0
- data/lib/pindo/module/android/android_config_helper.rb +9 -5
- data/lib/pindo/module/android/gradle_helper.rb +88 -0
- data/lib/pindo/module/appstore/bundleid_helper.rb +349 -0
- data/lib/pindo/module/appstore/itcapp_helper.rb +228 -0
- data/lib/pindo/module/build/build_helper.rb +12 -0
- data/lib/pindo/module/build/swark_helper.rb +116 -77
- data/lib/pindo/module/cert/cert_helper.rb +74 -0
- data/lib/pindo/module/cert/pem_helper.rb +72 -0
- data/lib/pindo/module/cert/{xcodecerthelper.rb → xcode_cert_helper.rb} +208 -6
- data/lib/pindo/module/task/model/appstore/appstore_task.rb +18 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_ipa_task.rb +151 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_metadata_task.rb +250 -0
- data/lib/pindo/module/task/model/appstore/appstore_upload_screenshot_task.rb +276 -0
- data/lib/pindo/module/task/model/build/android_build_adhoc_task.rb +210 -0
- data/lib/pindo/module/task/model/build/{android_dev_build_task.rb → android_build_dev_task.rb} +2 -2
- data/lib/pindo/module/task/model/build/android_build_gplay_task.rb +210 -0
- data/lib/pindo/module/task/model/build/android_build_task.rb +13 -0
- data/lib/pindo/module/task/model/build/ios_build_adhoc_task.rb +197 -0
- data/lib/pindo/module/task/model/build/ios_build_appstore_task.rb +367 -0
- data/lib/pindo/module/task/model/build/{ios_dev_build_task.rb → ios_build_dev_task.rb} +37 -27
- data/lib/pindo/module/task/model/build/ios_build_task.rb +13 -0
- data/lib/pindo/module/task/model/build/{web_dev_build_task.rb → web_build_dev_task.rb} +1 -1
- data/lib/pindo/module/task/model/build_task.rb +15 -12
- data/lib/pindo/module/task/model/jps_resign_task.rb +185 -0
- data/lib/pindo/module/task/model/{upload_task.rb → jps_upload_task.rb} +3 -3
- data/lib/pindo/module/task/model/unity_export_task.rb +3 -1
- data/lib/pindo/module/task/pindo_task.rb +19 -10
- data/lib/pindo/module/unity/unity_helper.rb +2 -1
- data/lib/pindo/module/xcode/ipa_resign_helper.rb +210 -0
- data/lib/pindo/module/xcode/{xcodeappconfig.rb → xcode_app_config.rb} +79 -0
- data/lib/pindo/module/xcode/xcode_build_config.rb +152 -17
- data/lib/pindo/module/xcode/xcode_build_helper.rb +151 -1
- data/lib/pindo/module/xcode/xcode_swark_helper.rb +341 -0
- data/lib/pindo/options/core/global_options_state.rb +268 -0
- data/lib/pindo/options/core/option_configuration.rb +206 -0
- data/lib/pindo/options/core/option_initializer.rb +51 -0
- data/lib/pindo/options/core/option_item.rb +144 -0
- data/lib/pindo/options/core/option_value_parser.rb +54 -0
- data/lib/pindo/options/groups/build_options.rb +60 -0
- data/lib/pindo/options/groups/jps_options.rb +70 -0
- data/lib/pindo/options/groups/option_group.rb +73 -0
- data/lib/pindo/options/helpers/bundleid_selector.rb +103 -0
- data/lib/pindo/options/options.rb +14 -0
- data/lib/pindo/version.rb +1 -1
- metadata +49 -41
- data/lib/pindo/command/android/build.rb +0 -186
- data/lib/pindo/command/appstore/import.rb +0 -259
- data/lib/pindo/command/deploy/build.rb +0 -250
- data/lib/pindo/command/deploy/bundleid.rb +0 -259
- data/lib/pindo/command/deploy/cert.rb +0 -202
- data/lib/pindo/command/deploy/check.rb +0 -93
- data/lib/pindo/command/deploy/configproj.rb +0 -120
- data/lib/pindo/command/deploy/confusecode.rb +0 -262
- data/lib/pindo/command/deploy/confuseproj.rb +0 -122
- data/lib/pindo/command/deploy/iap.rb +0 -826
- data/lib/pindo/command/deploy/initconfig.rb +0 -138
- data/lib/pindo/command/deploy/itcapp.rb +0 -146
- data/lib/pindo/command/deploy/pem.rb +0 -55
- data/lib/pindo/command/deploy/pullconfig.rb +0 -56
- data/lib/pindo/command/deploy/pushconfig.rb +0 -93
- data/lib/pindo/command/deploy/quswark.rb +0 -156
- data/lib/pindo/command/deploy/quswauth.rb +0 -76
- data/lib/pindo/command/deploy/reportbug.rb +0 -145
- data/lib/pindo/command/deploy/resign.rb +0 -300
- data/lib/pindo/command/deploy/tag.rb +0 -108
- data/lib/pindo/command/deploy/uploadipa.rb +0 -73
- data/lib/pindo/command/deploy.rb +0 -42
- data/lib/pindo/command/dev/autobuild.rb +0 -117
- data/lib/pindo/command/dev/build.rb +0 -94
- data/lib/pindo/command/dev/debug.rb +0 -112
- data/lib/pindo/module/task/model/build/android_release_build_task.rb +0 -29
- data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +0 -53
- data/lib/pindo/module/task/model/build/ios_release_build_task.rb +0 -53
- data/lib/pindo/options/appconfigoptions.rb +0 -24
- data/lib/pindo/options/deployoptions.rb +0 -372
|
@@ -97,6 +97,9 @@ module Pindo
|
|
|
97
97
|
puts "⚠ Keystore 签名配置跳过(使用工程原有配置)"
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
# 处理 Play Asset Delivery 配置(如果存在)
|
|
101
|
+
setup_play_asset_delivery(project_dir)
|
|
102
|
+
|
|
100
103
|
# 构建 APK
|
|
101
104
|
build_apk(project_dir, debug)
|
|
102
105
|
end
|
|
@@ -298,6 +301,113 @@ module Pindo
|
|
|
298
301
|
end
|
|
299
302
|
end
|
|
300
303
|
|
|
304
|
+
# 设置 Play Asset Delivery:直接扫描导出工程中的资源目录,按照 Android 原生方式创建 .androidpack 目录
|
|
305
|
+
def setup_play_asset_delivery(project_dir)
|
|
306
|
+
# 获取 unityLibrary 路径
|
|
307
|
+
unity_library_path = File.join(project_dir, "unityLibrary", "src", "main")
|
|
308
|
+
unless File.directory?(unity_library_path)
|
|
309
|
+
puts "警告:Unity Library 目录不存在: #{unity_library_path}"
|
|
310
|
+
return
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# 扫描 assets 目录下的资源(Unity 构建时会将 StreamingAssets 复制到这里)
|
|
314
|
+
assets_path = File.join(unity_library_path, "assets")
|
|
315
|
+
unless File.directory?(assets_path)
|
|
316
|
+
puts "未找到 assets 目录,跳过 Play Asset Delivery 设置"
|
|
317
|
+
return
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# 扫描 assets 目录下的所有一级子目录
|
|
321
|
+
# 这些目录对应 StreamingAssets/{DefaultYooFolderName} 下的资源包
|
|
322
|
+
asset_subdirs = Dir.glob(File.join(assets_path, "*")).select { |path| File.directory?(path) }
|
|
323
|
+
|
|
324
|
+
if asset_subdirs.empty?
|
|
325
|
+
puts "未找到 assets 下的子目录,跳过 Play Asset Delivery 设置"
|
|
326
|
+
return
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
puts "检测到 #{asset_subdirs.length} 个 assets 子目录,开始设置 Play Asset Delivery..."
|
|
330
|
+
|
|
331
|
+
begin
|
|
332
|
+
# 收集所有创建的 asset pack 模块名
|
|
333
|
+
created_pack_modules = []
|
|
334
|
+
|
|
335
|
+
# 扫描每个子目录,为每个子目录创建一个 asset pack 模块
|
|
336
|
+
asset_subdirs.each do |subdir|
|
|
337
|
+
original_pack_name = File.basename(subdir)
|
|
338
|
+
if original_pack_name.downcase == 'bin'
|
|
339
|
+
puts "跳过 bin 目录,保持在 base 模块中"
|
|
340
|
+
next
|
|
341
|
+
end
|
|
342
|
+
sanitized_pack_name = sanitize_pack_name(original_pack_name)
|
|
343
|
+
module_name = "#{sanitized_pack_name}_pack"
|
|
344
|
+
|
|
345
|
+
# 检查目录是否为空
|
|
346
|
+
if Dir.glob(File.join(subdir, "*")).empty?
|
|
347
|
+
puts "警告:跳过空的 Asset Pack 目录: #{subdir}"
|
|
348
|
+
next
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# 创建模块目录(在项目顶级目录,与 launcher、unityLibrary 同级)
|
|
352
|
+
android_pack_dir = File.join(project_dir, module_name)
|
|
353
|
+
FileUtils.rm_rf(android_pack_dir) if File.directory?(android_pack_dir)
|
|
354
|
+
FileUtils.mkdir_p(android_pack_dir)
|
|
355
|
+
|
|
356
|
+
# 在 asset pack 模块中创建 src/main/assets 目录
|
|
357
|
+
module_assets_dir = File.join(android_pack_dir, "src", "main", "assets")
|
|
358
|
+
FileUtils.mkdir_p(module_assets_dir)
|
|
359
|
+
|
|
360
|
+
# 复制整个子目录到模块的 assets 下,保留原始目录名
|
|
361
|
+
FileUtils.cp_r(subdir, module_assets_dir)
|
|
362
|
+
|
|
363
|
+
# 从 assets 目录中删除资源,避免被打包到 base 模块
|
|
364
|
+
puts " 从 assets 目录移除资源 #{subdir},避免重复打包到 base 模块..."
|
|
365
|
+
FileUtils.rm_rf(subdir)
|
|
366
|
+
|
|
367
|
+
# 创建 build.gradle 文件(默认使用 install-time delivery mode)
|
|
368
|
+
build_gradle_content = <<~GRADLE
|
|
369
|
+
plugins {
|
|
370
|
+
id 'com.android.asset-pack'
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
assetPack {
|
|
374
|
+
packName = "#{module_name}"
|
|
375
|
+
dynamicDelivery {
|
|
376
|
+
deliveryType = "install-time"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
GRADLE
|
|
380
|
+
|
|
381
|
+
build_gradle_path = File.join(android_pack_dir, "build.gradle")
|
|
382
|
+
File.write(build_gradle_path, build_gradle_content)
|
|
383
|
+
|
|
384
|
+
# 记录模块名(项目顶级目录下的简单模块名)
|
|
385
|
+
created_pack_modules << ":#{module_name}"
|
|
386
|
+
|
|
387
|
+
puts "✓ 已创建 Asset Pack: #{module_name} -> #{android_pack_dir}"
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# 更新 settings.gradle 文件,注册 asset pack 模块
|
|
391
|
+
if created_pack_modules.any?
|
|
392
|
+
GradleHelper.update_settings_gradle(project_dir, created_pack_modules)
|
|
393
|
+
# 更新 launcher/build.gradle 文件,添加 assetPacks 配置
|
|
394
|
+
GradleHelper.update_launcher_build_gradle(project_dir, created_pack_modules)
|
|
395
|
+
puts "✓ Play Asset Delivery 设置完成,共创建 #{created_pack_modules.length} 个 Asset Pack"
|
|
396
|
+
else
|
|
397
|
+
puts "未找到有效的 Asset Pack 目录"
|
|
398
|
+
end
|
|
399
|
+
rescue => e
|
|
400
|
+
puts "警告:设置 Play Asset Delivery 失败: #{e.message}"
|
|
401
|
+
puts e.backtrace.first(5).join("\n")
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def sanitize_pack_name(name)
|
|
406
|
+
sanitized = name.to_s.gsub(/[^A-Za-z0-9_]/, '_')
|
|
407
|
+
sanitized = "p_#{sanitized}" unless sanitized.match?(/^[A-Za-z]/)
|
|
408
|
+
sanitized = sanitized.gsub(/__+/, '_')
|
|
409
|
+
sanitized.empty? ? "pack" : sanitized
|
|
410
|
+
end
|
|
301
411
|
|
|
302
412
|
end
|
|
303
413
|
end
|
|
@@ -924,13 +924,15 @@ module Pindo
|
|
|
924
924
|
puts "\n检测到项目 Icon URL: #{icon_url}"
|
|
925
925
|
|
|
926
926
|
# 创建临时目录(所有 icon 处理都在此目录进行)
|
|
927
|
-
temp_icon_dir = File.join(project_dir, ".
|
|
927
|
+
temp_icon_dir = File.join(project_dir, ".pindo_temp_android_icon")
|
|
928
928
|
icon_download_path = nil
|
|
929
929
|
replace_success = false
|
|
930
930
|
|
|
931
931
|
begin
|
|
932
|
-
|
|
933
|
-
|
|
932
|
+
# 先清理旧的临时目录,确保干净的环境
|
|
933
|
+
FileUtils.rm_rf(temp_icon_dir) if File.exist?(temp_icon_dir)
|
|
934
|
+
FileUtils.mkdir_p(temp_icon_dir)
|
|
935
|
+
icon_download_path = File.join(temp_icon_dir, "android_downloaded_icon.png")
|
|
934
936
|
|
|
935
937
|
# 使用带重试机制的下载
|
|
936
938
|
unless IconDownloader.download_icon_with_retry(icon_url: icon_url, save_path: icon_download_path, max_retries: 3)
|
|
@@ -938,8 +940,10 @@ module Pindo
|
|
|
938
940
|
return false
|
|
939
941
|
end
|
|
940
942
|
|
|
941
|
-
# 生成 icon
|
|
942
|
-
new_icon_dir = File.join(temp_icon_dir, "
|
|
943
|
+
# 生成 icon 目录(在临时目录内部),先清理确保干净环境
|
|
944
|
+
new_icon_dir = File.join(temp_icon_dir, "android_generated_icons")
|
|
945
|
+
FileUtils.rm_rf(new_icon_dir) if File.exist?(new_icon_dir)
|
|
946
|
+
FileUtils.mkdir_p(new_icon_dir)
|
|
943
947
|
|
|
944
948
|
# 创建各种密度的 icon
|
|
945
949
|
Funlog.instance.fancyinfo_start("正在创建 Android icon...")
|
|
@@ -559,7 +559,95 @@ module Pindo
|
|
|
559
559
|
end
|
|
560
560
|
rescue => e
|
|
561
561
|
false
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
# =================== Play Asset Delivery 相关方法 ===================
|
|
567
|
+
|
|
568
|
+
# 更新 settings.gradle 文件,注册 asset pack 模块
|
|
569
|
+
def self.update_settings_gradle(project_dir, pack_modules)
|
|
570
|
+
settings_gradle_path = File.join(project_dir, "settings.gradle")
|
|
571
|
+
settings_gradle_kts_path = File.join(project_dir, "settings.gradle.kts")
|
|
572
|
+
|
|
573
|
+
# 优先使用 settings.gradle.kts,否则使用 settings.gradle
|
|
574
|
+
settings_file = File.exist?(settings_gradle_kts_path) ? settings_gradle_kts_path : settings_gradle_path
|
|
575
|
+
|
|
576
|
+
unless File.exist?(settings_file)
|
|
577
|
+
puts "警告:未找到 settings.gradle 或 settings.gradle.kts 文件"
|
|
578
|
+
return
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
content = File.read(settings_file)
|
|
582
|
+
original_content = content.dup
|
|
583
|
+
|
|
584
|
+
# 模块名已经是正确的格式(如 :FGUI.androidpack)
|
|
585
|
+
pack_module_names = pack_modules
|
|
586
|
+
|
|
587
|
+
# 移除已存在的 asset pack 模块引用(避免重复)
|
|
588
|
+
pack_module_names.each do |module_name|
|
|
589
|
+
# 移除可能存在的旧引用
|
|
590
|
+
content.gsub!(/^\s*include\s+['"]#{Regexp.escape(module_name)}['"]\s*$/, '')
|
|
591
|
+
content.gsub!(/,\s*['"]#{Regexp.escape(module_name)}['"]/, '')
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# 查找 include 语句的位置
|
|
595
|
+
include_pattern = /include\s+(['"]:launcher['"],\s*['"]:unityLibrary['"])/
|
|
596
|
+
if content.match(include_pattern)
|
|
597
|
+
# 在现有的 include 语句中添加 asset pack 模块
|
|
598
|
+
pack_includes = pack_module_names.map { |m| "'#{m}'" }.join(', ')
|
|
599
|
+
content.gsub!(include_pattern, "include \\1, #{pack_includes}")
|
|
600
|
+
else
|
|
601
|
+
# 如果没有找到标准格式,尝试在文件末尾添加
|
|
602
|
+
pack_includes = pack_module_names.map { |m| "'#{m}'" }.join(', ')
|
|
603
|
+
content += "\ninclude #{pack_includes}\n" unless content.include?(pack_includes)
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
# 只有当内容发生变化时才写入
|
|
607
|
+
if content != original_content
|
|
608
|
+
File.write(settings_file, content)
|
|
609
|
+
puts "✓ 已更新 #{File.basename(settings_file)},注册 #{pack_modules.length} 个 Asset Pack 模块"
|
|
610
|
+
puts " 模块: #{pack_module_names.join(', ')}"
|
|
611
|
+
else
|
|
612
|
+
puts "✓ #{File.basename(settings_file)} 已包含 Asset Pack 模块引用"
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
# 更新 launcher/build.gradle 文件,添加 assetPacks 配置
|
|
617
|
+
def self.update_launcher_build_gradle(project_dir, pack_modules)
|
|
618
|
+
launcher_build_gradle_path = File.join(project_dir, "launcher", "build.gradle")
|
|
619
|
+
unless File.exist?(launcher_build_gradle_path)
|
|
620
|
+
puts "警告:未找到 launcher/build.gradle 文件"
|
|
621
|
+
return
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
content = File.read(launcher_build_gradle_path)
|
|
625
|
+
original_content = content.dup
|
|
626
|
+
|
|
627
|
+
# 检查是否已有 assetPacks 配置
|
|
628
|
+
if content.match(/assetPacks\s*=\s*\[/)
|
|
629
|
+
# 更新现有的 assetPacks 配置
|
|
630
|
+
content.gsub!(/assetPacks\s*=\s*\[[^\]]*\]/, "assetPacks = #{pack_modules.inspect}")
|
|
631
|
+
else
|
|
632
|
+
# 在 android 块中添加 assetPacks 配置
|
|
633
|
+
android_block_pattern = /(android\s*\{)/
|
|
634
|
+
if content.match(android_block_pattern)
|
|
635
|
+
# 在 android { 后添加 assetPacks 配置
|
|
636
|
+
content.gsub!(android_block_pattern, "\\1\n assetPacks = #{pack_modules.inspect}")
|
|
637
|
+
else
|
|
638
|
+
puts "警告:未找到 android 块,无法添加 assetPacks 配置"
|
|
639
|
+
return
|
|
562
640
|
end
|
|
563
641
|
end
|
|
642
|
+
|
|
643
|
+
# 只有当内容发生变化时才写入
|
|
644
|
+
if content != original_content
|
|
645
|
+
File.write(launcher_build_gradle_path, content)
|
|
646
|
+
puts "✓ 已更新 launcher/build.gradle,添加 assetPacks 配置"
|
|
647
|
+
else
|
|
648
|
+
puts "✓ launcher/build.gradle 已包含 assetPacks 配置"
|
|
649
|
+
end
|
|
650
|
+
end
|
|
651
|
+
|
|
564
652
|
end
|
|
565
653
|
end
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
require 'spaceship'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
module Pindo
|
|
5
|
+
# Bundle ID 管理辅助类
|
|
6
|
+
# 负责在 Apple 开发者中心创建和配置 Bundle ID
|
|
7
|
+
class BundleIdHelper
|
|
8
|
+
|
|
9
|
+
# 从配置文件中提取所有必要的信息
|
|
10
|
+
# @param config_json [Hash] 配置 JSON 对象
|
|
11
|
+
# @return [Hash] 提取的配置信息
|
|
12
|
+
def self.extract_config_info(config_json)
|
|
13
|
+
config_info = {}
|
|
14
|
+
|
|
15
|
+
# 提取 Apple ID
|
|
16
|
+
if config_json['account_info'] && config_json['account_info']['apple_acount_id']
|
|
17
|
+
config_info[:apple_id] = config_json['account_info']['apple_acount_id']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# 提取 Bundle ID 信息
|
|
21
|
+
if config_json['app_info']
|
|
22
|
+
app_info = config_json['app_info']
|
|
23
|
+
config_info[:bundle_id] = app_info['app_identifier']
|
|
24
|
+
config_info[:bundle_id_pushcontent] = app_info['app_identifier_pushcontent']
|
|
25
|
+
config_info[:bundle_id_pushservice] = app_info['app_identifier_pushservice']
|
|
26
|
+
config_info[:bundle_id_keyboard] = app_info['app_identifier_keyboard']
|
|
27
|
+
config_info[:bundle_id_imessage] = app_info['app_identifier_imessage']
|
|
28
|
+
config_info[:bundle_id_extension] = app_info['app_identifier_extension']
|
|
29
|
+
config_info[:bundle_id_siri] = app_info['app_identifier_siri']
|
|
30
|
+
config_info[:bundle_id_siriui] = app_info['app_identifier_siriui']
|
|
31
|
+
config_info[:bundle_id_widget] = app_info['app_identifier_widget']
|
|
32
|
+
config_info[:bundle_id_extensionad] = app_info['app_identifier_extensionad']
|
|
33
|
+
config_info[:bundle_id_watchapp] = app_info['app_identifier_watchapp']
|
|
34
|
+
config_info[:bundle_id_watchapp_extension] = app_info['app_identifier_watchapp_extension']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# 提取 App Group 和 iCloud ID
|
|
38
|
+
if config_json['app_setting']
|
|
39
|
+
app_setting = config_json['app_setting']
|
|
40
|
+
config_info[:group_id] = app_setting['app_group_id']
|
|
41
|
+
config_info[:icloud_id] = app_setting['app_icloud_id']
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
config_info
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# 执行 Bundle ID 创建流程
|
|
48
|
+
# @param config_json [Hash] 配置 JSON 对象
|
|
49
|
+
# @param sign_flag [Boolean] 签名标志
|
|
50
|
+
def self.execute_bundleid_creation(config_json:, sign_flag: false)
|
|
51
|
+
# 提取配置信息
|
|
52
|
+
config_info = extract_config_info(config_json)
|
|
53
|
+
|
|
54
|
+
# 验证必需字段
|
|
55
|
+
raise "配置文件中缺少 Apple ID" if config_info[:apple_id].nil? || config_info[:apple_id].empty?
|
|
56
|
+
raise "配置文件中缺少 Bundle ID" if config_info[:bundle_id].nil? || config_info[:bundle_id].empty?
|
|
57
|
+
|
|
58
|
+
# 登录 Apple 开发者中心
|
|
59
|
+
puts config_info[:apple_id]
|
|
60
|
+
puts "Login #{config_info[:apple_id]}..."
|
|
61
|
+
Spaceship.login(config_info[:apple_id].to_s)
|
|
62
|
+
Spaceship.select_team
|
|
63
|
+
|
|
64
|
+
# 创建 App Group
|
|
65
|
+
app_group = nil
|
|
66
|
+
if !config_info[:group_id].nil?
|
|
67
|
+
app_group = create_group_id(group_id: config_info[:group_id])
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# 配置参数
|
|
71
|
+
parms = ["push_notification", "app_group"]
|
|
72
|
+
|
|
73
|
+
# 创建 iCloud ID
|
|
74
|
+
app_icloud = nil
|
|
75
|
+
if !config_info[:icloud_id].nil?
|
|
76
|
+
app_icloud = create_icloud_id(icloud_id: config_info[:icloud_id])
|
|
77
|
+
parms << "iclound"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# 创建主应用 Bundle ID
|
|
81
|
+
app = create_bundleid(
|
|
82
|
+
bundle_id: config_info[:bundle_id],
|
|
83
|
+
app_group: app_group,
|
|
84
|
+
app_icloud: app_icloud,
|
|
85
|
+
setting_array: parms
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# 创建各种扩展的 Bundle ID
|
|
89
|
+
create_extension_bundleids(app, app_group, app_icloud, config_info)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# 创建 Bundle ID
|
|
93
|
+
# @param bundle_id [String] Bundle ID
|
|
94
|
+
# @param app_group [Object] App Group 对象
|
|
95
|
+
# @param app_icloud [Object] iCloud Container 对象
|
|
96
|
+
# @param setting_array [Array] 配置数组
|
|
97
|
+
# @return [Object] 创建的 App 对象
|
|
98
|
+
def self.create_bundleid(bundle_id:, app_group: nil, app_icloud: nil, setting_array: [])
|
|
99
|
+
return nil if bundle_id.nil?
|
|
100
|
+
|
|
101
|
+
# 查找或创建 Bundle ID
|
|
102
|
+
app = Spaceship::Portal.app.find(bundle_id)
|
|
103
|
+
puts
|
|
104
|
+
|
|
105
|
+
if app.nil?
|
|
106
|
+
puts "Create bundle id #{bundle_id} in apple developer center..."
|
|
107
|
+
app = Spaceship::Portal.app.create!(bundle_id: bundle_id, name: bundle_id.gsub('.', ''))
|
|
108
|
+
else
|
|
109
|
+
puts "Find bundle id #{bundle_id} in apple developer center..."
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
bundle_id_obj = Spaceship::ConnectAPI::BundleId.find(bundle_id)
|
|
113
|
+
|
|
114
|
+
# 配置 Game Center
|
|
115
|
+
if !bundle_id_obj.nil?
|
|
116
|
+
if !setting_array.nil? && setting_array.to_s.include?("game_center")
|
|
117
|
+
puts "Enable #{bundle_id} game_center on"
|
|
118
|
+
bundle_id_obj.update_capability("GAME_CENTER", enabled: true)
|
|
119
|
+
else
|
|
120
|
+
puts "Enable #{bundle_id} game_center off"
|
|
121
|
+
bundle_id_obj.update_capability("GAME_CENTER", enabled: false)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
return nil if setting_array.nil? || setting_array.length == 0
|
|
126
|
+
|
|
127
|
+
# 配置 Push Notification
|
|
128
|
+
if !app.nil? && setting_array.to_s.include?("push_notification")
|
|
129
|
+
puts "Enable #{bundle_id} push on"
|
|
130
|
+
app.update_service(Spaceship::Portal.app_service.push_notification.on)
|
|
131
|
+
else
|
|
132
|
+
app.update_service(Spaceship::Portal.app_service.push_notification.off)
|
|
133
|
+
puts "Enable #{bundle_id} push off"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# 配置 Siri
|
|
137
|
+
if !app.nil? && setting_array.to_s.include?("siri")
|
|
138
|
+
puts "Enable #{bundle_id} siri on"
|
|
139
|
+
app.update_service(Spaceship::Portal.app_service.siri_kit.on)
|
|
140
|
+
else
|
|
141
|
+
app.update_service(Spaceship::Portal.app_service.siri_kit.off)
|
|
142
|
+
puts "Enable #{bundle_id} siri off"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# 配置 Sign with Apple
|
|
146
|
+
if !bundle_id_obj.nil? && setting_array.to_s.include?("apple_signin")
|
|
147
|
+
puts "Enable #{bundle_id} Sign with Apple on"
|
|
148
|
+
settings = build_settings_for(settings_key: "APPLE_ID_AUTH_APP_CONSENT", options_key: "PRIMARY_APP_CONSENT")
|
|
149
|
+
bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: true, settings: settings)
|
|
150
|
+
else
|
|
151
|
+
puts "Enable #{bundle_id} Sign with Apple off"
|
|
152
|
+
bundle_id_obj.update_capability("APPLE_ID_AUTH", enabled: false)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# 配置 App Group
|
|
156
|
+
if !app_group.nil? && setting_array.to_s.include?("app_group")
|
|
157
|
+
puts "Enable #{bundle_id} group on"
|
|
158
|
+
app.update_service(Spaceship::Portal.app_service.app_group.on)
|
|
159
|
+
app.associate_groups([app_group])
|
|
160
|
+
else
|
|
161
|
+
puts "Enable #{bundle_id} group off"
|
|
162
|
+
app.update_service(Spaceship::Portal.app_service.app_group.off)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# 配置 iCloud
|
|
166
|
+
if !app_icloud.nil? && setting_array.to_s.include?("iclound")
|
|
167
|
+
puts "Enable #{bundle_id} icloud on"
|
|
168
|
+
app.update_service(Spaceship::Portal.app_service.cloud.on)
|
|
169
|
+
app.update_service(Spaceship::Portal.app_service.cloud_kit.cloud_kit)
|
|
170
|
+
app.associate_cloud_containers([app_icloud])
|
|
171
|
+
else
|
|
172
|
+
puts "Enable #{bundle_id} icloud off"
|
|
173
|
+
app.update_service(Spaceship::Portal.app_service.cloud.off)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
app
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# 创建 App Group
|
|
180
|
+
# @param group_id [String] Group ID
|
|
181
|
+
# @return [Object] App Group 对象
|
|
182
|
+
def self.create_group_id(group_id:)
|
|
183
|
+
return nil if group_id.nil?
|
|
184
|
+
|
|
185
|
+
app_group = Spaceship::Portal.app_group.find(group_id)
|
|
186
|
+
|
|
187
|
+
if app_group.nil?
|
|
188
|
+
puts "Create group_id #{group_id} in apple developer center..."
|
|
189
|
+
app_group = Spaceship::Portal.app_group.create!(group_id: group_id, name: group_id.gsub('.', ''))
|
|
190
|
+
else
|
|
191
|
+
puts "Group_id #{group_id} is existed in apple developer center !!!"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
app_group
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# 创建 iCloud Container
|
|
198
|
+
# @param icloud_id [String] iCloud ID
|
|
199
|
+
# @return [Object] iCloud Container 对象
|
|
200
|
+
def self.create_icloud_id(icloud_id:)
|
|
201
|
+
return nil if icloud_id.nil?
|
|
202
|
+
|
|
203
|
+
puts "icloud_id +++++ #{icloud_id}"
|
|
204
|
+
app_icloud = Spaceship::Portal.cloud_container.find(icloud_id)
|
|
205
|
+
|
|
206
|
+
if app_icloud.nil?
|
|
207
|
+
puts "Create icloud_id #{icloud_id} in apple developer center..."
|
|
208
|
+
app_icloud = Spaceship::Portal.cloud_container.create!(identifier: icloud_id, name: icloud_id.gsub('.', ''))
|
|
209
|
+
else
|
|
210
|
+
puts "icloud_id #{icloud_id} is existed in apple developer center !!!"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
app_icloud
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# 构建设置
|
|
217
|
+
# @param settings_key [String] 设置键
|
|
218
|
+
# @param options_key [String] 选项键
|
|
219
|
+
# @return [Array] 设置数组
|
|
220
|
+
def self.build_settings_for(settings_key:, options_key:)
|
|
221
|
+
[{
|
|
222
|
+
key: settings_key,
|
|
223
|
+
options: [{
|
|
224
|
+
key: options_key
|
|
225
|
+
}]
|
|
226
|
+
}]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# 创建扩展的 Bundle ID
|
|
230
|
+
# @param app [Object] 主应用对象
|
|
231
|
+
# @param app_group [Object] App Group 对象
|
|
232
|
+
# @param app_icloud [Object] iCloud Container 对象
|
|
233
|
+
# @param config_info [Hash] 配置信息
|
|
234
|
+
def self.create_extension_bundleids(app, app_group, app_icloud, config_info)
|
|
235
|
+
return if app.nil?
|
|
236
|
+
|
|
237
|
+
# Push Content Extension
|
|
238
|
+
if !config_info[:bundle_id_pushcontent].nil?
|
|
239
|
+
create_bundleid(
|
|
240
|
+
bundle_id: config_info[:bundle_id_pushcontent],
|
|
241
|
+
app_group: app_group,
|
|
242
|
+
app_icloud: app_icloud,
|
|
243
|
+
setting_array: ["push_notification"]
|
|
244
|
+
)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Push Service Extension
|
|
248
|
+
if !config_info[:bundle_id_pushservice].nil?
|
|
249
|
+
create_bundleid(
|
|
250
|
+
bundle_id: config_info[:bundle_id_pushservice],
|
|
251
|
+
app_group: app_group,
|
|
252
|
+
app_icloud: app_icloud,
|
|
253
|
+
setting_array: ["push_notification"]
|
|
254
|
+
)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Keyboard Extension
|
|
258
|
+
if !config_info[:bundle_id_keyboard].nil?
|
|
259
|
+
create_bundleid(
|
|
260
|
+
bundle_id: config_info[:bundle_id_keyboard],
|
|
261
|
+
app_group: app_group,
|
|
262
|
+
app_icloud: app_icloud,
|
|
263
|
+
setting_array: ["app_group"]
|
|
264
|
+
)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# iMessage Extension
|
|
268
|
+
if !config_info[:bundle_id_imessage].nil?
|
|
269
|
+
create_bundleid(
|
|
270
|
+
bundle_id: config_info[:bundle_id_imessage],
|
|
271
|
+
app_group: app_group,
|
|
272
|
+
app_icloud: app_icloud,
|
|
273
|
+
setting_array: ["app_group"]
|
|
274
|
+
)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Siri Extension
|
|
278
|
+
if !config_info[:bundle_id_siri].nil?
|
|
279
|
+
create_bundleid(
|
|
280
|
+
bundle_id: config_info[:bundle_id_siri],
|
|
281
|
+
app_group: app_group,
|
|
282
|
+
app_icloud: app_icloud,
|
|
283
|
+
setting_array: ["app_group", "siri"]
|
|
284
|
+
)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Siri UI Extension
|
|
288
|
+
if !config_info[:bundle_id_siriui].nil?
|
|
289
|
+
create_bundleid(
|
|
290
|
+
bundle_id: config_info[:bundle_id_siriui],
|
|
291
|
+
app_group: app_group,
|
|
292
|
+
app_icloud: app_icloud,
|
|
293
|
+
setting_array: ["app_group", "siri"]
|
|
294
|
+
)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Widget Extension
|
|
298
|
+
if !config_info[:bundle_id_widget].nil?
|
|
299
|
+
create_bundleid(
|
|
300
|
+
bundle_id: config_info[:bundle_id_widget],
|
|
301
|
+
app_group: app_group,
|
|
302
|
+
app_icloud: app_icloud,
|
|
303
|
+
setting_array: ["app_group"]
|
|
304
|
+
)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# General Extension
|
|
308
|
+
if !config_info[:bundle_id_extension].nil?
|
|
309
|
+
create_bundleid(
|
|
310
|
+
bundle_id: config_info[:bundle_id_extension],
|
|
311
|
+
app_group: app_group,
|
|
312
|
+
app_icloud: app_icloud,
|
|
313
|
+
setting_array: ["app_group"]
|
|
314
|
+
)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Ad Extension
|
|
318
|
+
if !config_info[:bundle_id_extensionad].nil?
|
|
319
|
+
create_bundleid(
|
|
320
|
+
bundle_id: config_info[:bundle_id_extensionad],
|
|
321
|
+
app_group: app_group,
|
|
322
|
+
app_icloud: app_icloud,
|
|
323
|
+
setting_array: ["app_group"]
|
|
324
|
+
)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Watch App
|
|
328
|
+
if !config_info[:bundle_id_watchapp].nil?
|
|
329
|
+
create_bundleid(
|
|
330
|
+
bundle_id: config_info[:bundle_id_watchapp],
|
|
331
|
+
app_group: nil,
|
|
332
|
+
app_icloud: app_icloud,
|
|
333
|
+
setting_array: ["push_notification"]
|
|
334
|
+
)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Watch App Extension
|
|
338
|
+
if !config_info[:bundle_id_watchapp_extension].nil?
|
|
339
|
+
create_bundleid(
|
|
340
|
+
bundle_id: config_info[:bundle_id_watchapp_extension],
|
|
341
|
+
app_group: nil,
|
|
342
|
+
app_icloud: app_icloud,
|
|
343
|
+
setting_array: ["push_notification"]
|
|
344
|
+
)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
end
|
|
349
|
+
end
|