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.
- checksums.yaml +4 -4
- data/lib/pindo/base/git_handler.rb +120 -38
- data/lib/pindo/command/android/autobuild.rb +81 -40
- data/lib/pindo/command/appstore/adhocbuild.rb +1 -1
- data/lib/pindo/command/appstore/autobuild.rb +1 -1
- data/lib/pindo/command/appstore/autoresign.rb +1 -1
- data/lib/pindo/command/appstore/updateid.rb +229 -0
- data/lib/pindo/command/appstore.rb +1 -0
- data/lib/pindo/command/ios/autobuild.rb +70 -33
- data/lib/pindo/command/ios/podpush.rb +1 -1
- data/lib/pindo/command/jps/apptest.rb +2 -2
- data/lib/pindo/command/jps/bind.rb +1 -1
- data/lib/pindo/command/jps/media.rb +1 -1
- data/lib/pindo/command/jps/upload.rb +52 -22
- data/lib/pindo/command/unity/autobuild.rb +61 -44
- data/lib/pindo/command/utils/allcopyconfig.rb +144 -0
- data/lib/pindo/command/utils/copyconfig.rb +207 -0
- data/lib/pindo/command/utils/icon.rb +2 -2
- data/lib/pindo/command/utils/renewbundleid.rb +199 -0
- data/lib/pindo/command/utils/renewcert.rb +56 -54
- data/lib/pindo/command/utils.rb +3 -0
- data/lib/pindo/command/web/autobuild.rb +32 -26
- data/lib/pindo/config/build_info_manager.rb +1 -3
- data/lib/pindo/module/android/android_build_helper.rb +193 -33
- data/lib/pindo/module/android/android_config_helper.rb +305 -88
- data/lib/pindo/module/android/android_project_helper.rb +69 -14
- data/lib/pindo/module/android/android_res_helper.rb +349 -51
- data/lib/pindo/module/android/keystore_helper.rb +611 -295
- data/lib/pindo/module/android/workflow_gradle_injector.rb +702 -0
- data/lib/pindo/module/appselect.rb +4 -4
- data/lib/pindo/module/appstore/bundleid_helper.rb +204 -14
- data/lib/pindo/module/build/build_helper.rb +110 -10
- data/lib/pindo/module/build/git_repo_helper.rb +4 -4
- data/lib/pindo/module/cert/mode/base_cert_operator.rb +8 -6
- data/lib/pindo/module/pgyer/pgyerhelper.rb +105 -42
- data/lib/pindo/module/task/core/task_executor.rb +2 -0
- data/lib/pindo/module/task/model/build/android_build_dev_task.rb +64 -6
- data/lib/pindo/module/task/model/git/git_commit_task.rb +70 -54
- data/lib/pindo/module/task/model/git/git_tag_task.rb +13 -9
- data/lib/pindo/module/task/model/jps/jps_upload_task.rb +104 -1
- data/lib/pindo/module/task/model/unity/unity_export_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_update_task.rb +2 -1
- data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +2 -1
- data/lib/pindo/module/task/model/unity_task.rb +2 -1
- data/lib/pindo/module/task/task_manager.rb +8 -0
- data/lib/pindo/module/unity/unity_helper.rb +13 -10
- data/lib/pindo/module/unity/unity_proc_helper.rb +27 -2
- data/lib/pindo/module/xcode/applovin_xcode_helper.rb +4 -2
- data/lib/pindo/module/xcode/res/xcode_res_constant.rb +72 -0
- data/lib/pindo/module/xcode/xcode_build_config.rb +36 -17
- data/lib/pindo/module/xcode/xcode_build_helper.rb +180 -23
- data/lib/pindo/module/xcode/xcode_project_helper.rb +1 -1
- data/lib/pindo/module/xcode/xcode_res_helper.rb +32 -16
- data/lib/pindo/options/groups/build_options.rb +16 -5
- data/lib/pindo/options/groups/git_options.rb +7 -5
- data/lib/pindo/options/groups/unity_options.rb +11 -0
- data/lib/pindo/options/helpers/bundleid_selector.rb +25 -0
- data/lib/pindo/options/helpers/git_constants.rb +7 -6
- data/lib/pindo/version.rb +2 -2
- metadata +10 -5
|
@@ -4,6 +4,7 @@ require_relative 'gradle_helper'
|
|
|
4
4
|
require_relative 'gp_compliance_helper'
|
|
5
5
|
require_relative 'java_env_helper'
|
|
6
6
|
require_relative 'keystore_helper'
|
|
7
|
+
require_relative 'workflow_gradle_injector'
|
|
7
8
|
require 'fileutils'
|
|
8
9
|
|
|
9
10
|
module Pindo
|
|
@@ -19,7 +20,7 @@ module Pindo
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
def auto_build_apk(project_dir, debug = false, ignore_sub = false)
|
|
23
|
+
def auto_build_apk(project_dir, debug = false, ignore_sub = false, bundle_name: nil, workflow_name: nil)
|
|
23
24
|
raise ArgumentError, "项目目录不能为空" if project_dir.nil?
|
|
24
25
|
raise ArgumentError, "项目目录不存在" unless File.directory?(project_dir)
|
|
25
26
|
|
|
@@ -49,6 +50,7 @@ module Pindo
|
|
|
49
50
|
|
|
50
51
|
if File.directory?(unity_dir)
|
|
51
52
|
puts "找到 Unity 模块目录: Unity/"
|
|
53
|
+
validate_unity_libs_state!(unity_dir, stage: "导出前")
|
|
52
54
|
|
|
53
55
|
# 如果 Unity 子目录是完整的 Unity 导出工程,对其进行处理
|
|
54
56
|
if Pindo::AndroidProjectHelper.unity_android_project?(unity_dir)
|
|
@@ -72,6 +74,7 @@ module Pindo
|
|
|
72
74
|
raise RuntimeError, "编译 Unity 模块 SO 库失败"
|
|
73
75
|
end
|
|
74
76
|
copy_so_files(unity_dir, project_dir)
|
|
77
|
+
validate_unity_libs_state!(project_dir, stage: "导出后")
|
|
75
78
|
|
|
76
79
|
# SO 库拷贝完成后,重新配置主工程的 Java Home 和 Gradle 环境
|
|
77
80
|
puts "Unity SO库编译完成,切换到主工程编译环境"
|
|
@@ -94,26 +97,44 @@ module Pindo
|
|
|
94
97
|
# 检查并配置 local.properties(所有项目类型都需要)
|
|
95
98
|
Pindo::AndroidProjectHelper.check_main_local_properties(project_dir)
|
|
96
99
|
|
|
97
|
-
# 配置 Keystore
|
|
100
|
+
# 配置 Keystore 签名(从 JPS 获取,alias_name 为 Application ID)
|
|
98
101
|
build_type = debug ? "debug" : "release"
|
|
99
|
-
if
|
|
100
|
-
|
|
102
|
+
raise "bundle_name 不能为空,Keystore 签名需要 Application ID" if bundle_name.nil? || bundle_name.empty?
|
|
103
|
+
|
|
104
|
+
unless Pindo::KeystoreHelper.apply_keystore_config(project_dir, build_type, bundle_id: bundle_name)
|
|
105
|
+
raise RuntimeError, "Keystore 签名配置失败"
|
|
106
|
+
end
|
|
107
|
+
puts "✓ Android 签名配置成功"
|
|
108
|
+
|
|
109
|
+
if workflow_name && !workflow_name.to_s.empty?
|
|
110
|
+
injector = Pindo::Android::WorkflowGradleInjector.new
|
|
111
|
+
ctx = injector.prepare!(
|
|
112
|
+
project_dir: project_dir,
|
|
113
|
+
workflow_name: workflow_name,
|
|
114
|
+
enable_pad: true
|
|
115
|
+
)
|
|
116
|
+
apk_path = nil
|
|
117
|
+
begin
|
|
118
|
+
apk_path = build_apk(project_dir, debug, workflow_build_type: ctx[:workflow_build_type])
|
|
119
|
+
ensure
|
|
120
|
+
injector.cleanup!(ctx)
|
|
121
|
+
end
|
|
122
|
+
# JKS 仅在 universal.apk 已成功产出后删除;失败则保留,便于排查(Gradle 注入已在 ensure 中恢复)
|
|
123
|
+
Pindo::KeystoreHelper.cleanup_managed_signing_paths! if apk_path && File.exist?(apk_path.to_s)
|
|
124
|
+
Pindo::Android::WorkflowGradleInjector.remove_project_pindo_tmp_dir!(project_dir)
|
|
101
125
|
else
|
|
102
|
-
|
|
126
|
+
# 兼容旧行为:仍会永久写入 PAD 相关变更(如需临时恢复,请传 workflow_name 走注入管线)
|
|
127
|
+
setup_play_asset_delivery(project_dir)
|
|
128
|
+
apk_path = build_apk(project_dir, debug)
|
|
129
|
+
Pindo::KeystoreHelper.cleanup_managed_signing_paths! if apk_path && File.exist?(apk_path.to_s)
|
|
103
130
|
end
|
|
104
|
-
|
|
105
|
-
# 处理 Play Asset Delivery 配置(如果存在)
|
|
106
|
-
setup_play_asset_delivery(project_dir)
|
|
107
|
-
|
|
108
|
-
# 构建 APK
|
|
109
|
-
build_apk(project_dir, debug)
|
|
110
131
|
end
|
|
111
132
|
|
|
112
|
-
def build_apk(project_path, debug)
|
|
133
|
+
def build_apk(project_path, debug, workflow_build_type: nil)
|
|
113
134
|
raise ArgumentError, "项目路径不能为空" if project_path.nil? || project_path.empty?
|
|
114
135
|
|
|
115
136
|
# 构建 AAB 文件
|
|
116
|
-
unless build_aab(project_path, debug)
|
|
137
|
+
unless build_aab(project_path, debug, workflow_build_type: workflow_build_type)
|
|
117
138
|
raise RuntimeError, "AAB 构建失败"
|
|
118
139
|
end
|
|
119
140
|
|
|
@@ -121,7 +142,11 @@ module Pindo
|
|
|
121
142
|
main_module = Pindo::AndroidProjectHelper.get_main_module(project_path)
|
|
122
143
|
raise ArgumentError, "无法找到主模块" unless main_module
|
|
123
144
|
|
|
124
|
-
keystore_config = Pindo::KeystoreHelper.get_keystore_config_from_project(
|
|
145
|
+
keystore_config = Pindo::KeystoreHelper.get_keystore_config_from_project(
|
|
146
|
+
project_path,
|
|
147
|
+
debug,
|
|
148
|
+
workflow_build_type: workflow_build_type
|
|
149
|
+
)
|
|
125
150
|
raise ArgumentError, "无法从 build.gradle 中获取 keystore 信息" unless keystore_config
|
|
126
151
|
|
|
127
152
|
build_tools = Pindo::AndroidProjectHelper.get_build_tools
|
|
@@ -137,7 +162,11 @@ module Pindo
|
|
|
137
162
|
end
|
|
138
163
|
|
|
139
164
|
# 准备输出路径
|
|
140
|
-
build_type =
|
|
165
|
+
build_type = if workflow_build_type && !workflow_build_type.to_s.empty?
|
|
166
|
+
workflow_build_type.to_s
|
|
167
|
+
else
|
|
168
|
+
debug ? 'debug' : 'release'
|
|
169
|
+
end
|
|
141
170
|
main_module_name = File.basename(main_module)
|
|
142
171
|
output_dir = File.join(project_path, "build/apks")
|
|
143
172
|
|
|
@@ -181,14 +210,37 @@ module Pindo
|
|
|
181
210
|
# --- END ---
|
|
182
211
|
|
|
183
212
|
# puts "解析 keystore 配置"
|
|
184
|
-
|
|
185
|
-
#
|
|
186
|
-
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
213
|
+
# 与 Gradle 对 storeFile 的生效顺序一致:常见写法为
|
|
214
|
+
# storeFile file(System.getenv("RELEASE_KEYSTORE_PATH") ?: "signing/gxdebug.jks")
|
|
215
|
+
# apply_keystore_config 已在当前进程设置 RELEASE_*,Gradle 打 AAB 时走 ENV 指向的真实 jks;
|
|
216
|
+
# get_keystore_config_from_project 若只解析到 ?: 右侧占位路径,会与 AAB 实际签名不一致且文件可能不存在。
|
|
217
|
+
# 故:当 RELEASE_KEYSTORE_PATH 展开后文件存在时,bundletool 必须使用同一套 RELEASE_*(非「失败回退」)。
|
|
218
|
+
kh = Pindo::KeystoreHelper
|
|
219
|
+
env_ks = ENV[kh::ENV_RELEASE_KEYSTORE_PATH]
|
|
220
|
+
env_ks_abs = env_ks && !env_ks.to_s.empty? ? File.expand_path(env_ks) : nil
|
|
221
|
+
gradle_ks = keystore_config[:store_file]
|
|
222
|
+
|
|
223
|
+
use_release_env = env_ks_abs && File.exist?(env_ks_abs)
|
|
224
|
+
if use_release_env
|
|
225
|
+
ks = env_ks_abs
|
|
226
|
+
ks_pass = ENV[kh::ENV_RELEASE_KEYSTORE_PASSWORD] || keystore_config[:store_password]
|
|
227
|
+
key_alias = ENV[kh::ENV_RELEASE_KEY_ALIAS] || keystore_config[:key_alias]
|
|
228
|
+
key_pass = ENV[kh::ENV_RELEASE_KEY_PASSWORD] || keystore_config[:key_password]
|
|
229
|
+
else
|
|
230
|
+
ks = gradle_ks || env_ks
|
|
231
|
+
ks = File.expand_path(ks.to_s) if ks && !ks.to_s.empty?
|
|
232
|
+
ks_pass = keystore_config[:store_password] || ENV[kh::ENV_RELEASE_KEYSTORE_PASSWORD]
|
|
233
|
+
key_alias = keystore_config[:key_alias] || ENV[kh::ENV_RELEASE_KEY_ALIAS]
|
|
234
|
+
key_pass = keystore_config[:key_password] || ENV[kh::ENV_RELEASE_KEY_PASSWORD]
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
ks_display = ks && !ks.to_s.empty? ? File.expand_path(ks.to_s) : ks.to_s
|
|
238
|
+
# puts "[bundletool] universal.apk 实际使用的签名 keystore: #{ks_display}"
|
|
239
|
+
# if workflow_build_type && !workflow_build_type.to_s.empty?
|
|
240
|
+
# puts "[bundletool] workflow buildType: #{workflow_build_type}"
|
|
241
|
+
# end
|
|
242
|
+
# puts "[bundletool] 签名来源: #{use_release_env ? "RELEASE_KEYSTORE_PATH(文件存在,与 Gradle 打 AAB 一致)" : "build.gradle 解析 / ENV 兜底(非 RELEASE 路径或文件不存在时)"}"
|
|
243
|
+
# puts "[bundletool] keyAlias: #{key_alias.inspect}(口令不落日志)"
|
|
192
244
|
|
|
193
245
|
# 构建 APK
|
|
194
246
|
# 确保使用正确的 Java 版本 (Java 11+)
|
|
@@ -217,8 +269,12 @@ module Pindo
|
|
|
217
269
|
raise RuntimeError, "AAB 文件不存在: #{paths[:bundle]}"
|
|
218
270
|
end
|
|
219
271
|
|
|
272
|
+
if ks.nil? || ks.to_s.empty?
|
|
273
|
+
raise RuntimeError, "Keystore 路径为空:无法从 build.gradle 解析签名配置,且未从环境变量获取到 #{Pindo::KeystoreHelper::ENV_RELEASE_KEYSTORE_PATH}"
|
|
274
|
+
end
|
|
275
|
+
|
|
220
276
|
unless File.exist?(ks)
|
|
221
|
-
raise RuntimeError, "Keystore
|
|
277
|
+
raise RuntimeError, "Keystore 文件不存在: #{ks}"
|
|
222
278
|
end
|
|
223
279
|
|
|
224
280
|
unless system(*bundletool_cmd)
|
|
@@ -243,12 +299,85 @@ module Pindo
|
|
|
243
299
|
paths[:universal_apk]
|
|
244
300
|
end
|
|
245
301
|
|
|
246
|
-
def build_aab(project_path, debug)
|
|
302
|
+
def build_aab(project_path, debug, workflow_build_type: nil)
|
|
247
303
|
# 使用子 Shell 切换目录执行,避免影响主进程当前目录 (Thread Safe)
|
|
248
|
-
|
|
304
|
+
# --no-daemon:签名依赖当前进程注入的 RELEASE_* 环境变量;已存在的 Gradle Daemon
|
|
305
|
+
# 继承的是其首次启动时的环境,会看不到 pindo 刚设置的变量,从而回退到 build.gradle 里 ?: 的本地 jks。
|
|
306
|
+
main_module = Pindo::AndroidProjectHelper.get_main_module(project_path)
|
|
307
|
+
module_name = main_module ? File.basename(main_module) : nil
|
|
308
|
+
prefix = module_name && !module_name.empty? ? ":#{module_name}:" : ""
|
|
309
|
+
|
|
310
|
+
task_name = if workflow_build_type && !workflow_build_type.to_s.empty?
|
|
311
|
+
"bundle#{workflow_build_type.to_s[0].upcase}#{workflow_build_type.to_s[1..]}"
|
|
312
|
+
else
|
|
313
|
+
debug ? "bundleDebug" : "bundleRelease"
|
|
314
|
+
end
|
|
315
|
+
|
|
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
|
|
321
|
+
|
|
322
|
+
gradle_clean_resilient!(project_path) unless skip_clean
|
|
323
|
+
|
|
324
|
+
cmd = "cd \"#{project_path}\" && ./gradlew --no-daemon #{bundle_task}"
|
|
249
325
|
system(cmd)
|
|
250
326
|
end
|
|
251
327
|
|
|
328
|
+
# clean 失败(占用、.DS_Store 竞态等)时:停 Daemon → 再删 .DS_Store → 物理删除各模块 build/,与 Gradle clean 产物一致,不中断后续 bundle
|
|
329
|
+
private def gradle_clean_resilient!(project_path)
|
|
330
|
+
prune_ds_store_before_gradle_clean!(project_path)
|
|
331
|
+
cmd = %(cd "#{project_path}" && ./gradlew --no-daemon clean)
|
|
332
|
+
return if system(cmd)
|
|
333
|
+
|
|
334
|
+
puts ' ⚠ Gradle clean 失败,正在自动恢复:--stop、清理 .DS_Store、删除各模块 build/ ...'
|
|
335
|
+
system(%(cd "#{project_path}" && ./gradlew --stop), out: File::NULL, err: File::NULL)
|
|
336
|
+
sleep 0.3
|
|
337
|
+
prune_ds_store_before_gradle_clean!(project_path)
|
|
338
|
+
remove_android_module_build_dirs!(project_path)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# 删除 Gradle 模块产物目录(与 clean 目标一致:根 build、一级子模块/build、常见二级子模块/build)
|
|
342
|
+
private def remove_android_module_build_dirs!(project_path)
|
|
343
|
+
return unless project_path && File.directory?(project_path)
|
|
344
|
+
|
|
345
|
+
paths = []
|
|
346
|
+
root_build = File.join(project_path, 'build')
|
|
347
|
+
paths << root_build if File.directory?(root_build)
|
|
348
|
+
|
|
349
|
+
Dir.each_child(project_path) do |name|
|
|
350
|
+
next if name.start_with?('.')
|
|
351
|
+
|
|
352
|
+
mod_build = File.join(project_path, name, 'build')
|
|
353
|
+
paths << mod_build if File.directory?(mod_build)
|
|
354
|
+
|
|
355
|
+
sub = File.join(project_path, name)
|
|
356
|
+
next unless File.directory?(sub)
|
|
357
|
+
|
|
358
|
+
Dir.each_child(sub) do |subname|
|
|
359
|
+
next if subname.start_with?('.')
|
|
360
|
+
|
|
361
|
+
nested = File.join(sub, subname, 'build')
|
|
362
|
+
paths << nested if File.directory?(nested)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
paths.uniq.each do |p|
|
|
367
|
+
FileUtils.rm_rf(p)
|
|
368
|
+
end
|
|
369
|
+
rescue StandardError => e
|
|
370
|
+
puts " ⚠ 物理删除 build 目录时出现异常(将继续尝试 bundle): #{e.message}"
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# macOS 在 clean 遍历删除 build 目录时 Finder 可能写入 .DS_Store,Gradle 会报 Unable to delete / New files were found
|
|
374
|
+
private def prune_ds_store_before_gradle_clean!(project_path)
|
|
375
|
+
return unless project_path && File.directory?(project_path)
|
|
376
|
+
|
|
377
|
+
system('find', project_path, '-name', '.DS_Store', '-type', 'f', '-delete',
|
|
378
|
+
out: File::NULL, err: File::NULL)
|
|
379
|
+
end
|
|
380
|
+
|
|
252
381
|
def build_so_library(project_path)
|
|
253
382
|
# 编译so库 (Thread Safe)
|
|
254
383
|
cmd = "cd \"#{project_path}\" && ./gradlew unityLibrary:BuildIl2CppTask"
|
|
@@ -287,24 +416,55 @@ module Pindo
|
|
|
287
416
|
|
|
288
417
|
# 递归合并拷贝:将源目录的内容合并到目标目录
|
|
289
418
|
def copy_merge_recursive(src_dir, dst_dir)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
next if File.basename(src_item) == '.' || File.basename(src_item) == '..'
|
|
294
|
-
|
|
295
|
-
dst_item = File.join(dst_dir, File.basename(src_item))
|
|
419
|
+
Dir.each_child(src_dir) do |name|
|
|
420
|
+
src_item = File.join(src_dir, name)
|
|
421
|
+
dst_item = File.join(dst_dir, name)
|
|
296
422
|
|
|
297
423
|
if File.directory?(src_item)
|
|
298
424
|
# 如果是目录,确保目标子目录存在,然后递归拷贝
|
|
299
425
|
FileUtils.mkdir_p(dst_item)
|
|
300
426
|
copy_merge_recursive(src_item, dst_item)
|
|
301
427
|
else
|
|
302
|
-
#
|
|
428
|
+
# Unity/EDM 常在 libs 下放置指向解析缓存的符号链接;BuildIl2CppTask 后可能出现断裂链接,
|
|
429
|
+
# FileUtils.cp 跟随链接会导致 No such file or directory。
|
|
430
|
+
unless File.exist?(src_item)
|
|
431
|
+
puts " ⚠ 跳过缺失或断裂的引用: #{name}"
|
|
432
|
+
next
|
|
433
|
+
end
|
|
434
|
+
|
|
303
435
|
FileUtils.cp(src_item, dst_item)
|
|
304
436
|
end
|
|
305
437
|
end
|
|
306
438
|
end
|
|
307
439
|
|
|
440
|
+
def validate_unity_libs_state!(android_root, stage:)
|
|
441
|
+
# 某些项目会将 unityLibrary 作为缓存/中间产物纳入仓库,但 libs 下的 .aar -> .srcaar
|
|
442
|
+
# 符号链接目标是由 EDM4U/导出过程生成,初次拉取代码时可能为断链。
|
|
443
|
+
# 默认仍严格失败;如确有需要,可通过环境变量临时跳过此校验继续构建。
|
|
444
|
+
return if ENV["PINDO_SKIP_UNITY_LIBS_VALIDATE"] == "1"
|
|
445
|
+
|
|
446
|
+
libs_dir = File.join(android_root, "unityLibrary", "libs")
|
|
447
|
+
return unless File.directory?(libs_dir)
|
|
448
|
+
|
|
449
|
+
broken_links = []
|
|
450
|
+
Dir.each_child(libs_dir) do |name|
|
|
451
|
+
file_path = File.join(libs_dir, name)
|
|
452
|
+
next unless File.symlink?(file_path)
|
|
453
|
+
next if File.exist?(file_path)
|
|
454
|
+
|
|
455
|
+
broken_links << "#{name} -> #{File.readlink(file_path)}"
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
return if broken_links.empty?
|
|
459
|
+
|
|
460
|
+
raise RuntimeError, <<~MSG
|
|
461
|
+
Unity 依赖校验失败(#{stage}):发现失效的符号链接,请先在 Unity 中执行 EDM4U Resolve 后重新导出。
|
|
462
|
+
扫描目录: #{libs_dir}
|
|
463
|
+
失效条目:
|
|
464
|
+
- #{broken_links.join("\n- ")}
|
|
465
|
+
MSG
|
|
466
|
+
end
|
|
467
|
+
|
|
308
468
|
# 设置 Play Asset Delivery:直接扫描导出工程中的资源目录,按照 Android 原生方式创建 .androidpack 目录
|
|
309
469
|
# 仅适用于 Unity 项目,对于原生 Android 项目会静默跳过
|
|
310
470
|
def setup_play_asset_delivery(project_dir)
|