pindo 5.18.3 → 5.18.5

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/command/android/autobuild.rb +27 -25
  3. data/lib/pindo/command/appstore/adhocbuild.rb +3 -3
  4. data/lib/pindo/command/appstore/autobuild.rb +3 -3
  5. data/lib/pindo/command/appstore/autoresign.rb +6 -2
  6. data/lib/pindo/command/appstore/cert.rb +12 -6
  7. data/lib/pindo/command/appstore/getitcinfo.rb +10 -8
  8. data/lib/pindo/command/appstore/iap.rb +9 -9
  9. data/lib/pindo/command/appstore/initconfig.rb +6 -7
  10. data/lib/pindo/command/appstore/itcinfo.rb +12 -12
  11. data/lib/pindo/command/appstore/metadata.rb +7 -6
  12. data/lib/pindo/command/appstore/screenshots.rb +7 -6
  13. data/lib/pindo/command/appstore/tag.rb +7 -4
  14. data/lib/pindo/command/gplay/iap.rb +7 -6
  15. data/lib/pindo/command/gplay/metadata.rb +7 -6
  16. data/lib/pindo/command/gplay/screenshots.rb +7 -6
  17. data/lib/pindo/command/ios/applovin.rb +9 -8
  18. data/lib/pindo/command/ios/autobuild.rb +1 -1
  19. data/lib/pindo/command/ios/autoresign.rb +6 -2
  20. data/lib/pindo/command/ios/cert.rb +11 -6
  21. data/lib/pindo/command/ios/fixproj.rb +9 -6
  22. data/lib/pindo/command/ios/podlint.rb +10 -5
  23. data/lib/pindo/command/ios/podpush.rb +13 -6
  24. data/lib/pindo/command/ios/podupdate.rb +10 -6
  25. data/lib/pindo/command/jps/apptest.rb +2 -2
  26. data/lib/pindo/command/jps/bind.rb +1 -1
  27. data/lib/pindo/command/jps/download.rb +11 -10
  28. data/lib/pindo/command/jps/login.rb +8 -7
  29. data/lib/pindo/command/jps/media.rb +1 -1
  30. data/lib/pindo/command/jps/upload.rb +56 -31
  31. data/lib/pindo/command/repo.rb +0 -6
  32. data/lib/pindo/command/unity/autobuild.rb +33 -41
  33. data/lib/pindo/command/unity/packpush.rb +14 -8
  34. data/lib/pindo/command/utils/renewcert.rb +15 -13
  35. data/lib/pindo/command/utils/repoinit.rb +12 -6
  36. data/lib/pindo/command/utils.rb +7 -7
  37. data/lib/pindo/command/web/autobuild.rb +29 -28
  38. data/lib/pindo/command/web/run.rb +9 -8
  39. data/lib/pindo/module/android/android_build_helper.rb +6 -6
  40. data/lib/pindo/module/android/keystore_helper.rb +1 -1
  41. data/lib/pindo/module/build/build_helper.rb +37 -3
  42. data/lib/pindo/module/cert/cert_helper.rb +1 -1
  43. data/lib/pindo/module/pgyer/pgyerhelper.rb +3 -3
  44. data/lib/pindo/module/task/core/task_executor.rb +2 -0
  45. data/lib/pindo/module/task/task_manager.rb +8 -0
  46. data/lib/pindo/options/core/global_options_state.rb +1 -1
  47. data/lib/pindo/options/core/option_item.rb +1 -1
  48. data/lib/pindo/options/groups/appstore_options.rb +114 -0
  49. data/lib/pindo/options/groups/build_options.rb +93 -4
  50. data/lib/pindo/options/groups/cert_options.rb +0 -52
  51. data/lib/pindo/options/groups/common_options.rb +27 -0
  52. data/lib/pindo/options/groups/global_options.rb +18 -0
  53. data/lib/pindo/options/groups/ios_tool_options.rb +60 -0
  54. data/lib/pindo/options/groups/jps_options.rb +41 -0
  55. data/lib/pindo/options/groups/option_group.rb +1 -1
  56. data/lib/pindo/options/groups/pod_options.rb +37 -0
  57. data/lib/pindo/options/groups/unity_options.rb +4 -4
  58. data/lib/pindo/options/groups/utils_options.rb +125 -0
  59. data/lib/pindo/options/options.rb +6 -0
  60. data/lib/pindo/version.rb +2 -2
  61. metadata +7 -1
