pindo 5.2.4 → 5.3.7

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/aeshelper.rb +23 -2
  3. data/lib/pindo/base/pindocontext.rb +259 -0
  4. data/lib/pindo/client/pgyer_feishu_oauth_cli.rb +343 -80
  5. data/lib/pindo/client/pgyerclient.rb +30 -20
  6. data/lib/pindo/command/android/autobuild.rb +52 -22
  7. data/lib/pindo/command/android/build.rb +27 -16
  8. data/lib/pindo/command/android/debug.rb +25 -15
  9. data/lib/pindo/command/dev/debug.rb +2 -51
  10. data/lib/pindo/command/dev/feishu.rb +19 -2
  11. data/lib/pindo/command/ios/adhoc.rb +2 -1
  12. data/lib/pindo/command/ios/autobuild.rb +35 -8
  13. data/lib/pindo/command/ios/debug.rb +2 -132
  14. data/lib/pindo/command/lib/lint.rb +24 -1
  15. data/lib/pindo/command/setup.rb +24 -4
  16. data/lib/pindo/command/unity/apk.rb +15 -0
  17. data/lib/pindo/command/unity/ipa.rb +16 -0
  18. data/lib/pindo/command.rb +13 -2
  19. data/lib/pindo/module/android/android_build_config_helper.rb +425 -0
  20. data/lib/pindo/module/android/apk_helper.rb +23 -25
  21. data/lib/pindo/module/android/base_helper.rb +572 -0
  22. data/lib/pindo/module/android/build_helper.rb +8 -318
  23. data/lib/pindo/module/android/gp_compliance_helper.rb +668 -0
  24. data/lib/pindo/module/android/gradle_helper.rb +746 -3
  25. data/lib/pindo/module/appselect.rb +18 -5
  26. data/lib/pindo/module/build/buildhelper.rb +120 -29
  27. data/lib/pindo/module/build/unityhelper.rb +675 -18
  28. data/lib/pindo/module/build/versionhelper.rb +146 -0
  29. data/lib/pindo/module/cert/certhelper.rb +33 -2
  30. data/lib/pindo/module/cert/xcodecerthelper.rb +3 -1
  31. data/lib/pindo/module/pgyer/pgyerhelper.rb +114 -31
  32. data/lib/pindo/module/xcode/xcodebuildconfig.rb +232 -0
  33. data/lib/pindo/module/xcode/xcodebuildhelper.rb +0 -1
  34. data/lib/pindo/version.rb +356 -86
  35. data/lib/pindo.rb +72 -3
  36. metadata +5 -1
@@ -5,6 +5,7 @@ require 'fileutils'
5
5
  require 'pindo/base/executable'
6
6
  require 'pindo/module/build/unityhelper'
7
7
  require 'pindo/module/build/buildhelper'
8
+ require 'pindo/base/pindocontext'
8
9
 
9
10
  module Pindo
10
11
  class Command
@@ -129,6 +130,21 @@ module Pindo
129
130
  if isLibrary
130
131
  pindo_ios_project_dir = ios_export_lib_dir
131
132
  end
133
+
134
+ # 验证构建输出目录是否存在
135
+ unless File.directory?(pindo_ios_project_dir)
136
+ puts "\e[31m错误: Unity 构建输出目录不存在: #{pindo_ios_project_dir}\e[0m"
137
+ puts "\e[33m可能的原因:\e[0m"
138
+ puts "• Unity 构建失败但未正确报告错误"
139
+ puts "• GoodUnityBuild 配置的输出路径不正确"
140
+ puts "• Unity 项目配置问题"
141
+ puts "\e[33m建议检查:\e[0m"
142
+ puts "• Unity 控制台日志"
143
+ puts "• GoodUnityBuild 的 IOSBuildConfiguration.cs 配置"
144
+ puts "• 项目路径和权限设置"
145
+ raise "Unity 构建输出目录不存在,构建可能失败"
146
+ end
147
+
132
148
  unity_helper.build_project(unity_exe_full_path:unity_exe_path, project_path:pindo_project_dir, platform:'iOS', isLibrary:isLibrary)
