pindo 5.17.5 → 5.18.4

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/git_handler.rb +120 -38
  3. data/lib/pindo/command/android/autobuild.rb +81 -40
  4. data/lib/pindo/command/appstore/adhocbuild.rb +1 -1
  5. data/lib/pindo/command/appstore/autobuild.rb +1 -1
  6. data/lib/pindo/command/appstore/autoresign.rb +1 -1
  7. data/lib/pindo/command/appstore/updateid.rb +229 -0
  8. data/lib/pindo/command/appstore.rb +1 -0
  9. data/lib/pindo/command/ios/autobuild.rb +70 -33
  10. data/lib/pindo/command/ios/podpush.rb +1 -1
  11. data/lib/pindo/command/jps/apptest.rb +2 -2
  12. data/lib/pindo/command/jps/bind.rb +1 -1
  13. data/lib/pindo/command/jps/media.rb +1 -1
  14. data/lib/pindo/command/jps/upload.rb +52 -22
  15. data/lib/pindo/command/unity/autobuild.rb +61 -44
  16. data/lib/pindo/command/utils/allcopyconfig.rb +144 -0
  17. data/lib/pindo/command/utils/copyconfig.rb +207 -0
  18. data/lib/pindo/command/utils/icon.rb +2 -2
  19. data/lib/pindo/command/utils/renewbundleid.rb +199 -0
  20. data/lib/pindo/command/utils/renewcert.rb +56 -54
  21. data/lib/pindo/command/utils.rb +3 -0
  22. data/lib/pindo/command/web/autobuild.rb +32 -26
  23. data/lib/pindo/config/build_info_manager.rb +1 -3
  24. data/lib/pindo/module/android/android_build_helper.rb +193 -33
  25. data/lib/pindo/module/android/android_config_helper.rb +305 -88
  26. data/lib/pindo/module/android/android_project_helper.rb +69 -14
  27. data/lib/pindo/module/android/android_res_helper.rb +349 -51
  28. data/lib/pindo/module/android/keystore_helper.rb +611 -295
  29. data/lib/pindo/module/android/workflow_gradle_injector.rb +702 -0
  30. data/lib/pindo/module/appselect.rb +4 -4
  31. data/lib/pindo/module/appstore/bundleid_helper.rb +204 -14
  32. data/lib/pindo/module/build/build_helper.rb +110 -10
  33. data/lib/pindo/module/build/git_repo_helper.rb +4 -4
  34. data/lib/pindo/module/cert/mode/base_cert_operator.rb +8 -6
  35. data/lib/pindo/module/pgyer/pgyerhelper.rb +105 -42
  36. data/lib/pindo/module/task/core/task_executor.rb +2 -0
  37. data/lib/pindo/module/task/model/build/android_build_dev_task.rb +64 -6
  38. data/lib/pindo/module/task/model/git/git_commit_task.rb +70 -54
  39. data/lib/pindo/module/task/model/git/git_tag_task.rb +13 -9
  40. data/lib/pindo/module/task/model/jps/jps_upload_task.rb +104 -1
  41. data/lib/pindo/module/task/model/unity/unity_export_task.rb +2 -1
  42. data/lib/pindo/module/task/model/unity/unity_update_task.rb +2 -1
  43. data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +2 -1
  44. data/lib/pindo/module/task/model/unity_task.rb +2 -1
  45. data/lib/pindo/module/task/task_manager.rb +8 -0
  46. data/lib/pindo/module/unity/unity_helper.rb +13 -10
  47. data/lib/pindo/module/unity/unity_proc_helper.rb +27 -2
  48. data/lib/pindo/module/xcode/applovin_xcode_helper.rb +4 -2
  49. data/lib/pindo/module/xcode/res/xcode_res_constant.rb +72 -0
  50. data/lib/pindo/module/xcode/xcode_build_config.rb +36 -17
  51. data/lib/pindo/module/xcode/xcode_build_helper.rb +180 -23
  52. data/lib/pindo/module/xcode/xcode_project_helper.rb +1 -1
  53. data/lib/pindo/module/xcode/xcode_res_helper.rb +32 -16
  54. data/lib/pindo/options/groups/build_options.rb +16 -5
  55. data/lib/pindo/options/groups/git_options.rb +7 -5
  56. data/lib/pindo/options/groups/unity_options.rb +11 -0
  57. data/lib/pindo/options/helpers/bundleid_selector.rb +25 -0
  58. data/lib/pindo/options/helpers/git_constants.rb +7 -6
  59. data/lib/pindo/version.rb +2 -2
  60. metadata +10 -5