@@ -92,30 +92,27 @@ module Pindo
92
92
  # 定义此命令使用的参数项
93
93
  def self.option_items
94
94
  @option_items ||= Pindo::Options::OptionGroup.merge(
95
- Pindo::Options::BuildOptions.select(:bundleid), # 添加 bundleid 参数
95
+ Pindo::Options::BuildOptions.select(:bundleid),
96
96
  Pindo::Options::JPSOptions.select(:conf, :upload, :send, :media, :bind),
97
97
  Pindo::Options::UnityOptions.select(:skiplib, :skipyoo),
98
- Pindo::Options::UnityOptions.select_with_defaults(skipconfig: true),
98
+ Pindo::Options::UnityOptions.select_with_defaults(skipmacro: true),
99
99
  Pindo::Options::TaskOptions.select(:multi),
100
+ Pindo::Options::UtilsOptions.select(:run),
100
101
  Pindo::Options::GitOptions.all
101
102
  )
102
103
  end
103
104
 
104
105
  # 命令的选项列表
105
106
  def self.options
106
- [
107
- ['--run', '编译完成后再本地打开webgl包']
108
- ].concat(option_items.map(&:to_claide_option)).concat(super)
107
+ option_items.map(&:to_claide_option).concat(super)
109
108
  end
110
109
 
111
110
  def initialize(argv)
112
111
  @options = initialize_options(argv)
113
112
 
114
- @args_deploy_flag = argv.flag?('deploy', false)
115
- @args_adhoc_flag = argv.flag?('adhoc', false)
116
113
  @args_conf = @options[:conf]
117
- @args_bundle_id = @options[:bundleid] # 从 @options 获取,确保能被缓存
118
- @args_run_flag = argv.flag?('run', false)
114
+ @args_bundle_id = @options[:bundleid]
115
+ @args_run_flag = @options[:run] || false
119
116
 
120
117
  # send、media 或 bind 都依赖 upload:如果指定了任一参数,自动启用 upload
121
118
  @args_upload_flag = @options[:send] || @options[:bind] || @options[:media] || @options[:upload]
@@ -154,31 +151,35 @@ module Pindo
154
151
  def run
155
152
  pindo_project_dir = Dir.pwd
156
153
 
157
- # 加载 JPS 配置(如果存在)
158
- Pindo::BuildHelper.share_instance.load_jps_build_config(pindo_project_dir, conf: @args_conf)
154
+ begin
155
+ # 加载 JPS 配置(如果存在)
156
+ Pindo::BuildHelper.share_instance.load_jps_build_config(pindo_project_dir, conf: @args_conf)
159
157
 
160
- # 准备配置
161
- config = prepare_web_config(pindo_project_dir)
158
+ # 准备配置
159
+ config = prepare_web_config(pindo_project_dir)
162
160
 
163
- # 创建并执行任务
164
- tasks = make_build_task(config)
161
+ # 创建并执行任务
162
+ tasks = make_build_task(config)
165
163
 
166
- # 添加到任务管理器并执行
167
- task_manager = Pindo::TaskSystem::TaskManager.instance
168
- task_manager.clear_all
169
- tasks.each { |task| task_manager.add_task(task) }
164
+ # 添加到任务管理器并执行
165
+ task_manager = Pindo::TaskSystem::TaskManager.instance
166
+ task_manager.clear_all
167
+ tasks.each { |task| task_manager.add_task(task) }
170
168
 
171
- # 执行任务(根据 --multi 参数决定模式)
172
- if @args_multi_flag
173
- task_manager.start(mode: :concurrent, max_workers: 3)
174
- else
175
- task_manager.start
176
- end
169
+ # 执行任务(根据 --multi 参数决定模式)
170
+ if @args_multi_flag
171
+ task_manager.start(mode: :concurrent, max_workers: 3)
172
+ else
173
+ task_manager.start
174
+ end
177
175
 
178
- system "open #{pindo_project_dir}"
176
+ system "open #{pindo_project_dir}"
179
177
 
180
- # 可选运行 WebGL
181
- Pindo::Command::Web::Run.run([]) if @args_run_flag
178
+ # 可选运行 WebGL
179
+ Pindo::Command::Web::Run.run([]) if @args_run_flag
180
+ ensure
181
+ Pindo::Options::GlobalOptionsState.instance.clear
182
+ end
182
183
  end
183
184
 