133
149
 
134
150
 
data/lib/pindo/command.rb CHANGED
@@ -7,6 +7,7 @@ require 'pindo/base/funlog'
7
7
  require 'pindo/base/hashhelper'
8
8
  require 'pindo/base/plaininformative'
9
9
  require 'pindo/base/githelper'
10
+ require 'pindo/base/pindocontext'
10
11
  require 'pindo/client/giteeclient'
11
12
  require 'pindo/config/pindoconfig'
12
13
 
@@ -89,8 +90,18 @@ module Pindo
89
90
  end
90
91
 
91
92
  def self.run(argv)
92
-
93
- super(argv)
93
+ # 设置上下文
94
+ context = Pindo::PindoContext.instance
95
+ command_name = self.command # 获取完整的命令名称,如 'ios:autobuild'
96
+ context.set_context(command_name)
97
+
98
+ begin
99
+ result = super(argv)
100
+ ensure
101
+ # 确保在命令结束时重置上下文
102
+ context.reset_context
103
+ end
104
+ result
94
105
  end
95
106
 
96
107
  def initialize(argv)
@@ -0,0 +1,425 @@
1
+ require 'fileutils'
2
+ require_relative '../../base/funlog'
3
+ require_relative 'base_helper'
4
+
5
+ module Pindo
6
+
7
+ class AndroidBuildConfigHelper
8
+ include BaseAndroidHelper
9
+
10
+ # 更新Android工程版本号
11
+ # @param project_dir [String] Android项目目录路径
12
+ # @param version_name [String] 版本名
13
+ # @param version_code [Integer] 版本号
14
+ # @return [Boolean] 是否成功更新
15
+ def self.update_android_project_version(project_dir: nil, version_name: nil, version_code: nil)
16
+ raise ArgumentError, "项目目录不能为空" if project_dir.nil?
17
+ raise ArgumentError, "版本名不能为空" if version_name.nil?
18
+ raise ArgumentError, "版本号不能为空" if version_code.nil?
19
+
20
+ # 验证version_code的有效性
21
+ unless valid_build_number?(version_code)
22
+ Funlog.instance.fancyinfo_error("Android versionCode必须在1到#{2**31-1}之间,当前值:#{version_code}")
23
+ return false
24
+ end
25
+
26
+ Funlog.instance.fancyinfo_start("正在更新Android工程版本信息...")
27
+
28
+ begin
29
+ # 创建helper实例以使用基类方法
30
+ helper = self.new
31
+
32
+ # 获取主模块路径
33
+ main_module = helper.get_main_module(project_dir)
34
+
35
+ if main_module.nil?
36
+ # 如果无法获取主模块,尝试常见的模块名
37
+ ["app", "application", "main"].each do |module_name|
38
+ module_path = File.join(project_dir, module_name)
39
+ if File.exist?(File.join(module_path, "build.gradle")) ||
40
+ File.exist?(File.join(module_path, "build.gradle.kts"))
41
+ main_module = module_path
42
+ break
43
+ end
44
+ end
45
+ end
46
+
47
+ if main_module.nil?
48
+ Funlog.instance.fancyinfo_error("未找到Android主模块")
49
+ return false
50
+ end
51
+
52
+ # 查找build.gradle或build.gradle.kts文件
53
+ gradle_file = nil
54
+ if File.exist?(File.join(main_module, "build.gradle"))
55
+ gradle_file = File.join(main_module, "build.gradle")
56
+ elsif File.exist?(File.join(main_module, "build.gradle.kts"))
57
+ gradle_file = File.join(main_module, "build.gradle.kts")
58
+ end
59
+
60
+ if gradle_file.nil?
61
+ Funlog.instance.fancyinfo_error("未找到build.gradle文件")
62
+ return false
63
+ end
64
+
65
+ # 读取并更新gradle文件
66
+ content = File.read(gradle_file)
67
+ original_content = content.dup
68
+
69
+ # 更新versionCode
70
+ if content =~ /versionCode\s+\d+/
71
+ content.gsub!(/versionCode\s+\d+/, "versionCode #{version_code}")
72
+ elsif content =~ /versionCode\s*=\s*\d+/
73
+ content.gsub!(/versionCode\s*=\s*\d+/, "versionCode = #{version_code}")
74
+ end
75
+
76
+ # 更新versionName
77
+ if content =~ /versionName\s+["'][^"']*["']/
78
+ content.gsub!(/versionName\s+["'][^"']*["']/, "versionName \"#{version_name}\"")
79
+ elsif content =~ /versionName\s*=\s*["'][^"']*["']/
80
+ content.gsub!(/versionName\s*=\s*["'][^"']*["']/, "versionName = \"#{version_name}\"")
81
+ end
82
+
83
+ # 如果内容有变化,写回文件
84
+ if content != original_content
85
+ File.write(gradle_file, content)
86
+ Funlog.instance.fancyinfo_success("Android版本更新完成!")
87
+ puts " ✓ versionName已更新: #{version_name}"
88
+ puts " ✓ versionCode已更新: #{version_code}"
89
+ puts " ✓ 更新的文件: #{gradle_file}"
90
+ return true
91
+ else
92
+ # 如果没有找到版本字段,尝试在defaultConfig块中添加
93
+ if content =~ /defaultConfig\s*\{([^}]*)\}/m
94
+ default_config = $1
95
+ if !default_config.include?("versionCode") || !default_config.include?("versionName")
96
+ Funlog.instance.fancyinfo_update("gradle文件中未找到版本字段,尝试添加...")
97
+
98
+ # 在defaultConfig块中添加版本信息
99
+ new_default_config = default_config
100
+ unless default_config.include?("versionCode")
101
+ new_default_config += "\n versionCode #{version_code}"
102
+ end
103
+ unless default_config.include?("versionName")
104
+ new_default_config += "\n versionName \"#{version_name}\""
105
+ end
106
+
107
+ content.gsub!(/defaultConfig\s*\{[^}]*\}/m, "defaultConfig {#{new_default_config}\n }")
108
+ File.write(gradle_file, content)
109
+
110
+ Funlog.instance.fancyinfo_success("Android版本更新完成!")
111
+ puts " ✓ versionName已添加: #{version_name}"
112
+ puts " ✓ versionCode已添加: #{version_code}"
113
+ return true
114
+ end
115
+ end
116
+
117
+ Funlog.instance.fancyinfo_error("无法在gradle文件中找到或添加版本信息")
118
+ return false
119
+ end
120
+
121
+ rescue StandardError => e
122
+ Funlog.instance.fancyinfo_error("更新Android版本失败: #{e.message}")
123
+ return false
124
+ end
125
+ end
126
+
127
+ # 验证Build号是否在有效范围内
128
+ # @param build_number [Integer] Build号
129
+ # @return [Boolean] 是否有效
130
+ def self.valid_build_number?(build_number)
131
+ return false if build_number.nil?
132
+
133
+ # Android versionCode的有效范围是1到2^31-1
134
+ build_number >= 1 && build_number <= 2**31 - 1
135
+ end
136
+
137
+ # 添加测试scheme到Android工程
138
+ # @param project_dir [String] Android项目目录路径
139
+ # @param scheme_name [String] 要添加的scheme名称
140
+ # @return [Boolean] 是否成功添加
141
+ def self.add_test_scheme(project_dir: nil, scheme_name: nil)
142
+ # 参数验证
143
+ if scheme_name.nil?
144
+ Funlog.instance.fancyinfo_error("需要提供scheme名称")
145
+ return false
146
+ end
147
+
148
+ if project_dir.nil? || !File.directory?(project_dir)
149
+ Funlog.instance.fancyinfo_error("项目路径无效: #{project_dir}")
150
+ return false
151
+ end
152
+
153
+ scheme_name = scheme_name.to_s.gsub(/[^a-zA-Z0-9]/, '').downcase
154
+ puts "正在为Android项目添加自定义scheme: #{scheme_name}"
155
+
156
+ # 创建helper实例以使用基类方法
157
+ helper = self.new
158
+
159
+ # 查找所有可能的模块
160
+ main_module = helper.get_main_module(project_dir)
161
+ search_modules = ["app", "unityLibrary"]
162
+ search_modules << main_module if main_module
163
+ search_modules = search_modules.compact.uniq
164
+
165
+ puts "搜索的模块: #{search_modules.join(', ')}"
166
+
167
+ # 查找所有可能的AndroidManifest.xml文件
168
+ manifest_candidates = find_manifests(project_dir, search_modules)
169
+
170
+ if manifest_candidates.empty?
171
+ Funlog.instance.fancyinfo_error("未找到任何AndroidManifest.xml文件")
172
+ return false
173
+ end
174
+
175
+ puts "找到#{manifest_candidates.size}个AndroidManifest.xml文件"
176
+
177
+ # 寻找最佳的AndroidManifest.xml和Activity
178
+ manifest_path, main_activity, android_prefix = find_best_activity(manifest_candidates)
179
+
180
+ if manifest_path.nil? || main_activity.nil?
181
+ Funlog.instance.fancyinfo_error("无法找到合适的Activity")
182
+ return false
183
+ end
184
+
185
+ puts "已选择 #{manifest_path} 文件中的 #{main_activity['android:name'] || '主Activity'}"
186
+
187
+ # 检查scheme是否已存在
188
+ scheme_exists, existing_scheme = check_scheme_exists(main_activity, android_prefix, scheme_name)
189
+
190
+ # 如果scheme已存在,检查是否需要更新格式
191
+ if scheme_exists
192
+ activity_name = main_activity["#{android_prefix}:name"] || "主Activity"
193
+ if existing_scheme != scheme_name
194
+ # 格式不同,需要更新
195
+ if update_existing_scheme(manifest_path, main_activity, android_prefix, existing_scheme, scheme_name)
196
+ Funlog.instance.fancyinfo_update("已将scheme从'#{existing_scheme}'更新为'#{scheme_name}'")
197
+ else
198
+ Funlog.instance.fancyinfo_update("scheme已存在: #{existing_scheme}")
199
+ end
200
+ else
201
+ puts " ✓ scheme已存在: #{scheme_name}"
202
+ end
203
+ return true
204
+ end
205
+
206
+ # 尝试使用DOM添加
207
+ success = add_scheme_with_dom(manifest_path, main_activity, android_prefix, scheme_name)
208
+
209
+ unless success
210
+ # DOM方法失败,尝试文本替换
211
+ success = add_scheme_with_text_replace(manifest_path, scheme_name)
212
+ end
213
+
214
+ if success
215
+ puts " ✓ 成功添加scheme: #{scheme_name}"
216
+ else
217
+ Funlog.instance.fancyinfo_error("无法添加scheme: #{scheme_name}")
218
+ end
219
+
220
+ return success
221
+ end
222
+
223
+ private
224
+
225
+ # 查找所有可能的AndroidManifest.xml文件
226
+ def self.find_manifests(project_dir, modules)
227
+ manifest_candidates = []
228
+
229
+ modules.each do |mod|
230
+ mod_path = mod.is_a?(String) && !mod.start_with?(project_dir) ? File.join(project_dir, mod) : mod
231
+ next unless File.directory?(mod_path)
232
+
233
+ manifest_paths = [
234
+ File.join(mod_path, "src", "main", "AndroidManifest.xml"),
235
+ File.join(mod_path, "AndroidManifest.xml")
236
+ ]
237
+
238
+ manifest_paths.each do |path|
239
+ if File.exist?(path)
240
+ manifest_candidates << path
241
+ end
242
+ end
243
+ end
244
+
245
+ manifest_candidates
246
+ end
247
+
248
+ # 查找最佳的Activity
249
+ def self.find_best_activity(manifest_candidates)
250
+ require 'nokogiri'
251
+
252
+ best_manifest = nil
253
+ best_activity = nil
254
+ android_prefix = nil
255
+
256
+ manifest_candidates.each do |manifest_path|
257
+ begin
258
+ doc = Nokogiri::XML(File.read(manifest_path))
259
+ doc.remove_namespaces!
260
+
261
+ # 查找包含MAIN和LAUNCHER的Activity
262
+ activities = doc.xpath("//activity")
263
+ activities.each do |activity|
264
+ intent_filters = activity.xpath("intent-filter")
265
+ intent_filters.each do |intent_filter|
266
+ has_main = intent_filter.xpath("action[@android:name='android.intent.action.MAIN']").any?
267
+ has_launcher = intent_filter.xpath("category[@android:name='android.intent.category.LAUNCHER']").any?
268
+
269
+ if has_main && has_launcher
270
+ best_manifest = manifest_path
271
+ best_activity = activity
272
+ android_prefix = "android"
273
+ break
274
+ end
275
+ end
276
+ break if best_activity
277
+ end
278
+ rescue => e
279
+ # 静默处理解析错误,继续尝试下一个文件
280
+ end
281
+
282
+ break if best_activity
283
+ end
284
+
285
+ [best_manifest, best_activity, android_prefix]
286
+ end
287
+
288
+ # 检查scheme是否已存在
289
+ def self.check_scheme_exists(activity, android_prefix, scheme_name)
290
+ scheme_exists = false
291
+ existing_scheme = nil
292
+
293
+ # 首先检查完全一致的scheme
294
+ activity.xpath("intent-filter/data[@#{android_prefix}:scheme='#{scheme_name}']").each do |node|
295
+ scheme_exists = true
296
+ existing_scheme = scheme_name
297
+ break
298
+ end
299
+
300
+ # 如果没有找到完全一致的,检查可能格式不同的scheme
301
+ if !scheme_exists
302
+ activity.xpath("intent-filter/data[@#{android_prefix}:scheme]").each do |node|
303
+ current_scheme = node["#{android_prefix}:scheme"]
304
+ normalized_current = current_scheme.to_s.downcase.strip.gsub(/[\s\-_]/, '')
305
+
306
+ if normalized_current == scheme_name
307
+ scheme_exists = true
308
+ existing_scheme = current_scheme
309
+ break
310
+ end
311
+ end
312
+ end
313
+
314
+ [scheme_exists, existing_scheme]
315
+ end
316
+
317
+ # 使用DOM操作添加scheme
318
+ def self.add_scheme_with_dom(manifest_path, activity, android_prefix, scheme_name)
319
+ begin
320
+ doc = Nokogiri::XML(File.read(manifest_path))
321
+
322
+ # 创建intent-filter
323
+ intent_filter = doc.create_element('intent-filter')
324
+
325
+ # 添加子元素
326
+ intent_filter.add_child(create_element(doc, 'action', "#{android_prefix}:name", 'android.intent.action.VIEW'))
327
+ intent_filter.add_child(create_element(doc, 'category', "#{android_prefix}:name", 'android.intent.category.DEFAULT'))
328
+ intent_filter.add_child(create_element(doc, 'category', "#{android_prefix}:name", 'android.intent.category.BROWSABLE'))
329
+ intent_filter.add_child(create_element(doc, 'data', "#{android_prefix}:scheme", scheme_name))
330
+
331
+ # 添加空白和缩进
332
+ activity.add_child(doc.create_text_node("\n "))
333
+ activity.add_child(intent_filter)
334
+ activity.add_child(doc.create_text_node("\n "))
335
+
336
+ # 保存修改
337
+ xml_content = doc.to_xml(indent: 2, encoding: 'UTF-8')
338
+
339
+ # 验证修改是否成功
340
+ if xml_content.include?("android:scheme=\"#{scheme_name}\"")
341
+ File.write(manifest_path, xml_content)
342
+ return true
343
+ end
344
+
345
+ return false
346
+ rescue => e
347
+ return false
348
+ end
349
+ end
350
+
351
+ # 创建XML元素并设置属性
352
+ def self.create_element(doc, name, attr_name, attr_value)
353
+ element = doc.create_element(name)
354
+ element[attr_name] = attr_value
355
+ element
356
+ end
357
+
358
+ # 使用文本替换添加scheme
359
+ def self.add_scheme_with_text_replace(manifest_path, scheme_name)
360
+ begin
361
+ # 读取原始内容
362
+ xml_content = File.read(manifest_path)
363
+
364
+ # 定义要添加的intent-filter
365
+ scheme_intent_filter = %Q{
366
+ <intent-filter>
367
+ <action android:name="android.intent.action.VIEW"/>
368
+ <category android:name="android.intent.category.DEFAULT"/>
369
+ <category android:name="android.intent.category.BROWSABLE"/>
370
+ <data android:scheme="#{scheme_name}"/>
371
+ </intent-filter>}
372
+
373
+ # 在</activity>前添加intent-filter
374
+ if xml_content.match(/<\/activity>/)
375
+ modified_xml = xml_content.gsub(/<\/activity>/) do |match|
376
+ "#{scheme_intent_filter}\n #{match}"
377
+ end
378
+
379
+ # 保存修改
380
+ File.write(manifest_path, modified_xml)
381
+ return true
382
+ end
383
+
384
+ return false
385
+ rescue => e
386
+ return false
387
+ end
388
+ end
389
+
390
+ def self.update_existing_scheme(manifest_path, activity, android_prefix, existing_scheme, scheme_name)
391
+ begin
392
+ doc = Nokogiri::XML(File.read(manifest_path))
393
+
394
+ # 查找所有intent-filter
395
+ intent_filters = doc.xpath("//intent-filter")
396
+
397
+ intent_filters.each do |intent_filter|
398
+ # 检查intent-filter中的scheme
399
+ intent_filter.xpath("data[@#{android_prefix}:scheme]").each do |data|
400
+ current_scheme = data["#{android_prefix}:scheme"]
401
+ if current_scheme == existing_scheme
402
+ # 找到intent-filter,更新scheme
403
+ data["#{android_prefix}:scheme"] = scheme_name
404
+ end
405
+ end
406
+ end
407
+
408
+ # 保存修改
409
+ xml_content = doc.to_xml(indent: 2, encoding: 'UTF-8')
410
+
411
+ # 验证修改是否成功
412
+ if xml_content.include?("android:scheme=\"#{scheme_name}\"")
413
+ File.write(manifest_path, xml_content)
414
+ return true
415
+ end
416
+
417
+ return false
418
+ rescue => e
419
+ return false
420
+ end
421
+ end
422
+
423
+ end
424
+
425
+ end
@@ -1,4 +1,5 @@
1
1
  require_relative 'base_helper'
