pindo 5.13.7 → 5.13.9
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/command/android/autobuild.rb +38 -7
- data/lib/pindo/command/appstore/adhocbuild.rb +52 -6
- data/lib/pindo/command/appstore/autobuild.rb +51 -5
- data/lib/pindo/command/appstore/autoresign.rb +2 -2
- data/lib/pindo/command/ios/autobuild.rb +62 -16
- data/lib/pindo/command/jps/upload.rb +1 -1
- data/lib/pindo/command/unity/autobuild.rb +47 -10
- data/lib/pindo/command/web/autobuild.rb +44 -14
- data/lib/pindo/module/task/model/git_tag_task.rb +1 -1
- data/lib/pindo/module/task/model/{jps_upload_task.rb → jps/jps_upload_task.rb} +2 -2
- data/lib/pindo/module/task/model/{ipa_local_resign_task.rb → resign/ipa_local_resign_task.rb} +2 -2
- data/lib/pindo/module/task/model/{jps_resign_task.rb → resign/jps_resign_task.rb} +2 -2
- data/lib/pindo/module/task/model/unity/unity_config_task.rb +107 -0
- data/lib/pindo/module/task/model/{unity_export_task.rb → unity/unity_export_task.rb} +71 -74
- data/lib/pindo/module/task/model/unity/unity_update_task.rb +94 -0
- data/lib/pindo/module/task/model/unity/unity_yoo_asset_task.rb +155 -0
- data/lib/pindo/module/task/model/unity_task.rb +113 -0
- data/lib/pindo/module/task/task_manager.rb +9 -1
- data/lib/pindo/module/unity/unity_command_helper.rb +188 -0
- data/lib/pindo/module/unity/unity_env_helper.rb +208 -0
- data/lib/pindo/module/unity/unity_helper.rb +189 -746
- data/lib/pindo/module/unity/unity_proc_helper.rb +390 -0
- data/lib/pindo/version.rb +1 -1
- metadata +12 -5
|
@@ -3,361 +3,87 @@ require 'json'
|
|
|
3
3
|
require 'singleton'
|
|
4
4
|
require 'pindo/base/funlog'
|
|
5
5
|
require 'pindo/config/pindoconfig'
|
|
6
|
+
require 'pindo/module/unity/unity_env_helper'
|
|
7
|
+
require 'pindo/module/unity/unity_proc_helper'
|
|
8
|
+
require 'pindo/module/unity/unity_command_helper'
|
|
6
9
|
|
|
7
10
|
# 定义Informative异常类
|
|
8
11
|
class Informative < StandardError; end
|
|
9
12
|
|
|
10
13
|
module Pindo
|
|
11
|
-
module
|
|
14
|
+
module Unity
|
|
12
15
|
class UnityHelper
|
|
13
16
|
include Singleton
|
|
14
17
|
|
|
15
|
-
UNITY_MAC_PATHS = [
|
|
16
|
-
"/Applications/Unity/Unity.app/Contents/MacOS/Unity",
|
|
17
|
-
"/Applications/Unity/Hub/Editor/*/Unity.app/Contents/MacOS/Unity",
|
|
18
|
-
"/Applications/Unity/*/Unity.app/Contents/MacOS/Unity"
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
UNITY_WINDOWS_PATHS = [
|
|
22
|
-
"C:/Program Files/Unity/Editor/Unity.exe",
|
|
23
|
-
"C:/Program Files/Unity/Hub/Editor/*/Unity.exe",
|
|
24
|
-
"C:/Program Files/Unity/*/Editor/Unity.exe"
|
|
25
|
-
]
|
|
26
|
-
|
|
27
18
|
class << self
|
|
28
19
|
def share_instance
|
|
29
20
|
instance
|
|
30
21
|
end
|
|
31
22
|
end
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
unity_major_version = project_unity_version.split('.')[0..1].join('.')
|
|
40
|
-
paths = case RUBY_PLATFORM
|
|
41
|
-
when /darwin/
|
|
42
|
-
UNITY_MAC_PATHS
|
|
43
|
-
when /mswin|mingw|windows/
|
|
44
|
-
UNITY_WINDOWS_PATHS
|
|
45
|
-
else
|
|
46
|
-
raise "Unsupported platform: #{RUBY_PLATFORM}"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
unity_versions = []
|
|
50
|
-
|
|
51
|
-
paths.each do |path|
|
|
52
|
-
if path.include?("*")
|
|
53
|
-
Dir.glob(path).each do |expanded_path|
|
|
54
|
-
version = extract_version_from_path(expanded_path)
|
|
55
|
-
if version
|
|
56
|
-
major_version = version.split('.')[0..1].join('.')
|
|
57
|
-
unity_versions << {
|
|
58
|
-
path: expanded_path,
|
|
59
|
-
version: version,
|
|
60
|
-
major_version: major_version
|
|
61
|
-
}
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
elsif File.exist?(path)
|
|
65
|
-
version = extract_version_from_path(path)
|
|
66
|
-
if version
|
|
67
|
-
major_version = version.split('.')[0..1].join('.')
|
|
68
|
-
unity_versions << {
|
|
69
|
-
path: path,
|
|
70
|
-
version: version,
|
|
71
|
-
major_version: major_version
|
|
72
|
-
}
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
if unity_versions.empty?
|
|
78
|
-
puts "调试信息: 搜索的Unity路径:"
|
|
79
|
-
paths.each do |path|
|
|
80
|
-
puts " - #{path}"
|
|
81
|
-
if path.include?("*")
|
|
82
|
-
Dir.glob(path).each do |expanded_path|
|
|
83
|
-
puts " 展开: #{expanded_path}"
|
|
84
|
-
end
|
|
85
|
-
elsif File.exist?(path)
|
|
86
|
-
puts " 存在: #{path}"
|
|
87
|
-
else
|
|
88
|
-
puts " 不存在: #{path}"
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
raise Informative, "未找到任何Unity版本,请检查Unity是否正确安装"
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
select_unity_versions = unity_versions.select { |v| v[:version] == project_unity_version } || []
|
|
96
|
-
if !select_unity_versions.nil? && !select_unity_versions.empty? && select_unity_versions.length >= 1
|
|
97
|
-
return select_unity_versions.first[:path]
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
unity_versions.sort_by! { |v| v[:major_version] }
|
|
101
|
-
select_unity_versions = unity_versions.select { |v| v[:major_version] == unity_major_version } if unity_major_version
|
|
102
|
-
if select_unity_versions.nil? || select_unity_versions.empty?
|
|
103
|
-
if force_change_version
|
|
104
|
-
puts "强制使用最新版本: #{unity_versions.last[:version]}"
|
|
105
|
-
return unity_versions.last[:path]
|
|
106
|
-
else
|
|
107
|
-
puts "调试信息: 项目Unity版本: #{project_unity_version}"
|
|
108
|
-
puts "调试信息: 可用的Unity版本:"
|
|
109
|
-
unity_versions.each do |v|
|
|
110
|
-
puts " - #{v[:version]} (#{v[:major_version]})"
|
|
111
|
-
end
|
|
112
|
-
raise Informative, "未找到匹配的Unity版本 #{project_unity_version},可用的版本: #{unity_versions.map { |v| v[:version] }.join(', ')}"
|
|
113
|
-
end
|
|
114
|
-
else
|
|
115
|
-
return select_unity_versions.first[:path]
|
|
116
|
-
end
|
|
117
|
-
|
|
24
|
+
# 委托给 UnityEnvHelper 的类方法
|
|
25
|
+
def find_unity_path(project_unity_version: nil, force_change_version: false)
|
|
26
|
+
UnityEnvHelper.find_unity_path(
|
|
27
|
+
project_unity_version: project_unity_version,
|
|
28
|
+
force_change_version: force_change_version
|
|
29
|
+
)
|
|
118
30
|
end
|
|
119
31
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
# macOS路径格式: /Applications/Unity/Hub/Editor/2021.3.45f1/Unity.app/Contents/MacOS/Unity
|
|
124
|
-
# macOS路径格式(变体): /Applications/Unity/Hub/Editor/2021.3.45f1c1/Unity.app/Contents/MacOS/Unity
|
|
125
|
-
# macOS路径格式(旧版): /Applications/Unity/Unity.app/Contents/MacOS/Unity
|
|
126
|
-
# Windows路径格式: C:/Program Files/Unity/Hub/Editor/2021.3.45f1/Editor/Unity.exe
|
|
127
|
-
# Windows路径格式(变体): C:/Program Files/Unity/Hub/Editor/2021.3.45f1c1/Editor/Unity.exe
|
|
128
|
-
# Windows路径格式(旧版): C:/Program Files/Unity/Editor/Unity.exe
|
|
129
|
-
|
|
130
|
-
# 尝试匹配 macOS Hub 路径格式
|
|
131
|
-
if match = path.match(/Editor\/([\d.]+[a-zA-Z]\d+(?:c\d+)?)\//)
|
|
132
|
-
return match[1]
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# 尝试匹配 Windows Hub 路径格式
|
|
136
|
-
if match = path.match(/([\d.]+[a-zA-Z]\d+(?:c\d+)?)\/Editor\//)
|
|
137
|
-
return match[1]
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
# 尝试匹配 macOS 旧版路径格式 (从Info.plist提取版本)
|
|
141
|
-
if match = path.match(/Unity\.app\/Contents\/MacOS\/Unity$/)
|
|
142
|
-
info_plist_path = File.join(File.dirname(File.dirname(path)), "Info.plist")
|
|
143
|
-
if File.exist?(info_plist_path)
|
|
144
|
-
begin
|
|
145
|
-
content = File.read(info_plist_path)
|
|
146
|
-
if content =~ /<key>CFBundleVersion<\/key>\s*<string>([^<]+)<\/string>/
|
|
147
|
-
return $1.strip
|
|
148
|
-
elsif content =~ /<key>CFBundleShortVersionString<\/key>\s*<string>Unity version ([^<]+)<\/string>/
|
|
149
|
-
return $1.strip
|
|
150
|
-
end
|
|
151
|
-
rescue => e
|
|
152
|
-
puts "警告: 无法读取Info.plist文件: #{e.message}"
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# 尝试匹配 Windows 旧版路径格式
|
|
158
|
-
if match = path.match(/Unity\.exe$/)
|
|
159
|
-
# 对于旧版Unity,尝试从父目录获取版本信息
|
|
160
|
-
parent_dir = File.dirname(path)
|
|
161
|
-
if File.basename(parent_dir) =~ /^([\d.]+[a-zA-Z]\d+(?:c\d+)?)$/
|
|
162
|
-
return $1
|
|
163
|
-
end
|
|
164
|
-
end
|
|
32
|
+
def get_unity_version(project_path)
|
|
33
|
+
UnityEnvHelper.get_unity_version(project_path)
|
|
34
|
+
end
|
|
165
35
|
|
|
166
|
-
|
|
36
|
+
def unity_project?(project_path)
|
|
37
|
+
UnityEnvHelper.unity_project?(project_path)
|
|
167
38
|
end
|
|
168
39
|
|
|
169
|
-
|
|
40
|
+
def version_less_than?(v1, v2)
|
|
41
|
+
UnityEnvHelper.version_less_than?(v1, v2)
|
|
42
|
+
end
|
|
170
43
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
end
|
|
44
|
+
# ============================================
|
|
45
|
+
# Unity 构建相关功能
|
|
46
|
+
# ============================================
|
|
175
47
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
# 'normal' - 显示错误、警告和关键进度
|
|
180
|
-
# 'verbose' - 显示所有输出
|
|
48
|
+
# 检查 GoodUnityBuild 版本是否满足要求
|
|
49
|
+
def check_goodunitybuild_version(unity_exe_full_path, project_path)
|
|
50
|
+
Funlog.instance.fancyinfo_start("检查 GoodUnityBuild 版本")
|
|
181
51
|
|
|
182
|
-
#
|
|
183
|
-
|
|
184
|
-
raise Informative, "Unity项目路径不存在: #{project_path}"
|
|
185
|
-
end
|
|
52
|
+
# 检查是否有Unity进程在运行
|
|
53
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
186
54
|
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
55
|
+
# 执行 Unity 命令获取库版本
|
|
56
|
+
result = UnityCommandHelper.execute_unity_command(
|
|
57
|
+
unity_exe_full_path,
|
|
58
|
+
project_path,
|
|
59
|
+
method: 'GoodUnityBuild.BuildManager.PrintLibraryVersion',
|
|
60
|
+
additional_args: {}
|
|
61
|
+
)
|
|
192
62
|
|
|
193
|
-
|
|
194
|
-
platform = additional_args[:platform]
|
|
63
|
+
return unless result[:success]
|
|
195
64
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
"-projectPath",
|
|
201
|
-
project_path.to_s,
|
|
202
|
-
"-executeMethod",
|
|
203
|
-
"GoodUnityBuild.BuildManager.BatchBuild"
|
|
65
|
+
# 尝试多种模式匹配版本号
|
|
66
|
+
patterns = [
|
|
67
|
+
/GoodUnityBuild Version:\s*(\d+\.\d+\.\d+)/i,
|
|
68
|
+
/\[GoodUnityBuild\]\s+Version\s+(\d+\.\d+\.\d+)/i
|
|
204
69
|
]
|
|
205
70
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
71
|
+
library_version = nil
|
|
72
|
+
patterns.each do |pattern|
|
|
73
|
+
if match = result[:stdout].match(pattern)
|
|
74
|
+
library_version = match[1]
|
|
75
|
+
break
|
|
76
|
+
end
|
|
210
77
|
end
|
|
211
78
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
puts ""
|
|
220
|
-
|
|
221
|
-
# 使用更智能的进度检测机制
|
|
222
|
-
progress_thread = nil
|
|
223
|
-
start_time = Time.now
|
|
224
|
-
last_output_time = Time.now
|
|
225
|
-
|
|
226
|
-
begin
|
|
227
|
-
# 使用 Open3.popen3 来实时监控输出
|
|
228
|
-
Open3.popen3(*cmd_args) do |stdin, stdout, stderr, wait_thr|
|
|
229
|
-
stdin.close
|
|
230
|
-
|
|
231
|
-
# 启动进度显示线程
|
|
232
|
-
progress_thread = Thread.new do
|
|
233
|
-
dots = 0
|
|
234
|
-
while wait_thr.alive?
|
|
235
|
-
sleep(2)
|
|
236
|
-
dots = (dots + 1) % 4
|
|
237
|
-
elapsed = (Time.now - start_time).to_i
|
|
238
|
-
print "\r\e[33mUnity 构建中#{'.' * dots}#{' ' * (3 - dots)} (已用时: #{elapsed}秒)\e[0m"
|
|
239
|
-
$stdout.flush
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# 实时读取输出
|
|
244
|
-
stdout_buffer = ""
|
|
245
|
-
stderr_buffer = ""
|
|
246
|
-
|
|
247
|
-
# 定义错误关键词模式(优化正则,避免重复)
|
|
248
|
-
error_pattern = /error|exception|failed|Build completed with a result of 'Failed'/i
|
|
249
|
-
warning_pattern = /warning|warn/i
|
|
250
|
-
success_pattern = /Build completed successfully|Exiting batchmode successfully/i
|
|
251
|
-
|
|
252
|
-
# 使用非阻塞方式读取输出
|
|
253
|
-
while wait_thr.alive?
|
|
254
|
-
# 检查是否有输出可读
|
|
255
|
-
ready_streams = IO.select([stdout, stderr], nil, nil, 1)
|
|
256
|
-
|
|
257
|
-
if ready_streams
|
|
258
|
-
ready_streams[0].each do |stream|
|
|
259
|
-
if line = stream.gets
|
|
260
|
-
# 记录输出
|
|
261
|
-
if stream == stdout
|
|
262
|
-
stdout_buffer += line
|
|
263
|
-
else
|
|
264
|
-
stderr_buffer += line
|
|
265
|
-
end
|
|
266
|
-
last_output_time = Time.now
|
|
267
|
-
|
|
268
|
-
# 根据调试级别和内容类型显示输出
|
|
269
|
-
case debug_level
|
|
270
|
-
when 'verbose'
|
|
271
|
-
# 详细模式:显示所有输出
|
|
272
|
-
puts line
|
|
273
|
-
when 'quiet'
|
|
274
|
-
# 安静模式:只显示错误
|
|
275
|
-
if line.match?(error_pattern)
|
|
276
|
-
puts "\e[31m[错误] #{line.strip}\e[0m"
|
|
277
|
-
end
|
|
278
|
-
else # 'normal'
|
|
279
|
-
# 正常模式:显示错误、警告和关键进度
|
|
280
|
-
if line.match?(error_pattern)
|
|
281
|
-
puts "\n\e[31m[错误] #{line.strip}\e[0m"
|
|
282
|
-
elsif line.match?(warning_pattern)
|
|
283
|
-
puts "\n\e[33m[警告] #{line.strip}\e[0m"
|
|
284
|
-
elsif line.match?(success_pattern)
|
|
285
|
-
puts "\n\e[32m[成功] #{line.strip}\e[0m"
|
|
286
|
-
elsif line.match?(/\d+%/) || line.match?(/Building|Compiling|Processing/i)
|
|
287
|
-
# 显示进度相关信息
|
|
288
|
-
print "\r\e[36m[进度] #{line.strip}\e[0m"
|
|
289
|
-
$stdout.flush
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
# 读取剩余输出
|
|
299
|
-
stdout_buffer += stdout.read
|
|
300
|
-
stderr_buffer += stderr.read
|
|
301
|
-
|
|
302
|
-
# 停止进度显示线程
|
|
303
|
-
progress_thread.kill if progress_thread
|
|
304
|
-
|
|
305
|
-
# 检查构建是否真的成功
|
|
306
|
-
build_success = wait_thr.value.success?
|
|
307
|
-
|
|
308
|
-
# 检查是否有构建错误的关键词
|
|
309
|
-
if stdout_buffer.match?(/Build completed with a result of 'Failed'|Build completed with a result of 'Cancelled'|BuildPlayerWindow\+BuildMethod\+Invoke|error|Error|ERROR|exception|Exception|EXCEPTION|failed|Failed|FAILED/)
|
|
310
|
-
build_success = false
|
|
311
|
-
# puts "\n\e[31m检测到构建错误信息,构建可能失败\e[0m"
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
if build_success
|
|
315
|
-
print "\r\e[32mUnity 构建完成!\e[0m\n"
|
|
316
|
-
# 构建完成后检查并清理可能的 Unity 进程残留
|
|
317
|
-
cleanup_unity_processes_after_build(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
318
|
-
else
|
|
319
|
-
print "\r\e[31mUnity 构建失败!\e[0m\n"
|
|
320
|
-
puts "\e[31m构建输出:\e[0m"
|
|
321
|
-
puts stdout_buffer if !stdout_buffer.empty?
|
|
322
|
-
puts "\e[31m错误输出:\e[0m"
|
|
323
|
-
puts stderr_buffer if !stderr_buffer.empty?
|
|
324
|
-
# 构建失败时也清理可能的进程残留
|
|
325
|
-
cleanup_unity_processes_after_build(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
# 返回结果
|
|
329
|
-
{
|
|
330
|
-
success: build_success,
|
|
331
|
-
stdout: stdout_buffer,
|
|
332
|
-
stderr: stderr_buffer,
|
|
333
|
-
exit_status: wait_thr.value.exitstatus,
|
|
334
|
-
unity_version: extract_version_from_path(unity_exe_full_path)
|
|
335
|
-
}
|
|
79
|
+
# 从文件读取作为备用方案
|
|
80
|
+
if library_version.nil?
|
|
81
|
+
version_file = File.join(project_path, "Logs", "GoodUnityBuild_version.txt")
|
|
82
|
+
if File.exist?(version_file)
|
|
83
|
+
content = File.read(version_file).strip
|
|
84
|
+
library_version = content[/(\d+\.\d+\.\d+)/, 1]
|
|
336
85
|
end
|
|
337
|
-
rescue => e
|
|
338
|
-
# 停止进度显示线程
|
|
339
|
-
progress_thread.kill if progress_thread
|
|
340
|
-
print "\r\e[31mUnity 构建失败!\e[0m\n"
|
|
341
|
-
raise e
|
|
342
86
|
end
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
# 比较版本号 (语义化版本比较)
|
|
346
|
-
# 返回: true 如果 v1 < v2, false 否则
|
|
347
|
-
def version_less_than?(v1, v2)
|
|
348
|
-
return false if v1.nil? || v2.nil?
|
|
349
|
-
|
|
350
|
-
Gem::Version.new(v1) < Gem::Version.new(v2)
|
|
351
|
-
rescue ArgumentError
|
|
352
|
-
# 版本格式无效时的降级处理
|
|
353
|
-
v1.to_s < v2.to_s
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# 检查 GoodUnityBuild 版本是否满足要求
|
|
357
|
-
def check_goodunitybuild_version(unity_exe_full_path, project_path)
|
|
358
|
-
Funlog.instance.fancyinfo_start("检查 GoodUnityBuild 版本")
|
|
359
|
-
|
|
360
|
-
library_version = get_library_version(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
361
87
|
|
|
362
88
|
return unless library_version
|
|
363
89
|
|
|
@@ -384,51 +110,10 @@ module Pindo
|
|
|
384
110
|
Funlog.warning("GoodUnityBuild 库版本检查失败: #{e.message}")
|
|
385
111
|
end
|
|
386
112
|
|
|
387
|
-
|
|
388
|
-
def get_library_version(unity_exe_full_path:, project_path:)
|
|
389
|
-
cmd_args = [
|
|
390
|
-
unity_exe_full_path,
|
|
391
|
-
"-batchmode",
|
|
392
|
-
"-quit",
|
|
393
|
-
"-projectPath",
|
|
394
|
-
project_path.to_s,
|
|
395
|
-
"-executeMethod",
|
|
396
|
-
"GoodUnityBuild.BuildManager.PrintLibraryVersion"
|
|
397
|
-
]
|
|
398
|
-
|
|
399
|
-
stdout_str, _, _ = Open3.capture3(*cmd_args)
|
|
400
|
-
|
|
401
|
-
# 尝试多种模式匹配版本号
|
|
402
|
-
patterns = [
|
|
403
|
-
/GoodUnityBuild Version:\s*(\d+\.\d+\.\d+)/i,
|
|
404
|
-
/\[GoodUnityBuild\]\s+Version\s+(\d+\.\d+\.\d+)/i
|
|
405
|
-
]
|
|
406
|
-
|
|
407
|
-
patterns.each do |pattern|
|
|
408
|
-
if match = stdout_str.match(pattern)
|
|
409
|
-
return match[1]
|
|
410
|
-
end
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
# 从文件读取作为备用方案
|
|
414
|
-
version_file = File.join(project_path, "Logs", "GoodUnityBuild_version.txt")
|
|
415
|
-
if File.exist?(version_file)
|
|
416
|
-
content = File.read(version_file).strip
|
|
417
|
-
return content[/(\d+\.\d+\.\d+)/, 1]
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
nil
|
|
421
|
-
rescue => e
|
|
422
|
-
nil
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
def build_project(unity_exe_full_path:nil, project_path:nil, platform: nil, isLibrary: false, indexNo: nil, deployMode: nil)
|
|
113
|
+
def export_project(unity_exe_full_path:nil, project_path:nil, platform: nil, isLibrary: false, indexNo: nil, deployMode: nil)
|
|
426
114
|
|
|
427
115
|
# 检查是否有Unity进程在运行,传入Unity路径和项目路径以精确匹配
|
|
428
|
-
check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
429
|
-
|
|
430
|
-
# 检查 GoodUnityBuild 库版本
|
|
431
|
-
check_goodunitybuild_version(unity_exe_full_path, project_path)
|
|
116
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
432
117
|
|
|
433
118
|
additional_args = {}
|
|
434
119
|
additional_args[:platform] = platform if platform
|
|
@@ -436,8 +121,13 @@ module Pindo
|
|
|
436
121
|
additional_args[:indexno] = indexNo if indexNo
|
|
437
122
|
additional_args[:deploymode] = deployMode || 'dev' if deployMode || true # 默认为 dev
|
|
438
123
|
|
|
439
|
-
# 使用GoodUnityBuild.BuildManager.BatchBuild
|
|
440
|
-
result = execute_unity_command(
|
|
124
|
+
# 使用GoodUnityBuild.BuildManager.BatchBuild进行导出
|
|
125
|
+
result = UnityCommandHelper.execute_unity_command(
|
|
126
|
+
unity_exe_full_path,
|
|
127
|
+
project_path,
|
|
128
|
+
method: 'GoodUnityBuild.BuildManager.BatchBuild',
|
|
129
|
+
additional_args: additional_args
|
|
130
|
+
)
|
|
441
131
|
|
|
442
132
|
if result[:success]
|
|
443
133
|
puts "Unity build completed successfully"
|
|
@@ -447,422 +137,175 @@ module Pindo
|
|
|
447
137
|
puts result[:stdout]
|
|
448
138
|
end
|
|
449
139
|
else
|
|
450
|
-
|
|
140
|
+
|
|
451
141
|
puts "Unity构建失败! "
|
|
452
142
|
|
|
453
|
-
# 构造简洁的错误信息
|
|
454
|
-
|
|
455
|
-
# # 检查特定错误类型,提供简洁的错误信息
|
|
456
|
-
# if !result[:stdout].empty? && result[:stdout].include?("Multiple Unity instances cannot open the same project")
|
|
457
|
-
# error_msg = "Unity实例冲突:另一个Unity正在使用此项目,请关闭所有Unity实例后重试"
|
|
458
|
-
# elsif !result[:stdout].empty? && (result[:stdout].include?("Failed to download package") || result[:stdout].include?("Install Android SDK Platform"))
|
|
459
|
-
# error_msg = "Android SDK下载失败:请检查网络连接或手动配置SDK路径"
|
|
460
|
-
# elsif !result[:stderr].empty?
|
|
461
|
-
# # 只取第一行错误信息
|
|
462
|
-
# first_error = result[:stderr].lines.first.strip
|
|
463
|
-
# error_msg = "Unity构建失败: #{first_error}"
|
|
464
|
-
# elsif !result[:stdout].empty?
|
|
465
|
-
# # 只取第一行输出信息,不添加"Unity输出:"前缀
|
|
466
|
-
# first_output = result[:stdout].lines.first.strip
|
|
467
|
-
# error_msg = "Unity构建失败: #{first_output}"
|
|
468
|
-
# end
|
|
469
|
-
|
|
470
143
|
raise Informative, "GoodUnityBuild 导出时候失败!请确保GoodUnityBuild 能正常导出!!!"
|
|
471
144
|
end
|
|
472
145
|
|
|
473
146
|
result
|
|
474
147
|
end
|
|
475
148
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
#
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if unity_pids.any?
|
|
495
|
-
puts "⚠️ 检测到与当前项目相关的 Unity 进程正在运行:"
|
|
496
|
-
# 只显示真正的Unity进程,不显示 pindo 相关进程
|
|
497
|
-
unity_pids.each_with_index do |process_info, index|
|
|
498
|
-
puts " #{index + 1}. PID: #{process_info[:pid]}, 命令: #{process_info[:command]}"
|
|
499
|
-
end
|
|
500
|
-
puts ""
|
|
501
|
-
|
|
502
|
-
# 询问用户是否要自动关闭Unity进程
|
|
503
|
-
loop do
|
|
504
|
-
puts "批处理模式需要关闭这些 Unity 进程以避免冲突"
|
|
505
|
-
puts " [y] 是, 自动关闭所有 Unity 进程"
|
|
506
|
-
puts " [s] 跳过, 我已经手动关闭 Unity 进程,继续构建(可能导致冲突)"
|
|
507
|
-
puts " [e] 退出编译"
|
|
508
|
-
print "请输入选择 (y/s/e): "
|
|
509
|
-
|
|
510
|
-
input = STDIN.gets
|
|
511
|
-
choice = input ? input.chomp.strip.downcase : ""
|
|
512
|
-
|
|
513
|
-
case choice
|
|
514
|
-
when 'y', 'yes', '1'
|
|
515
|
-
puts "\n正在关闭 Unity 相关进程..."
|
|
516
|
-
success_count = 0
|
|
517
|
-
unity_pids.each do |process_info|
|
|
518
|
-
if kill_unity_process(process_info[:pid])
|
|
519
|
-
puts "✅ 成功关闭进程 #{process_info[:pid]}"
|
|
520
|
-
success_count += 1
|
|
521
|
-
else
|
|
522
|
-
puts "❌ 关闭进程 #{process_info[:pid]} 失败"
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
if success_count > 0
|
|
527
|
-
puts "\n✅ 已关闭 #{success_count} 个 Unity 相关进程"
|
|
528
|
-
puts "等待3秒后继续编译..."
|
|
529
|
-
sleep(3)
|
|
530
|
-
else
|
|
531
|
-
puts "\n❌ 无法关闭 Unity 相关进程,请手动关闭后重试"
|
|
532
|
-
raise "Unity进程冲突:无法自动关闭 Unity 相关进程,请手动关闭后重试"
|
|
533
|
-
end
|
|
534
|
-
break # 退出循环
|
|
535
|
-
|
|
536
|
-
when 's', 'skip', '2'
|
|
537
|
-
puts "\n✅ 跳过检查,继续编译..."
|
|
538
|
-
puts "假设Unity Editor已经手动关闭,如果仍在运行可能导致编译失败"
|
|
539
|
-
sleep(1)
|
|
540
|
-
break # 退出循环
|
|
541
|
-
|
|
542
|
-
when 'e', 'exit', '3'
|
|
543
|
-
puts "\n⚠️ 用户选择退出编译"
|
|
544
|
-
puts "退出Unity编译流程"
|
|
545
|
-
exit 0
|
|
546
|
-
|
|
547
|
-
else
|
|
548
|
-
puts "\n⚠️ 无效选择: '#{choice}'"
|
|
549
|
-
puts "请输入 y (是), s (跳过), 或 e (退出)\n\n"
|
|
550
|
-
# 继续循环,让用户重新输入
|
|
551
|
-
end
|
|
552
|
-
end
|
|
553
|
-
else
|
|
554
|
-
# 没有检测到与当前项目相关的Unity进程,静默继续
|
|
149
|
+
# 检查 YooAsset 是否存在
|
|
150
|
+
# YooAsset 可能以以下形式存在:
|
|
151
|
+
# 1. Assets/Packages/Joy.Tool.YooExt.* (手动导入)
|
|
152
|
+
# 2. Library/PackageCache/com.tuyoogame.yooasset@* (官方 YooAsset)
|
|
153
|
+
# 3. Library/PackageCache/com.fununitylib.yooext@* (YooExt 辅助包)
|
|
154
|
+
# @param project_path [String] Unity 项目路径
|
|
155
|
+
# @return [Boolean] 如果 YooAsset 存在返回 true
|
|
156
|
+
def yoo_asset_exists?(project_path)
|
|
157
|
+
# 1. 检查 Assets/Packages 目录(手动导入方式)
|
|
158
|
+
packages_path = File.join(project_path, "Assets", "Packages")
|
|
159
|
+
if File.directory?(packages_path)
|
|
160
|
+
yoo_pattern = File.join(packages_path, "Joy.Tool.YooExt.*")
|
|
161
|
+
matching_dirs = Dir.glob(yoo_pattern)
|
|
162
|
+
|
|
163
|
+
if matching_dirs.any?
|
|
164
|
+
puts "找到 YooAsset (Assets): #{matching_dirs.first}"
|
|
165
|
+
return true
|
|
555
166
|
end
|
|
556
167
|
end
|
|
557
|
-
end
|
|
558
168
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
# 1. 必须是Unity Editor主进程(排除VS Code等其他进程)
|
|
577
|
-
is_unity_editor = command.match?(/Unity\.app.*\/Unity/i) || command.match?(/Unity\.exe/i)
|
|
578
|
-
|
|
579
|
-
if is_unity_editor
|
|
580
|
-
# 2. 检查是否是打开了指定项目的Unity进程
|
|
581
|
-
# Unity 使用 -projectpath 参数指定项目路径
|
|
582
|
-
if project_path
|
|
583
|
-
# 标准化路径以确保匹配
|
|
584
|
-
normalized_project_path = File.expand_path(project_path)
|
|
585
|
-
# 精确匹配项目路径(必须完全匹配,不能只是包含)
|
|
586
|
-
if command.match?(/-projectpath\s+#{Regexp.escape(normalized_project_path)}(\s|$)/i)
|
|
587
|
-
# 只有当项目路径完全匹配时才认为是相关进程
|
|
588
|
-
is_relevant_unity_process = true
|
|
589
|
-
match_reasons << "Unity Editor打开了当前项目"
|
|
590
|
-
|
|
591
|
-
# 如果还指定了Unity路径,也要验证
|
|
592
|
-
if unity_exe_full_path
|
|
593
|
-
if command.include?(unity_exe_full_path)
|
|
594
|
-
match_reasons << "使用指定的Unity版本"
|
|
595
|
-
else
|
|
596
|
-
# Unity路径不匹配,不是我们要的进程
|
|
597
|
-
is_relevant_unity_process = false
|
|
598
|
-
match_reasons.clear
|
|
599
|
-
end
|
|
600
|
-
end
|
|
601
|
-
end
|
|
602
|
-
elsif unity_exe_full_path && command.include?(unity_exe_full_path)
|
|
603
|
-
# 只提供了Unity路径,没有项目路径时才匹配
|
|
604
|
-
# 这种情况下匹配所有使用该Unity版本的进程
|
|
605
|
-
is_relevant_unity_process = true
|
|
606
|
-
match_reasons << "使用指定的Unity版本"
|
|
607
|
-
end
|
|
608
|
-
end
|
|
609
|
-
|
|
610
|
-
# 3. 如果没有提供路径参数,不匹配任何进程(由上层函数处理)
|
|
611
|
-
|
|
612
|
-
if is_relevant_unity_process
|
|
613
|
-
processes << { pid: pid, command: command }
|
|
614
|
-
end
|
|
169
|
+
# 2. 检查 Library/PackageCache 目录(UPM 安装方式)
|
|
170
|
+
package_cache_path = File.join(project_path, "Library", "PackageCache")
|
|
171
|
+
if File.directory?(package_cache_path)
|
|
172
|
+
# 检查多个可能的包名
|
|
173
|
+
yoo_patterns = [
|
|
174
|
+
"com.tuyoogame.yooasset@*", # 官方 YooAsset 包
|
|
175
|
+
"com.fununitylib.yooext@*" # YooExt 辅助包
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
yoo_patterns.each do |pattern|
|
|
179
|
+
yoo_pattern = File.join(package_cache_path, pattern)
|
|
180
|
+
matching_dirs = Dir.glob(yoo_pattern)
|
|
181
|
+
|
|
182
|
+
if matching_dirs.any?
|
|
183
|
+
puts "找到 YooAsset (UPM): #{matching_dirs.first}"
|
|
184
|
+
return true
|
|
615
185
|
end
|
|
616
186
|
end
|
|
617
187
|
end
|
|
618
|
-
|
|
188
|
+
|
|
189
|
+
false
|
|
190
|
+
rescue => e
|
|
191
|
+
# 如果检查失败,返回 false(保守处理)
|
|
192
|
+
Funlog.warning("检查 YooAsset 是否存在时出错: #{e.message}")
|
|
193
|
+
false
|
|
619
194
|
end
|
|
620
|
-
|
|
621
|
-
#
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
# 检查进程是否真的存在且活跃
|
|
631
|
-
if process_exists_and_active?(pid_int)
|
|
632
|
-
valid_processes << process_info
|
|
633
|
-
end
|
|
195
|
+
|
|
196
|
+
# 构建 YooAsset 资源包
|
|
197
|
+
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
198
|
+
# @param project_path [String] Unity 项目路径
|
|
199
|
+
# @param platform [String] 目标平台 ('Android', 'iOS' 等)
|
|
200
|
+
# @return [Hash] 执行结果,如果跳过则返回 { skipped: true }
|
|
201
|
+
def build_yoo_asset(unity_exe_full_path:nil, project_path:nil, platform: nil)
|
|
202
|
+
# 检查项目中是否存在 YooAsset
|
|
203
|
+
unless yoo_asset_exists?(project_path)
|
|
204
|
+
return { skipped: true, reason: 'YooAsset not found' }
|
|
634
205
|
end
|
|
635
206
|
|
|
636
|
-
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
# 检查进程是否真的存在且活跃
|
|
640
|
-
def process_exists_and_active?(pid)
|
|
641
|
-
begin
|
|
642
|
-
# 使用更简单可靠的方式检查进程
|
|
643
|
-
# 尝试发送信号0来检查进程是否存在
|
|
644
|
-
Process.kill(0, pid)
|
|
645
|
-
|
|
646
|
-
# 如果需要检查进程状态,使用不同的命令格式
|
|
647
|
-
# -o pid=,stat= 去掉标题行
|
|
648
|
-
process_info = `ps -p #{pid} -o pid=,stat= 2>/dev/null`.strip
|
|
649
|
-
|
|
650
|
-
if process_info.empty?
|
|
651
|
-
return false
|
|
652
|
-
end
|
|
207
|
+
puts "检测到 YooAsset,开始构建资源..."
|
|
653
208
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
if parts.length >= 2
|
|
657
|
-
stat = parts[1]
|
|
658
|
-
# Z = 僵尸进程, T = 停止进程
|
|
659
|
-
# 只过滤僵尸进程,不过滤停止进程(T可能是正常的暂停状态)
|
|
660
|
-
if stat.include?('Z')
|
|
661
|
-
puts " 进程 #{pid} 是僵尸进程,过滤掉"
|
|
662
|
-
return false
|
|
663
|
-
end
|
|
664
|
-
end
|
|
209
|
+
# 检查是否有Unity进程在运行
|
|
210
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
665
211
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
# 进程不存在
|
|
669
|
-
false
|
|
670
|
-
rescue Errno::EPERM
|
|
671
|
-
# 权限不足,但进程存在
|
|
672
|
-
true
|
|
673
|
-
rescue => e
|
|
674
|
-
puts "检查进程 #{pid} 时出错: #{e.message}"
|
|
675
|
-
# 如果出错,假设进程存在(保守处理)
|
|
676
|
-
true
|
|
677
|
-
end
|
|
678
|
-
end
|
|
212
|
+
additional_args = {}
|
|
213
|
+
additional_args[:platform] = platform if platform
|
|
679
214
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
puts
|
|
694
|
-
return true
|
|
695
|
-
end
|
|
696
|
-
|
|
697
|
-
# 获取进程信息进行额外验证
|
|
698
|
-
process_info = get_process_info(pid_int)
|
|
699
|
-
if process_info && !process_info.include?('Unity')
|
|
700
|
-
puts "⚠️ 跳过非Unity进程 #{pid}: #{process_info}"
|
|
701
|
-
return true
|
|
702
|
-
end
|
|
703
|
-
|
|
704
|
-
puts "正在关闭Unity进程 #{pid}..."
|
|
705
|
-
|
|
706
|
-
# 先尝试优雅关闭
|
|
707
|
-
begin
|
|
708
|
-
Process.kill('TERM', pid_int)
|
|
709
|
-
puts "已发送TERM信号给进程 #{pid}"
|
|
710
|
-
rescue Errno::EPERM
|
|
711
|
-
puts "❌ 没有权限关闭进程 #{pid},尝试使用sudo"
|
|
712
|
-
return kill_unity_process_with_sudo(pid)
|
|
713
|
-
rescue Errno::ESRCH
|
|
714
|
-
puts "进程 #{pid} 已不存在"
|
|
715
|
-
return true
|
|
716
|
-
end
|
|
717
|
-
|
|
718
|
-
# 等待进程优雅退出
|
|
719
|
-
sleep(3)
|
|
720
|
-
|
|
721
|
-
# 检查进程是否还存在
|
|
722
|
-
if process_exists?(pid_int)
|
|
723
|
-
puts "进程 #{pid} 未响应TERM信号,尝试强制关闭..."
|
|
724
|
-
begin
|
|
725
|
-
Process.kill('KILL', pid_int)
|
|
726
|
-
puts "已发送KILL信号给进程 #{pid}"
|
|
727
|
-
sleep(2)
|
|
728
|
-
rescue Errno::EPERM
|
|
729
|
-
puts "❌ 没有权限强制关闭进程 #{pid}"
|
|
730
|
-
return false
|
|
731
|
-
rescue Errno::ESRCH
|
|
732
|
-
puts "进程 #{pid} 已不存在"
|
|
733
|
-
return true
|
|
734
|
-
end
|
|
735
|
-
end
|
|
736
|
-
|
|
737
|
-
# 最终检查
|
|
738
|
-
if process_exists?(pid_int)
|
|
739
|
-
puts "❌ 无法关闭进程 #{pid}"
|
|
740
|
-
false
|
|
741
|
-
else
|
|
742
|
-
puts "✅ 成功关闭进程 #{pid}"
|
|
743
|
-
true
|
|
215
|
+
# 使用 Yoo.Editor.YooCommandHelper.BatchBuild 进行资源构建
|
|
216
|
+
result = UnityCommandHelper.execute_unity_command(
|
|
217
|
+
unity_exe_full_path,
|
|
218
|
+
project_path,
|
|
219
|
+
method: 'Yoo.Editor.YooCommandHelper.BatchBuild',
|
|
220
|
+
additional_args: additional_args
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if result[:success]
|
|
224
|
+
puts "YooAsset 构建完成"
|
|
225
|
+
puts "使用 Unity 版本: #{result[:unity_version]}"
|
|
226
|
+
if !result[:stdout].empty?
|
|
227
|
+
puts "Unity 输出:"
|
|
228
|
+
puts result[:stdout]
|
|
744
229
|
end
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
puts "错误类型: #{e.class}"
|
|
749
|
-
false
|
|
230
|
+
else
|
|
231
|
+
puts "YooAsset 构建失败!"
|
|
232
|
+
raise Informative, "YooAsset 资源构建失败!请确保 YooAsset 配置正确!"
|
|
750
233
|
end
|
|
234
|
+
|
|
235
|
+
result
|
|
751
236
|
end
|
|
752
237
|
|
|
753
|
-
#
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
238
|
+
# 强制更新必备库(NugetForUnity)
|
|
239
|
+
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
240
|
+
# @param project_path [String] Unity 项目路径
|
|
241
|
+
# @return [Hash] 执行结果
|
|
242
|
+
def force_update_libraries(unity_exe_full_path:nil, project_path:nil)
|
|
243
|
+
# 检查是否有Unity进程在运行
|
|
244
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
245
|
+
|
|
246
|
+
# 使用 NugetForUnity.Joy.JoyTools.CheckForceUpdate 强制更新库
|
|
247
|
+
result = UnityCommandHelper.execute_unity_command(
|
|
248
|
+
unity_exe_full_path,
|
|
249
|
+
project_path,
|
|
250
|
+
method: 'NugetForUnity.Joy.JoyTools.CheckForceUpdate',
|
|
251
|
+
additional_args: {}
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
if result[:success]
|
|
255
|
+
puts "必备库更新完成"
|
|
256
|
+
puts "使用 Unity 版本: #{result[:unity_version]}"
|
|
257
|
+
if !result[:stdout].empty?
|
|
258
|
+
puts "Unity 输出:"
|
|
259
|
+
puts result[:stdout]
|
|
769
260
|
end
|
|
770
|
-
|
|
771
|
-
puts "
|
|
772
|
-
|
|
261
|
+
else
|
|
262
|
+
puts "必备库更新失败!"
|
|
263
|
+
raise Informative, "NugetForUnity 库更新失败!请检查网络连接和配置!"
|
|
773
264
|
end
|
|
774
|
-
end
|
|
775
265
|
|
|
776
|
-
|
|
777
|
-
def get_process_info(pid)
|
|
778
|
-
begin
|
|
779
|
-
`ps -p #{pid} -o comm=`.strip
|
|
780
|
-
rescue => e
|
|
781
|
-
nil
|
|
782
|
-
end
|
|
266
|
+
result
|
|
783
267
|
end
|
|
784
268
|
|
|
785
|
-
#
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
269
|
+
# 配置 GoodUnityBuild 编译模式
|
|
270
|
+
# @param unity_exe_full_path [String] Unity 可执行文件路径
|
|
271
|
+
# @param project_path [String] Unity 项目路径
|
|
272
|
+
# @param deploy_mode [String] 部署模式 ('dev', 'adhoc', 'release')
|
|
273
|
+
# @return [Hash] 执行结果
|
|
274
|
+
def config_build_mode(unity_exe_full_path:nil, project_path:nil, deploy_mode: 'dev')
|
|
275
|
+
# 验证 deploy_mode 参数
|
|
276
|
+
valid_modes = ['dev', 'adhoc', 'release']
|
|
277
|
+
unless valid_modes.include?(deploy_mode)
|
|
278
|
+
raise Informative, "无效的编译模式: #{deploy_mode},必须是 #{valid_modes.join(', ')}"
|
|
795
279
|
end
|
|
796
|
-
end
|
|
797
280
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
begin
|
|
801
|
-
# 等待一小段时间让 Unity 进程自然退出
|
|
802
|
-
sleep(2)
|
|
803
|
-
|
|
804
|
-
# 如果没有提供路径参数,不清理进程
|
|
805
|
-
if unity_exe_full_path.nil? && project_path.nil?
|
|
806
|
-
return
|
|
807
|
-
end
|
|
281
|
+
# 检查是否有Unity进程在运行
|
|
282
|
+
UnityProcHelper.check_unity_processes(unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
808
283
|
|
|
809
|
-
|
|
810
|
-
unity_processes = `ps aux | grep -i unity | grep -v grep`.strip
|
|
811
|
-
|
|
812
|
-
if !unity_processes.empty?
|
|
813
|
-
# 解析进程信息,传入Unity路径和项目路径进行精确匹配
|
|
814
|
-
unity_pids = parse_unity_processes(unity_processes, unity_exe_full_path: unity_exe_full_path, project_path: project_path)
|
|
815
|
-
|
|
816
|
-
if unity_pids.any?
|
|
817
|
-
puts "\e[33m检测到构建后仍有项目相关的 Unity 进程残留,正在清理...\e[0m"
|
|
818
|
-
# 自动清理残留的 Unity 进程
|
|
819
|
-
cleaned_count = 0
|
|
820
|
-
unity_pids.each do |process_info|
|
|
821
|
-
if kill_unity_process(process_info[:pid])
|
|
822
|
-
cleaned_count += 1
|
|
823
|
-
end
|
|
824
|
-
end
|
|
825
|
-
|
|
826
|
-
if cleaned_count > 0
|
|
827
|
-
puts "\e[32m✅ 已清理 #{cleaned_count} 个 Unity 相关进程残留\e[0m"
|
|
828
|
-
end
|
|
829
|
-
end
|
|
830
|
-
end
|
|
831
|
-
rescue => e
|
|
832
|
-
# 清理失败不影响主流程
|
|
833
|
-
# 静默处理,不输出错误信息
|
|
834
|
-
end
|
|
835
|
-
end
|
|
284
|
+
puts "配置 GoodUnityBuild 编译模式为: #{deploy_mode}"
|
|
836
285
|
|
|
286
|
+
# 使用 GoodUnityBuild.BuildManager.BatchConfig 配置编译模式
|
|
287
|
+
result = UnityCommandHelper.execute_unity_command(
|
|
288
|
+
unity_exe_full_path,
|
|
289
|
+
project_path,
|
|
290
|
+
method: 'GoodUnityBuild.BuildManager.BatchConfig',
|
|
291
|
+
additional_args: { deployMode: deploy_mode }
|
|
292
|
+
)
|
|
837
293
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
version
|
|
845
|
-
else
|
|
846
|
-
raise "Could not parse Unity version from #{version_path}"
|
|
294
|
+
if result[:success]
|
|
295
|
+
puts "编译模式配置完成: #{deploy_mode}"
|
|
296
|
+
puts "使用 Unity 版本: #{result[:unity_version]}"
|
|
297
|
+
if !result[:stdout].empty?
|
|
298
|
+
puts "Unity 输出:"
|
|
299
|
+
puts result[:stdout]
|
|
847
300
|
end
|
|
848
301
|
else
|
|
849
|
-
|
|
302
|
+
puts "编译模式配置失败!"
|
|
303
|
+
raise Informative, "GoodUnityBuild 编译模式配置失败!请确保 GoodUnityBuild 正确安装!"
|
|
850
304
|
end
|
|
851
|
-
end
|
|
852
|
-
|
|
853
305
|
|
|
854
|
-
|
|
855
|
-
# 检查关键Unity工程文件和目录是否存在
|
|
856
|
-
project_settings_path = File.join(project_path, "ProjectSettings")
|
|
857
|
-
assets_path = File.join(project_path, "Assets")
|
|
858
|
-
packages_path = File.join(project_path, "Packages")
|
|
859
|
-
|
|
860
|
-
File.directory?(project_settings_path) &&
|
|
861
|
-
File.directory?(assets_path) &&
|
|
862
|
-
File.directory?(packages_path) &&
|
|
863
|
-
File.exist?(File.join(project_settings_path, "ProjectSettings.asset"))
|
|
306
|
+
result
|
|
864
307
|
end
|
|
865
308
|
|
|
866
309
|
end
|
|
867
310
|
end
|
|
868
|
-
end
|
|
311
|
+
end
|