184
185
  private
@@ -34,19 +34,20 @@ module Pindo
34
34
  # 暂无参数
35
35
  ]
36
36
 
37
+ def self.option_items
38
+ @option_items ||= Pindo::Options::UtilsOptions.select(:port, :debug)
39
+ end
40
+
37
41
  # 命令的选项列表
38
42
  def self.options
39
- [
40
- # 添加HTTP服务器端口选项
41
- ['--port', '指定HTTP服务器的端口,默认为8000'],
42
- # 添加调试选项
43
- ['--debug', '显示详细的调试信息']
44
- ].concat(super)
43
+ option_items.map(&:to_claide_option).concat(super)
45
44
  end
46
45
 
47
46
  def initialize(argv)
48
- @args_port = argv.option('port', '8000').to_i # 添加端口参数,默认8000
49
- @args_debug = argv.flag?('debug', false) # 是否显示调试信息
47
+ @options = initialize_options(argv)
48
+
49
+ @args_port = (@options[:port] || '8000').to_i
50
+ @args_debug = @options[:debug] || false
50
51
 
51
52
  super
52
53
  @additional_args = argv.remainder!
@@ -314,10 +314,10 @@ module Pindo
314
314
  end
315
315
 
316
316
  bundle_task = "#{prefix}#{task_name}"
317
- skip_clean = ENV['PINDO_SKIP_GRADLE_CLEAN'] == '1'
318
- # 任意 bundle 变体(含 debug)均先 clean,避免 aabresguard 等任务因残留输出报「文件已存在」;本地加速可设 PINDO_SKIP_GRADLE_CLEAN=1
319
- puts ' AAB 构建前先执行 Gradle clean(环境变量 PINDO_SKIP_GRADLE_CLEAN=1 可跳过)' unless skip_clean
320
- puts ' 已跳过 Gradle clean(PINDO_SKIP_GRADLE_CLEAN=1)' if skip_clean
317
+ skip_clean = Pindo::Options::GlobalOptionsState.instance[:skipclean]
318
+ # 任意 bundle 变体(含 debug)均先 clean,避免 aabresguard 等任务因残留输出报「文件已存在」;可通过 --skipclean 或 PINDO_SKIP_GRADLE_CLEAN=1 跳过
319
+ puts ' AAB 构建前先执行 Gradle clean(--skipclean 可跳过)' unless skip_clean
320
+ puts ' 已跳过 Gradle clean(--skipclean)' if skip_clean
321
321
 
322
322
  gradle_clean_resilient!(project_path) unless skip_clean
323
323
 
@@ -440,8 +440,8 @@ module Pindo
440
440
  def validate_unity_libs_state!(android_root, stage:)
441
441
  # 某些项目会将 unityLibrary 作为缓存/中间产物纳入仓库,但 libs 下的 .aar -> .srcaar
442
442
  # 符号链接目标是由 EDM4U/导出过程生成,初次拉取代码时可能为断链。
443
- # 默认仍严格失败;如确有需要,可通过环境变量临时跳过此校验继续构建。
444
- return if ENV["PINDO_SKIP_UNITY_LIBS_VALIDATE"] == "1"
443
+ # 默认仍严格失败;可通过 --skipvalidate 或 PINDO_SKIP_UNITY_LIBS_VALIDATE=1 跳过
444
+ return if Pindo::Options::GlobalOptionsState.instance[:skipvalidate]
445
445
 
446
446
  libs_dir = File.join(android_root, "unityLibrary", "libs")
447
447
  return unless File.directory?(libs_dir)
@@ -172,7 +172,7 @@ module Pindo
172
172
 
173
173
  abs_keystore = File.expand_path(File.join(project_dir, rel_plain))
174
174
 
175
- inject_gradle = ENV["PINDO_INJECT_ANDROID_SIGNING_GRADLE"] == "1"
175
+ inject_gradle = Pindo::Options::GlobalOptionsState.instance[:injectsigning]
176
176
  if inject_gradle
177
177
  if gradle_file.end_with?(".kts")
178
178
  ensure_keystore_config_kts(gradle_file, project_dir, build_type, sign_config, bundle_id: bundle_id)
@@ -237,20 +237,44 @@ module Pindo
237
237
  # 检查 wildcard_bundle_group_name 和 bundle_group_name(兼容旧字段名)
238
238
  wildcard_bundle_group_name = config['wildcard_bundle_group_name'] || config['wildcardBundleId']