2
+ require_relative 'gp_compliance_helper'
2
3
 
3
4
  module Pindo
4
5
  module ApkHelper
@@ -43,31 +44,20 @@ module Pindo
43
44
  raise RuntimeError, "找不到 AAB 文件: #{paths[:bundle]}"
44
45
  end
45
46
 
46
- # --- AAB 包体积检测 ---
47
- aab_size = File.size(paths[:bundle])
48
- aab_size_mb = (aab_size.to_f / 1024 / 1024).round(2)
49
- base_size = 0
50
- base_size_mb = 0
51
- base_percent = 0
52
- base_limit_bytes = 194615705 # 185MB
53
- base_limit_mb = 185
47
+ # --- Google Play 合规检测 (包含包体积、Target SDK、ELF对齐检测) ---
54
48
  begin
55
- # unzip -v 统计 base/ 文件夹压缩体积
56
- unzip_out = `unzip -v "#{paths[:bundle]}"`
57
- base_lines = unzip_out.lines.select { |l| l.include?(" base/") }
58
- base_size = base_lines.map { |l| l.split[2].to_i }.sum
59
- base_size_mb = (base_size.to_f / 1024 / 1024).round(2)
60
- base_percent = aab_size > 0 ? ((base_size.to_f * 100) / aab_size).round(2) : 0
49
+ compliance_result = Pindo::GPComplianceHelper.check_aab_compliance(paths[:bundle])
50
+
51
+ # 合规检测结果已在 gp_compliance_helper.rb 中输出,这里只做简单的状态提示
52
+ if compliance_result.compliant?
53
+ puts "\e[32m\e[1m✓ AAB 包符合 Google Play 最新合规要求,可以正常提交\e[0m"
54
+ else
55
+ puts "\e[31m\e[1m✗ AAB 包不符合 Google Play 提交标准,需要修复合规问题才能提交!!!\e[0m"
56
+ end
57
+
61
58
  rescue => e