@@ -74,7 +74,7 @@ module Pindo
74
74
 
75
75
  $ pindo unity autobuild --bundleid=com.example.app # 指定 Bundle ID (iOS)
76
76
 
77
- $ pindo unity autobuild --bundle_name=com.example.app # 指定 Bundle Name (Android)
77
+ $ pindo unity autobuild --bundle_name=com.example.* # 指定 Bundle Name (Android,支持通配符)
78
78
 
79
79
  $ pindo unity autobuild --proj="My App" # 指定项目名称
80
80
 
@@ -89,6 +89,8 @@ module Pindo
89
89
  $ pindo unity autobuild --send # 编译、打tag、上传、发上传消息、上传媒体附件、绑定包到工作流 + 发送群消息
90
90
 
91
91
  $ pindo unity autobuild --multi # 使用并发模式执行
92
+
93
+ $ pindo unity autobuild --kill-unity # 自动关闭 Unity 进程(不询问确认)
92
94
  DESC
93
95
 
94
96
  # 命令参数
@@ -99,9 +101,9 @@ module Pindo
99
101
  # 定义此命令使用的参数项
100
102
  def self.option_items
101
103
  @option_items ||= Pindo::Options::OptionGroup.merge(
102
- Pindo::Options::BuildOptions.select(:bundleid, :bundle_name), # 添加 bundleid 和 bundle_name 参数
104
+ Pindo::Options::BuildOptions.select(:bundleid, :bundle_name, :types),
103
105
  Pindo::Options::JPSOptions.select(:conf, :upload, :send, :media, :bind),
104
- Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
106
+ Pindo::Options::UnityOptions.select(:skiplib, :skipyoo, :kill_unity),
105
107
  Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
106
108
  Pindo::Options::TaskOptions.select(:multi),
107
109
  Pindo::Options::GitOptions.all
@@ -111,7 +113,6 @@ module Pindo
111
113
  # 命令选项
112
114
  def self.options
113
115
  [
114
- ['--types=TYPES', '指定要构建的类型,逗号分隔(如:ipa,apk,html),默认全部类型'],
115
116
  ['--adhoc', '使用AdHoc证书打包iOS(默认使用Dev证书)'],
116
117
  ['--deploy', '使用发布证书打包iOS'],
117
118
  ['--release', '使用Release模式构建Android(默认使用Debug)']
@@ -128,7 +129,7 @@ module Pindo
128
129
  @args_release_flag = argv.flag?('release', false)
129
130
  @args_bundle_id = @options[:bundleid] # 从 @options 获取,确保能被缓存
130
131
  @args_bundle_name = @options[:bundle_name] # 从 @options 获取,确保能被缓存
131
- @args_types = argv.option('types')
132
+ @args_types = @options[:types]
132
133
 
133
134
  # send、media 或 bind 都依赖 upload:如果指定了任一参数,自动启用 upload
134
135
  @args_upload_flag = @options[:send] || @options[:bind] || @options[:media] || @options[:upload]
@@ -144,6 +145,7 @@ module Pindo
144
145
  # Unity 参数
145
146
  @args_skip_lib = @options[:skiplib] || false
146
147
  @args_skip_yoo = @options[:skipyoo] || false
148
+ @args_kill_unity = @options[:kill_unity] || false
147
149
 
148
150
  # Task 参数
149
151
  @args_multi_flag = @options[:multi] || false
@@ -198,35 +200,36 @@ module Pindo
198
200
  raise Informative, "当前目录不是Unity工程,请在Unity工程根目录下执行此命令"
199
201
  end
200
202
 
201
- # 1. 获取要构建的类型列表
202
- selected_platforms = get_selected_build_types()
203
+ begin
204
+ # 加载 JPS 配置(缓存 project_name,并通过映射表解析 bundle_id)
205
+ Pindo::BuildHelper.share_instance.load_jps_build_config(pindo_project_dir, conf: @args_conf)
203
206
 
204
- # 2. 按平台顺序准备所有配置(iOS → Android → Web)
205
- all_platform_configs = prepare_all_platform_configs(selected_platforms)
207
+ # 1. 获取要构建的类型列表
208
+ selected_platforms = get_selected_build_types()
206
209
 
207
- # 3. 按平台顺序创建所有任务(包含 GitTagTask
208
- all_tasks = make_task_with_config(selected_platforms, all_platform_configs)
210
+ # 2. 按平台顺序准备所有配置(iOS → Android → Web
211
+ all_platform_configs = prepare_all_platform_configs(selected_platforms)
209
212
 
210
- # 4. 统一添加到任务管理器并执行
211
- task_manager = Pindo::TaskSystem::TaskManager.instance
212
- task_manager.clear_all # 清空之前的任务
213
+ # 3. 按平台顺序创建所有任务(包含 GitTagTask)
214
+ all_tasks = make_task_with_config(selected_platforms, all_platform_configs)
213
215
 
214
- # 按顺序添加所有任务
215
- all_tasks.each do |task|
216
- task_manager.add_task(task)
217
- end
216
+ # 4. 统一添加到任务管理器并执行
217
+ task_manager = Pindo::TaskSystem::TaskManager.instance
218
+ task_manager.clear_all # 清空之前的任务
218
219
 
219
- # # 启用输出管理(自动处理多线程日志隔离)
220
- # task_manager.enable_output_management(
221
- # log_dir: File.join(pindo_project_dir, 'pindo_logs'),
222
- # max_lines_per_task: 0
223
- # )
220
+ # 按顺序添加所有任务
221
+ all_tasks.each do |task|
222
+ task_manager.add_task(task)
223
+ end
224
224
 
225
- # 执行任务(根据 --multi 参数决定模式)
226
- if @args_multi_flag
227
- task_manager.start(mode: :concurrent, max_workers: 3)
228
- else
229
- task_manager.start(mode: :serial)
225
+ # 执行任务(根据 --multi 参数决定模式)
226
+ if @args_multi_flag
227
+ task_manager.start(mode: :concurrent, max_workers: 3)
228
+ else
229
+ task_manager.start(mode: :serial)
230
+ end
231
+ ensure
232
+ Pindo::Options::GlobalOptionsState.instance.clear
230
233
  end
231
234
  end
232
235
 
@@ -264,9 +267,9 @@ module Pindo
264
267
  # 判断是否只有 web 平台(web 平台需要在导出前创建 Tag)
265
268
  only_web_platform = selected_platforms == ['web']
266
269
 
267
- # 如果只有 web 平台,在 Unity 导出之前创建 Git 标签任务
268
- # 所有参数都从 GitCommitTask 获取
269
- if only_web_platform
270
+ # 如果只有 web 平台,在 Unity 导出之前创建 Git 标签任务(skip_without_tag 模式下不创建)
271
+ git_tag_task = nil
272
+ if only_web_platform && process_type != Pindo::UncommittedFilesProcessType::SKIP_WITHOUT_TAG
270
273
  git_tag_task = Pindo::TaskSystem::GitTagTask.new(Dir.pwd)
271
274
  git_tag_task.dependencies << git_commit_task.id
272
275
  all_tasks << git_tag_task
@@ -276,7 +279,8 @@ module Pindo
276
279
  # 第一步:创建 Unity 更新任务(所有平台共享,可选)
277
280
  unless @args_skip_lib
278
281
  unity_update_task = Pindo::TaskSystem::UnityUpdateTask.new(
279
- project_path: Dir.pwd
282
+ project_path: Dir.pwd,
283
+ auto_kill: @args_kill_unity
280
284
  )
281
285
  unity_update_task.dependencies << common_dependency_task.id
282
286
  all_tasks << unity_update_task
@@ -297,7 +301,8 @@ module Pindo
297
301
  unless @args_skip_yoo
298
302
  unity_yoo_task = Pindo::TaskSystem::UnityYooAssetTask.new(
299
303
  platform,
300
- project_path: Dir.pwd
304
+ project_path: Dir.pwd,
305
+ auto_kill: @args_kill_unity
301
306
  )
302
307
  unity_yoo_task.dependencies << platform_dependency_task.id
303
308
  all_tasks << unity_yoo_task
@@ -316,10 +321,9 @@ module Pindo
316
321
  platform_build_tasks[platform] = build_task
317
322
  end
318
323
 
319
- # 第三步:创建 Git 标签任务(依赖第一个平台的构建任务)
324
+ # 第三步:创建 Git 标签任务(skip_without_tag 模式下不创建)
320
325
  # 注意:如果只有 web 平台,GitTagTask 已在前面创建,这里跳过
321
- # 所有参数都从 GitCommitTask 获取
322
- unless only_web_platform
326
+ unless only_web_platform || process_type == Pindo::UncommittedFilesProcessType::SKIP_WITHOUT_TAG
323
327
  first_build_task = platform_build_tasks[selected_platforms.first]
324
328
  if first_build_task
325
329
  git_tag_task = Pindo::TaskSystem::GitTagTask.new(Dir.pwd)
@@ -411,7 +415,7 @@ module Pindo
411
415
  )
412
416
  # 依赖 Git Commit、Git Tag 和 Bind Package 任务
413
417
  workflow_message_task.dependencies << git_commit_task.id
414
- workflow_message_task.dependencies << git_tag_task.id
418
+ workflow_message_task.dependencies << git_tag_task.id if git_tag_task
415
419
  workflow_message_task.dependencies << bind_package_task.id
416
420
  all_tasks << workflow_message_task
417
421
  end
@@ -460,7 +464,8 @@ module Pindo
460
464
  platform,
461
465
  project_path: Dir.pwd,
462
466
  export_path: export_path,
463
- context: context
467
+ context: context,
468
+ auto_kill: @args_kill_unity
464
469
  )