239
239
  bundle_group_name = config['bundle_group_name'] || config['bundleId']
240
+ project_id = config['project_id']
240
241
 
241
242
  # 如果缺失,通过 JPS 请求获取并回写
242
243
  if (wildcard_bundle_group_name.nil? || wildcard_bundle_group_name.empty?) ||
243
244
  (bundle_group_name.nil? || bundle_group_name.empty?)
244
- project_id = config['project_id']
245
+
246
+ if ENV['PINDO_DEBUG']
247
+ puts "[PINDO_DEBUG] load_jps_build_config: wildcard_bundle_group_name 或 bundle_group_name 缺失,尝试自动修复"
248
+ puts "[PINDO_DEBUG] wildcard_bundle_group_name=#{wildcard_bundle_group_name.inspect}"
249
+ puts "[PINDO_DEBUG] bundle_group_name=#{bundle_group_name.inspect}"
250
+ puts "[PINDO_DEBUG] project_id=#{project_id.inspect}, project_name=#{project_name.inspect}"
251
+ end
252
+
245
253
  app_info_data = nil
246
254
 
255
+ # 确保 PgyerHelper 已登录,否则 API 调用会因 @pgyer_client 为 nil 而失败
256
+ pgyer_helper = PgyerHelper.share_instace
257
+ pgyer_helper.login
258
+
247
259
  if project_id && !project_id.to_s.empty?
248
- app_info_data = PgyerHelper.share_instace.get_project_detail(project_id: project_id)
260
+ puts "[PINDO_DEBUG] 使用 project_id=#{project_id} 调用 get_project_detail" if ENV['PINDO_DEBUG']
261
+ app_info_data = pgyer_helper.get_project_detail(project_id: project_id)
262
+ puts "[PINDO_DEBUG] get_project_detail 返回: #{app_info_data.nil? ? 'nil' : '有数据'}" if ENV['PINDO_DEBUG']
249
263
  elsif project_name && !project_name.empty?
250
- app_info_data = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name: project_name)
264
+ puts "[PINDO_DEBUG] 使用 project_name=#{project_name} 调用 find_app_info_with_obj_list" if ENV['PINDO_DEBUG']
265
+ app_info_data = pgyer_helper.find_app_info_with_obj_list(proj_name: project_name)
266
+ puts "[PINDO_DEBUG] find_app_info_with_obj_list 返回: #{app_info_data.nil? ? 'nil' : '有数据'}" if ENV['PINDO_DEBUG']
267
+ else
268
+ puts "[PINDO_DEBUG] project_id 和 project_name 均为空,跳过自动修复" if ENV['PINDO_DEBUG']
251
269
  end
252
270
 
253
271
  if app_info_data
272
+ if ENV['PINDO_DEBUG']
273
+ puts "[PINDO_DEBUG] app_info_data 字段列表: #{app_info_data.keys.join(', ')}"
274
+ puts "[PINDO_DEBUG] wildcardBundleId=#{app_info_data['wildcardBundleId'].inspect}"
275
+ puts "[PINDO_DEBUG] bundleId=#{app_info_data['bundleId'].inspect}"
276
+ end
277
+
254
278
  wildcard_bundle_group_name = app_info_data["wildcardBundleId"]
255
279
  bundle_group_name = app_info_data["bundleId"]
256
280
 
@@ -259,8 +283,14 @@ module Pindo
259
283
  config['bundle_group_name'] = bundle_group_name
260
284
  File.write(config_file, JSON.pretty_generate(config) + "\n")
261
285
  puts "已从 JPS 获取并保存: wildcard_bundle_group_name=#{wildcard_bundle_group_name}, bundle_group_name=#{bundle_group_name}"
286
+ else
287
+ puts "[PINDO_DEBUG] wildcardBundleId 为空,无法自动修复" if ENV['PINDO_DEBUG']
262
288
  end
289
+ else
290
+ puts "[PINDO_DEBUG] 未获取到 app_info_data,自动修复失败" if ENV['PINDO_DEBUG']
263
291
  end
292
+ else
293
+ puts "[PINDO_DEBUG] load_jps_build_config: wildcard_bundle_group_name 和 bundle_group_name 已存在,跳过自动修复" if ENV['PINDO_DEBUG']
264
294
  end
265
295
 
266
296
  # 设置全局状态
