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.
- checksums.yaml +4 -4
- data/lib/pindo/base/aeshelper.rb +23 -2
- data/lib/pindo/base/pindocontext.rb +259 -0
- data/lib/pindo/client/pgyer_feishu_oauth_cli.rb +343 -80
- data/lib/pindo/client/pgyerclient.rb +30 -20
- data/lib/pindo/command/android/autobuild.rb +52 -22
- data/lib/pindo/command/android/build.rb +27 -16
- data/lib/pindo/command/android/debug.rb +25 -15
- data/lib/pindo/command/dev/debug.rb +2 -51
- data/lib/pindo/command/dev/feishu.rb +19 -2
- data/lib/pindo/command/ios/adhoc.rb +2 -1
- data/lib/pindo/command/ios/autobuild.rb +35 -8
- data/lib/pindo/command/ios/debug.rb +2 -132
- data/lib/pindo/command/lib/lint.rb +24 -1
- data/lib/pindo/command/setup.rb +24 -4
- data/lib/pindo/command/unity/apk.rb +15 -0
- data/lib/pindo/command/unity/ipa.rb +16 -0
- data/lib/pindo/command.rb +13 -2
- data/lib/pindo/module/android/android_build_config_helper.rb +425 -0
- data/lib/pindo/module/android/apk_helper.rb +23 -25
- data/lib/pindo/module/android/base_helper.rb +572 -0
- data/lib/pindo/module/android/build_helper.rb +8 -318
- data/lib/pindo/module/android/gp_compliance_helper.rb +668 -0
- data/lib/pindo/module/android/gradle_helper.rb +746 -3
- data/lib/pindo/module/appselect.rb +18 -5
- data/lib/pindo/module/build/buildhelper.rb +120 -29
- data/lib/pindo/module/build/unityhelper.rb +675 -18
- data/lib/pindo/module/build/versionhelper.rb +146 -0
- data/lib/pindo/module/cert/certhelper.rb +33 -2
- data/lib/pindo/module/cert/xcodecerthelper.rb +3 -1
- data/lib/pindo/module/pgyer/pgyerhelper.rb +114 -31
- data/lib/pindo/module/xcode/xcodebuildconfig.rb +232 -0
- data/lib/pindo/module/xcode/xcodebuildhelper.rb +0 -1
- data/lib/pindo/version.rb +356 -86
- data/lib/pindo.rb +72 -3
- 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
|
-
|
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
|
-
# ---
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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[
|
63
|
-
|
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
|
-
"
|
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
|
-
|
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 文件
|