465
470
  end
466
471
 
@@ -584,6 +589,10 @@ module Pindo
584
589
  package_type: package_type
585
590
  )
586
591
 
592
+ # prepare_upload 可能会创建/更新 JPSBuildConfig.json(尤其是首次执行)
593
+ # 这里需要重新加载一次,以便通过映射表解析出 bundleid/bundle_name
594
+ Pindo::BuildHelper.share_instance.load_jps_build_config(Dir.pwd, conf: @args_conf)
595
+
587
596
  # 保存 app_info_obj 到共享配置(所有平台共享同一个项目)
588
597
  if configs["app_info_obj"].nil?
589
598
  configs["app_info_obj"] = app_info_obj
@@ -599,11 +608,14 @@ module Pindo
599
608
 
600
609
  case platform
601
610
  when 'ios'
602
- # 获取 iOS Bundle ID
603
- if @args_bundle_id
611
+ # 获取 iOS Bundle ID(优先级:命令行 > JPSBuildConfig映射 > 交互选择)
612
+ if @args_bundle_id && !@args_bundle_id.empty?
604
613
  platform_config["bundle_id"] = @args_bundle_id
605
614
  else
606
- if @args_deploy_flag
615
+ cached = Pindo::Options::GlobalOptionsState.instance[:bundleid]
616
+ if cached && !cached.empty?
617
+ platform_config["bundle_id"] = cached
618
+ elsif @args_deploy_flag
607
619
  platform_config["bundle_id"] = get_selected_deploy_bundleid()