@@ -281,6 +311,10 @@ module Pindo
281
311
  return config
282
312
  rescue => e
283
313
  puts "加载 JPSBuildConfig.json 失败: #{e.message}" if ENV['PINDO_VERBOSE'] == '1'
314
+ if ENV['PINDO_DEBUG']
315
+ puts "[PINDO_DEBUG] load_jps_build_config 异常: #{e.class}: #{e.message}"
316
+ puts "[PINDO_DEBUG] #{e.backtrace&.first(5)&.join("\n[PINDO_DEBUG] ")}"
317
+ end
284
318
  end
285
319
  nil
286
320
  end
@@ -199,7 +199,7 @@ module Pindo
199
199
 
200
200
  def install_and_config_certs(build_type:, platform_type: 'ios', project_dir: Dir.pwd)
201
201
  # 标准化构建类型
202
- cert_type = Pindo::Options::CertOptions.normalize_build_type(build_type)
202
+ cert_type = Pindo::Options::BuildOptions.normalize_build_type(build_type)
203
203
 
204
204
  # 使用 IosConfigParser 单例
205
205
  require 'pindo/config/ios_config_parser'
@@ -56,9 +56,9 @@ module Pindo
56
56
  # - project_name [String] 项目名称
57
57
  # - project_id [String] 项目ID
58
58
  # - workflow_info [Hash] 工作流信息(如果有效)
59
- def try_load_jps_build_config(config_file:, package_type:, manage_type: "")
59
+ def parse_jps_build_config(config_file:, package_type:, manage_type: "")
60
60
  if ENV['PINDO_DEBUG']
61
- puts "\n[PINDO_DEBUG] try_load_jps_build_config 调用:"
61
+ puts "\n[PINDO_DEBUG] parse_jps_build_config 调用:"
62
62
  puts " config_file: #{config_file}"
63
63
  puts " package_type: #{package_type.inspect}"
64
64
  puts " manage_type: #{manage_type.inspect}"
@@ -485,7 +485,7 @@ module Pindo
485
485
 
486
486
  # 尝试从配置文件加载
487
487
  if package_type || manage_type