62
- puts "\e[31mAAB base 文件夹体积检测失败: #{e.message}\e[0m"
63
- end
64
- puts "\e[36mAAB 包体积: #{aab_size_mb} MB\e[0m"
65
- puts "\e[36mbase 文件夹压缩体积: #{base_size_mb} MB (占比 #{base_percent}%)\e[0m"
66
- if base_size > base_limit_bytes
67
- puts "\e[41;97m警告: base 文件夹已超出 Google Play 限制(#{base_limit_mb}MB),请优化资源或分包!\e[0m"
68
- puts "\e[31mAAB 包体积不符合 Google Play 提交标准,需要缩减包体积才能提交!!!\e[0m"
69
- else
70
- puts "\e[32mAAB 包体积符合 Google Play 提交标准,可以正常提交\e[0m"
59
+ puts "\e[31mGoogle Play 合规检测失败: #{e.message}\e[0m"
60
+ puts "\e[33m建议手动检查包体积、Target SDK 版本和共享库对齐情况\e[0m"
71
61
  end
72
62
  # --- END ---
73
63
 
@@ -82,8 +72,11 @@ module Pindo
82
72
  # puts "读取 key pass = #{key_pass}"
83
73
 
84
74
  # 构建 APK
75
+ # 确保使用正确的 Java 版本 (Java 11+)
76
+ java_cmd = find_java_command
77
+ # puts "\e[36m使用 Java 命令: #{java_cmd}\e[0m"
85
78
  bundletool_cmd = [
86
- "java -jar #{bundle_tool} build-apks",
79
+ "#{java_cmd} -jar #{bundle_tool} build-apks",
87
80
  "--bundle=#{paths[:bundle]}",
88
81
  "--output=#{paths[:output_apks]}",
89
82
  "--ks=#{ks}",
@@ -94,7 +87,12 @@ module Pindo
94
87
  ].join(" ")
95
88
 
96
89
  unless system(bundletool_cmd)
97
- raise RuntimeError, "APKS 构建失败"
90
+ # 检查是否是 Java 版本问题
91
+ if java_cmd == 'java'
92
+ raise RuntimeError, "APKS 构建失败。可能是 Java 版本不兼容,bundletool 需要 Java 11+,请检查 JAVA_HOME 环境变量或安装正确的 Java 版本"
93
+ else
94
+ raise RuntimeError, "APKS 构建失败。使用的 Java 命令: #{java_cmd}"
95
+ end
98
96
  end
99
97
 
100
98
  # 解压 APKs 文件