608
620
  else
609
621
  platform_config["bundle_id"] = get_selected_dev_bundleid()
@@ -615,11 +627,16 @@ module Pindo
615
627
  prepare_ios_config(platform_config["bundle_id"])
616
628
 
617
629
  when 'android'
618
- # 获取 Android Package Name
619
- if @args_bundle_name
630
+ # 获取 Android Package Name(优先级:命令行 > JPSBuildConfig映射 > 交互选择)
631
+ if @args_bundle_name && !@args_bundle_name.empty?
620
632
  platform_config["bundle_name"] = @args_bundle_name
621
633
  else
622
- platform_config["bundle_name"] = get_selected_dev_bundle_name()
634
+ cached = Pindo::Options::GlobalOptionsState.instance[:bundle_name]
635
+ if cached && !cached.empty?
636
+ platform_config["bundle_name"] = cached
637
+ else
638
+ platform_config["bundle_name"] = get_selected_dev_bundle_name()
639
+ end
623
640
  end
624
641
  puts " Package Name: #{platform_config["bundle_name"]}"
625
642
 
@@ -0,0 +1,144 @@
1
+ require 'fileutils'
2
+ require 'json'
3
+
4
+ module Pindo
5
+ class Command
6
+ class Utils < Command
7
+ class Allcopyconfig < Utils
8
+
9
+ include Appselect
10
+
11
+ self.summary = '批量复制所有配置仓库到新的组织前缀'
12
+
13
+ self.description = <<-DESC
14
+ 遍历当前账号下所有Bundle ID配置仓库,
15
+ 批量执行copyconfig命令将每个仓库复制到新的组织前缀下。
16
+
17
+ 支持功能:
18
+
19
+ * 自动遍历所有dev、tool、release的bundle id
20
+
21
+ * 对每个bundle id执行copyconfig复制
22
+
23
+ * 替换组织前缀和Apple ID
24
+
25
+ * 记录并汇总失败的bundle id
26
+
27
+ 使用示例:
28
+
29
+ $ pindo utils allcopyconfig --to-prefix=com.eyesofstorms --apple-id=eyesofstorms@hotmail.com
30
+
31
+ 注意事项:
32
+
33
+ * 确保目标组织在Gitee上有创建仓库的权限
34
+
35
+ * 已存在的目标仓库会被跳过
36
+ DESC
37
+
38
+ self.arguments = []
39
+
40
+ def self.options
41
+ [
42
+ ['--to-prefix', '目标组织前缀 (如 com.eyesofstorms)'],
43
+ ['--apple-id', '新的Apple开发者账号邮箱']
44
+ ].concat(super)
45
+ end
46
+
47
+ def initialize(argv)
48
+ @to_prefix = argv.option('to-prefix')
49
+ @new_apple_id = argv.option('apple-id')
50
+ super
51
+ end
52
+
53
+ def validate!
54
+ super
55
+ help! "请通过 --to-prefix 指定目标组织前缀 (如 com.eyesofstorms)" if @to_prefix.nil? || @to_prefix.empty?
56
+ help! "请通过 --apple-id 指定新的Apple开发者账号" if @new_apple_id.nil? || @new_apple_id.empty?
57
+ end
58
+
59
+ def run
60
+ @dev_bundle_id_array = all_dev_bundleid()
61
+ @tool_bundle_id_array = all_tool_bundleid()
62
+ @deploy_bundle_id_array = all_release_bundleid()
63
+ all_bundle_ids = @dev_bundle_id_array + @deploy_bundle_id_array + @tool_bundle_id_array
64
+
65
+ puts "目标前缀: #{@to_prefix}"
66
+ puts "目标 Apple ID: #{@new_apple_id}"
67
+ puts "共 #{all_bundle_ids.length} 个 Bundle ID 需要复制"
68
+ puts
69
+
70
+ success_count = 0
71
+ skip_count = 0
72
+ failed_ids = []
73
+
74
+ all_bundle_ids.each_with_index do |from_bundle_id, index|
75
+ if from_bundle_id.include?("*")
76
+ # 通配符 bundle id: com.heroneverdie101.* -> 仓库名 com.heroneverdie101
77
+ clean_from = from_bundle_id.gsub(".*", "")
78
+ new_bundle_id = @to_prefix
79
+
80
+ puts "=" * 60
81
+ puts "[#{index + 1}/#{all_bundle_ids.length}] #{clean_from} -> #{new_bundle_id}"
82
+ puts "=" * 60
83
+
84
+ begin
85
+ args_temp = []
86
+ args_temp << new_bundle_id
87
+ args_temp << "--from=#{clean_from}"
88
+ args_temp << "--apple-id=#{@new_apple_id}"
89
+ Pindo::Command::Utils::Copyconfig.run(args_temp)
90
+ success_count += 1
91
+ rescue => err
92
+ puts " 失败: #{err.message}"
93
+ failed_ids << clean_from
94
+ end
95
+
96
+ puts
97
+ next
98
+ end
99
+
100
+ # 计算新 bundle id: 替换前缀
101
+ from_parts = from_bundle_id.split('.')
102
+ if from_parts.length < 3
103
+ puts "[#{index + 1}/#{all_bundle_ids.length}] #{from_bundle_id} — 格式不合法,跳过"
104
+ skip_count += 1
105
+ next
106
+ end
107
+
108
+ app_name_parts = from_parts[2..]
109
+ new_bundle_id = "#{@to_prefix}.#{app_name_parts.join('.')}"
110
+
111
+ puts "=" * 60
112
+ puts "[#{index + 1}/#{all_bundle_ids.length}] #{from_bundle_id} -> #{new_bundle_id}"
113
+ puts "=" * 60
114
+
115
+ begin
116
+ args_temp = []
117
+ args_temp << new_bundle_id
118
+ args_temp << "--from=#{from_bundle_id}"
119
+ args_temp << "--apple-id=#{@new_apple_id}"
120
+ Pindo::Command::Utils::Copyconfig.run(args_temp)
121
+ success_count += 1
122
+ rescue => err
123
+ puts " 失败: #{err.message}"
124
+ failed_ids << from_bundle_id
125
+ end
126
+
127
+ puts
128
+ end
129
+
130
+ # 汇总
131
+ puts "=" * 60
132
+ puts "完成: #{success_count} 成功, #{failed_ids.length} 失败, #{skip_count} 跳过"
133
+
134
+ if !failed_ids.empty?
135
+ puts
136
+ puts "失败的 Bundle ID:"
137
+ failed_ids.each { |bid| puts " #{bid}" }
138
+ end
139
+ end
140
+
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,207 @@
1
+ require 'fileutils'
2
+ require 'json'
3
+ require 'pindo/base/git_handler'
4
+ require 'pindo/config/build_info_manager'
5
+
6
+ module Pindo
7
+ class Command
8
+ class Utils < Command
9
+ class Copyconfig < Utils
10
+
11
+ self.summary = '从已有配置仓库复制创建新的配置仓库,替换bundle id前缀'
12
+
13
+ self.description = <<-DESC
14
+ 从已有的配置仓库复制内容创建新的配置仓库,
15
+ 并将config.json中所有bundle id的组织前缀替换为新的前缀。
16
+
17
+ 支持功能:
18
+
19
+ * 在Gitee上创建新的配置仓库
20
+
21
+ * 复制源仓库的所有内容到新仓库
22
+
23
+ * 自动替换config.json中所有bundle id的组织前缀
24
+
25
+ * 只修改config.json, 其他文件保持不变
26
+
27
+ 使用示例:
28
+
29
+ $ pindo utils copyconfig com.neworg.app --from=com.oldorg.app
30
+
31
+ 注意事项:
32
+
33
+ * 源仓库必须已存在
34
+
35
+ * 新仓库名称不能与已有仓库重名
36
+ DESC
37
+
38
+ self.arguments = [
39
+ CLAide::Argument.new('new_bundle_id', false)
40
+ ]
41
+
42
+ def self.options
43
+ [
44
+ ['--from', '源配置仓库的bundle id'],
45
+ ['--apple-id', '新的Apple开发者账号邮箱']
46
+ ].concat(super)
47
+ end
48
+
49
+ def initialize(argv)
50
+ @new_bundle_id = argv.shift_argument
51
+ @from_bundle_id = argv.option('from')
52
+ @new_apple_id = argv.option('apple-id')
53
+ super
54
+ end
55
+
56
+ def validate!
57
+ super
58
+ help! "请指定新的 bundle id" if @new_bundle_id.nil? || @new_bundle_id.empty?
59
+ help! "请通过 --from 指定源 bundle id" if @from_bundle_id.nil? || @from_bundle_id.empty?
60
+ end
61
+
62
+ def run
63
+ # 提取组织前缀: com.heroneverdie101.xxx -> com.heroneverdie101
64
+ from_parts = @from_bundle_id.split('.')
65
+ new_parts = @new_bundle_id.split('.')
66
+
67
+ if from_parts.length < 2 || new_parts.length < 2
68
+ puts "bundle id 格式错误,至少需要两段 (如 com.org)"
69
+ return
70
+ end
71
+
72
+ from_prefix = from_parts[0..1].join('.')
73
+ new_prefix = new_parts[0..1].join('.')
74
+
75
+ puts "源仓库: #{@from_bundle_id}"
76
+ puts "新仓库: #{@new_bundle_id}"
77
+ puts "前缀替换: #{from_prefix} -> #{new_prefix}"
78
+ puts
79
+
80
+ # 拉取源仓库
81
+ puts "拉取源配置仓库..."
82
+ source_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name: @from_bundle_id)
83
+ source_config = File.join(source_dir, "config.json")
84
+
85
+ unless File.exist?(source_config)
86
+ puts "源仓库 #{@from_bundle_id} 中不存在 config.json"
87
+ return
88
+ end
89
+
90
+ # 创建新仓库
91
+ puts "创建新配置仓库 #{@new_bundle_id}..."
92
+ require_relative '../../client/giteeclient'
93
+
94
+ pindo_single_config = Pindoconfig.instance
95
+ gitee_client = GiteeClient.new(access_token: pindo_single_config.gitee_api_key)
96
+
97
+ owner_org = pindo_single_config.build_test_org
98
+
99
+ puts "目标组织: #{owner_org}"
100
+
101
+ success = gitee_client.gitee_create_repo(
102
+ owner: owner_org,
103
+ repo_name: @new_bundle_id,
104
+ public_type: 2
105
+ )
106
+
107
+ unless success
108
+ puts "创建仓库失败,仓库可能已存在"
109
+ return
110
+ end
111
+
112
+ # 将新仓库注册到 git_base_url.json,确保 clong_buildconfig_repo 能找到正确的 org
113
+ build_info_manager = Pindo::BuildInfoManager.share_instance
114
+ build_info_manager.modify_repo_setting(
115
+ repo_name: @new_bundle_id,
116
+ owner_org: owner_org
117
+ )
118
+
119
+ Funlog.instance.fancyinfo_update("等待 Gitee 仓库初始化...")
120
+ sleep 2
121
+
122
+ # 克隆新仓库
123
+ new_config_dir = nil
124
+ 3.times do |i|
125
+ begin
126
+ new_config_dir = Pindo::GitHandler.clong_buildconfig_repo(repo_name: @new_bundle_id)
127
+ break if new_config_dir && File.exist?(new_config_dir)
128
+ rescue => e
129
+ if i < 2
130
+ Funlog.instance.fancyinfo_update("克隆失败 (#{i + 1}/3),3秒后重试...")
131
+ sleep 3
132
+ else
133
+ puts "克隆仓库失败: #{e.message}"
134
+ return
135
+ end
136
+ end
137
+ end
138
+
139
+ # 复制源仓库所有内容到新仓库
140
+ puts "复制源仓库内容..."
141
+ Dir.glob(File.join(source_dir, '*'), File::FNM_DOTMATCH).each do |item|
142
+ basename = File.basename(item)
143
+ next if basename == '.' || basename == '..' || basename == '.git'
144
+ FileUtils.cp_r(item, new_config_dir)
145
+ end
146
+
147
+ # 修改 config.json
148
+ new_config_file = File.join(new_config_dir, "config.json")
149
+ if File.exist?(new_config_file)
150
+ config_json = JSON.parse(File.read(new_config_file))
151
+
152
+ # 替换所有 bundle id 的组织前缀
153
+ replace_prefix_in_hash(config_json, from_prefix, new_prefix)
154
+ puts "已替换 config.json 中的 #{from_prefix} -> #{new_prefix}"
155
+
156
+ # 更新 Apple ID
157
+ if @new_apple_id && !@new_apple_id.empty?
158
+ if config_json['account_info'] && config_json['account_info']['apple_acount_id']
159
+ old_apple_id = config_json['account_info']['apple_acount_id']
160
+ config_json['account_info']['apple_acount_id'] = @new_apple_id
161
+ puts "已替换 apple_acount_id: #{old_apple_id} -> #{@new_apple_id}"
162
+ end
163
+ end
164
+
165
+ File.open(new_config_file, "w") do |f|
166
+ f.write(JSON.pretty_generate(config_json) + "\n")
167
+ end
168
+ end
169
+
170
+ # 只提交 config.json
171
+ Pindo::GitHandler.git_addpush_repo(
172
+ path: new_config_dir,
173
+ message: "init config from #{@from_bundle_id}"
174
+ )
175
+
176
+ puts
177
+ puts "配置仓库创建完成: #{new_config_dir}"
178
+ end
179
+
180
+ private
181
+
182
+ # 递归替换 Hash 中所有字符串值的前缀
183
+ def replace_prefix_in_hash(obj, from_prefix, new_prefix)
184
+ case obj
185
+ when Hash
186
+ obj.each do |key, value|
187
+ if value.is_a?(String)
188
+ obj[key] = value.gsub(from_prefix, new_prefix)
189
+ else
190
+ replace_prefix_in_hash(value, from_prefix, new_prefix)
191
+ end
192
+ end
193
+ when Array
194
+ obj.each_with_index do |value, i|
195
+ if value.is_a?(String)
196
+ obj[i] = value.gsub(from_prefix, new_prefix)
197
+ else
198
+ replace_prefix_in_hash(value, from_prefix, new_prefix)
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ end
205
+ end
206
+ end
207
+ end
@@ -75,7 +75,7 @@ module Pindo
75
75
 
76
76
  Funlog.instance.fancyinfo_start("正在生成icon...")
77
77
  begin
78
- XcodeResHelper.create_icons(icon_name: icon_name, new_icon_dir: new_icon_dir)
78
+ XcodeResHelper.create_icons(icon_name: icon_name, new_icon_dir: new_icon_dir, proj_dir: Dir.pwd)
79
79
  Funlog.instance.fancyinfo_success("生成icon成功!")
80
80
  rescue StandardError => e
81
81
  Funlog.instance.fancyinfo_error("生成icon失败!")
@@ -101,4 +101,4 @@ module Pindo
101
101
  end
102
102
  end
103
103
  end
104
- end
104
+ end