488
- config_result = try_load_jps_build_config(
488
+ config_result = parse_jps_build_config(
489
489
  config_file: config_path,
490
490
  package_type: package_type,
491
491
  manage_type: manage_type
@@ -120,6 +120,8 @@ module Pindo
120
120
 
121
121
  rescue => e
122
122
  # 任务失败
123
+ task.status = TaskStatus::FAILED
124
+ task.error = e
123
125
  @reporter.print_task_failure(task, e)
124
126
  end
125
127
  end
@@ -117,6 +117,14 @@ module Pindo
117
117
 
118
118
  # 输出执行摘要
119
119
  @reporter.print_execution_summary
120
+
121
+ # 检查失败任务,有失败则抛出异常(确保进程返回非零退出码)
122
+ report = execution_report
123
+ if report[:failed] > 0
124
+ failed_tasks = @queue.completed_snapshot.select { |t| t.status == TaskStatus::FAILED }
125
+ failed_names = failed_tasks.map(&:name).join(', ')
126
+ raise Informative, "#{report[:failed]} 个任务执行失败: #{failed_names}"
127
+ end
120
128
  end
121
129
 
122
130
  # 获取执行报告
@@ -109,7 +109,7 @@ module Pindo
109
109
  # 3. JPS 相关
110
110
  :conf, :upload, :send, :desc,
111
111
  # 4. Unity 相关
112
- :skipconfig, :skiplib, :skipyoo,
112
+ :skipmacro, :skiplib, :skipyoo,
113
113
  # 5. Git 相关
114
114
  :ver_inc, :tag_type, :tag_pre, :release_branch
115
115
  ].freeze
@@ -114,7 +114,7 @@ module Pindo
114
114
  # @param overrides [Hash] 要覆盖的属性
115
115
  # @return [OptionItem] 新的 OptionItem 实例
116
116
  # @example
117
- # UnityOptions.select(:skipconfig).first.with(default_value: true)
117
+ # UnityOptions.select(:skipmacro).first.with(default_value: true)
118
118
  def with(**overrides)
119
119
  OptionItem.new(
120
120
  key: overrides[:key] || @key,
@@ -0,0 +1,114 @@
1
+ require 'pindo/options/core/option_item'
2
+ require 'pindo/options/groups/option_group'
3
+
4
+ module Pindo
5
+ module Options
6
+ # App Store / Google Play 商店操作参数组
7
+ # 定义 ITC 信息管理、内购、截图、元数据等商店相关参数
8
+ module AppStoreOptions
9
+ extend OptionGroup
10
+
11
+ def self.all_options
12
+ @all_options ||= {
13
+ metadata: OptionItem.new(
14
+ key: :metadata,
15
+ name: '元数据',
16
+ description: '上传或下载应用元数据',
17
+ type: OptionItem::Boolean,
18
+ env_name: 'PINDO_APPSTORE_METADATA',
19
+ default_value: false,
20
+ optional: true,
21
+ example: 'pindo appstore itcinfo --metadata'
22
+ ),
23
+
24
+ screenshots: OptionItem.new(
25
+ key: :screenshots,
26
+ name: '截图',
27
+ description: '上传或下载应用截图',
28
+ type: OptionItem::Boolean,
29
+ env_name: 'PINDO_APPSTORE_SCREENSHOTS',
30
+ default_value: false,
31
+ optional: true,
32
+ example: 'pindo appstore itcinfo --screenshots'
33
+ ),
34
+
35
+ overwrite: OptionItem.new(
36
+ key: :overwrite,
37
+ name: '覆盖',
38
+ description: '覆盖已有的数据或文件',
39
+ type: OptionItem::Boolean,
40
+ env_name: 'PINDO_APPSTORE_OVERWRITE',
41
+ default_value: false,
42
+ optional: true,
43
+ example: 'pindo appstore itcinfo --overwrite'
44
+ ),
45
+
46
+ sync: OptionItem.new(
47
+ key: :sync,
48
+ name: '同步模式',
49
+ description: '同步截图到 iTunes Connect',
50
+ type: OptionItem::Boolean,
51
+ env_name: 'PINDO_APPSTORE_SYNC',
52
+ default_value: false,
53
+ optional: true,
54
+ example: 'pindo appstore itcinfo --sync'
55
+ ),
56
+
57
+ ipa: OptionItem.new(
58
+ key: :ipa,
59
+ name: '上传 IPA',
60
+ description: '上传 IPA 到 iTunes Connect',
61
+ type: OptionItem::Boolean,
62
+ env_name: 'PINDO_APPSTORE_IPA',
63
+ default_value: false,
64
+ optional: true,
65
+ example: 'pindo appstore itcinfo --ipa'
66
+ ),
67
+
68
+ check: OptionItem.new(
69
+ key: :check,
70
+ name: '检查',
71
+ description: '检查内购配置信息',
72
+ type: OptionItem::Boolean,
73
+ env_name: 'PINDO_APPSTORE_CHECK',
74
+ default_value: false,
75
+ optional: true,
76
+ example: 'pindo appstore iap --check'
77
+ ),
78
+
79
+ boss: OptionItem.new(
80
+ key: :boss,
81
+ name: 'Boss 模式',
82
+ description: '生成 Boss 平台的内购信息',
83
+ type: OptionItem::Boolean,
84
+ env_name: 'PINDO_APPSTORE_BOSS',
85
+ default_value: false,
86
+ optional: true,
87
+ example: 'pindo appstore iap --boss'
88
+ ),
89
+
90
+ download: OptionItem.new(
91
+ key: :download,
92
+ name: '下载',
93
+ description: '从 App Store 下载应用的内购信息',
94
+ type: OptionItem::Boolean,
95
+ env_name: 'PINDO_APPSTORE_DOWNLOAD',
96
+ default_value: false,
97
+ optional: true,
98
+ example: 'pindo appstore iap --download'
99
+ ),
100
+
101
+ delete: OptionItem.new(
102
+ key: :delete,
103
+ name: '删除 Tag',
104
+ description: '删除指定的 Git Tag(同时删除代码仓库和配置仓库)',
105
+ type: String,
106
+ env_name: 'PINDO_DELETE_TAG',
107
+ optional: true,
108
+ example: 'pindo appstore tag --delete=tag_name'
109
+ )
110
+ }
111
+ end
112
+ end
113
+ end
114
+ end
@@ -48,16 +48,17 @@ module Pindo
48
48
  build_type: OptionItem.new(
49
49
  key: :build_type,
50
50
  name: '构建类型',
51
- description: '指定构建类型(dev/adhoc/appstore/developer_id',
51
+ description: '构建类型: dev(开发), adhoc(测试), release/appstore(发布), developer_id(macOS)',
52
52
  type: String,
53
53
  env_name: 'PINDO_BUILD_TYPE',
54
54
  default_value: nil,
55
55
  optional: true,
56
+ cacheable: true,
56
57
  verify_block: proc do |value|
57
- next if value.nil? # 允许 nil 值
58
- valid_types = ['dev', 'adhoc', 'appstore', 'developer_id']
58
+ next if value.nil?
59
+ valid_types = %w[dev development adhoc release appstore developer_id develop_id]
59
60
  unless valid_types.include?(value.to_s.downcase)
60
- raise "构建类型错误: #{value},必须是 #{valid_types.join('')} 之一"
61
+ raise "构建类型错误: #{value},必须是 #{valid_types.join(', ')} 之一"
61
62
  end
62
63
  end,
63
64
  example: 'pindo ios autobuild --build_type=appstore'
@@ -71,6 +72,94 @@ module Pindo
71
72
  env_name: 'PINDO_SCHEME',
72
73
  optional: true,
73
74
  example: 'pindo ios autobuild --scheme=MyAppScheme'
75
+ ),
76
+
77
+ types: OptionItem.new(
78
+ key: :types,
79
+ name: '包类型',
80
+ description: '指定包类型,逗号分隔(ipa,apk,html,mac,exe)',
81
+ type: String,
82
+ env_name: 'PINDO_BUILD_TYPES',
83
+ optional: true,
84
+ cacheable: false,
85
+ example: 'pindo unity autobuild --types=ipa,apk'
86
+ ),
87
+
88
+ dev: OptionItem.new(
89
+ key: :dev,
90
+ name: '开发模式',
91
+ description: '使用开发证书构建(等价于 --build_type=dev)',
92
+ type: OptionItem::Boolean,
93
+ env_name: 'PINDO_BUILD_DEV',
94
+ default_value: false,
95
+ optional: true,
96
+ example: 'pindo appstore cert --dev'
97
+ ),
98
+
99
+ adhoc: OptionItem.new(
100
+ key: :adhoc,
101
+ name: 'AdHoc 模式',
102
+ description: '使用 AdHoc 证书构建 iOS(等价于 --build_type=adhoc)',
103
+ type: OptionItem::Boolean,
104
+ env_name: 'PINDO_BUILD_ADHOC',
105
+ default_value: false,
106
+ optional: true,
107
+ example: 'pindo unity autobuild --adhoc'
108
+ ),
109
+
110
+ release: OptionItem.new(
111
+ key: :release,
112
+ name: 'Release 模式',
113
+ description: '使用 Release/发布模式构建(等价于 --build_type=release)',
114
+ type: OptionItem::Boolean,
115
+ env_name: 'PINDO_BUILD_RELEASE',
116
+ default_value: false,
117
+ optional: true,
118
+ example: 'pindo android autobuild --release'
119
+ ),
120
+
121
+ develop_id: OptionItem.new(
122
+ key: :develop_id,
123
+ name: 'Developer ID 模式',
124
+ description: '使用 macOS Developer ID 证书(等价于 --build_type=developer_id,仅 macOS)',
125
+ type: OptionItem::Boolean,
126
+ env_name: 'PINDO_BUILD_DEVELOP_ID',
127
+ default_value: false,
128
+ optional: true,
129
+ example: 'pindo appstore cert --develop_id --platform=macos'
130
+ ),
131
+
132
+ skipclean: OptionItem.new(
133
+ key: :skipclean,
134
+ name: '跳过 Gradle Clean',
135
+ description: '跳过 Android AAB 构建前的 Gradle clean 步骤(加速本地开发)',
136
+ type: OptionItem::Boolean,
137
+ env_name: 'PINDO_SKIP_GRADLE_CLEAN',
138
+ default_value: false,
139
+ optional: true,
140
+ example: 'pindo android autobuild --skipclean'
141
+ ),
142
+
143
+ skipvalidate: OptionItem.new(
144
+ key: :skipvalidate,
145
+ name: '跳过 Unity 库校验',
146
+ description: '跳过 Unity unityLibrary/libs 符号链接有效性校验',
147
+ type: OptionItem::Boolean,
148
+ env_name: 'PINDO_SKIP_UNITY_LIBS_VALIDATE',
149
+ default_value: false,
150
+ optional: true,
151
+ example: 'pindo android autobuild --skipvalidate'
152
+ ),
153
+
154
+ injectsigning: OptionItem.new(
155
+ key: :injectsigning,
156
+ name: '注入签名配置',
157
+ description: '注入签名配置到 Android build.gradle(自动改写 signingConfigs)',
158
+ type: OptionItem::Boolean,
159
+ env_name: 'PINDO_INJECT_ANDROID_SIGNING_GRADLE',
160
+ default_value: false,
161
+ optional: true,
162
+ example: 'pindo android autobuild --injectsigning'
74
163
  )
75
164
  }
76
165
  end
@@ -32,58 +32,6 @@ module Pindo
32
32
  example: 'pindo appstore cert --config=/path/config.json'
33
33
  ),
34
34
 
35
- build_type: OptionItem.new(
36
- key: :build_type,
37
- name: '构建类型',
38
- description: '构建类型: dev/development(开发), adhoc(测试), release/appstore(发布), developer_id/develop_id(macOS)',
39
- type: String,
40
- env_name: 'PINDO_BUILD_TYPE',
41
- default_value: nil,
42
- optional: true,
43
- cacheable: true,
44
- verify_block: proc do |value|
45
- next if value.nil? # 允许 nil 值
46
- unless BUILD_TYPES.include?(value.to_s.downcase)
47
- raise "构建类型错误: #{value},必须是 #{BUILD_TYPES.join(', ')} 之一"
48
- end
49
- end,
50
- example: 'pindo appstore cert --build_type=dev'
51
- ),
52
-
53
- # 证书类型快捷方式(等价于 --build_type)
54
- dev: OptionItem.new(
55
- key: :dev,
56
- name: '使用开发证书',
57
- description: '使用开发证书(等价于 --build_type=dev)',
58
- type: OptionItem::Boolean,
59
- env_name: 'PINDO_CERT_DEV',
60
- optional: true,
61
- default_value: false,
62
- example: 'pindo appstore cert --dev'
63
- ),
64
-
65
- adhoc: OptionItem.new(
66
- key: :adhoc,
67
- name: '使用 AdHoc 证书',
68
- description: '使用 AdHoc 证书(等价于 --build_type=adhoc)',
69
- type: OptionItem::Boolean,
70
- env_name: 'PINDO_CERT_ADHOC',
71
- optional: true,
72
- default_value: false,
73
- example: 'pindo appstore cert --adhoc'
74
- ),
75
-
76
- develop_id: OptionItem.new(
77
- key: :develop_id,
78
- name: '使用 Developer ID 证书',
79
- description: '使用 macOS Developer ID Application 证书(等价于 --build_type=developer_id,仅 macOS)',
80
- type: OptionItem::Boolean,
81
- env_name: 'PINDO_CERT_DEVELOP_ID',
82
- optional: true,
83
- default_value: false,
84
- example: 'pindo appstore cert --develop_id --platform=macos'
85
- ),
86
-
87
35
  renew: OptionItem.new(
88
36
  key: :renew,
89
37
  name: '重新生成证书',
@@ -0,0 +1,27 @@
1
+ require 'pindo/options/core/option_item'
2
+ require 'pindo/options/groups/option_group'
3
+
4
+ module Pindo
5
+ module Options
6
+ # 通用参数组
7
+ # 定义跨命令共享的通用参数(如 login、force、auto 等常见操作参数)
8
+ module CommonOptions
9
+ extend OptionGroup
10
+
11
+ def self.all_options
12
+ @all_options ||= {
13
+ force: OptionItem.new(
14
+ key: :force,
15
+ name: '强制执行',
16
+ description: '强制执行操作,跳过确认或验证',
17
+ type: OptionItem::Boolean,
18
+ env_name: 'PINDO_FORCE',
19
+ default_value: false,
20
+ optional: true,
21
+ example: 'pindo unity packpush --force'
22
+ )
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ require 'pindo/options/core/option_item'
2
+ require 'pindo/options/groups/option_group'
3
+
4
+ module Pindo
5
+ module Options
6
+ # 全局行为参数组
7
+ # 控制 pindo 运行时的全局行为(调试、缓存、UI、版本检查等)
8
+ # 与 CommonOptions(命令级共享参数)不同,GlobalOptions 影响所有命令的运行环境
9
+ module GlobalOptions
10
+ extend OptionGroup
11
+
12
+ def self.all_options
13
+ @all_options ||= {
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end