pindo 5.11.1 → 5.11.3
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 +7 -7
- data/lib/pindo/command/android/build.rb +2 -2
- data/lib/pindo/command/android/keystore.rb +2 -2
- data/lib/pindo/command/unity/apk.rb +13 -7
- data/lib/pindo/command/unity/autobuild.rb +230 -18
- data/lib/pindo/command/unity/ipa.rb +7 -1
- data/lib/pindo/command/unity/packpush.rb +10 -0
- data/lib/pindo/command/unity/web.rb +7 -1
- data/lib/pindo/command/web/autobuild.rb +7 -1
- data/lib/pindo/module/android/android_build_helper.rb +22 -12
- data/lib/pindo/module/android/{android_build_config_helper.rb → android_config_helper.rb} +20 -4
- data/lib/pindo/module/android/android_res_helper.rb +50 -0
- data/lib/pindo/module/task/model/build_task.rb +361 -0
- data/lib/pindo/module/task/model/unity_export_task.rb +201 -0
- data/lib/pindo/module/task/model/upload_task.rb +278 -0
- data/lib/pindo/module/task/pindo_task.rb +237 -0
- data/lib/pindo/module/task/task_config.rb +84 -0
- data/lib/pindo/module/task/task_manager.rb +494 -0
- data/lib/pindo/module/unity/unity_helper.rb +20 -44
- data/lib/pindo/version.rb +1 -1
- metadata +8 -2
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'thread'
|
|
3
|
+
|
|
4
|
+
module Pindo
|
|
5
|
+
module TaskSystem
|
|
6
|
+
class TaskManager
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@pending_queue = [] # 待执行队列
|
|
11
|
+
@triggered_queue = [] # 已触发队列
|
|
12
|
+
@running_tasks = [] # 正在运行的任务
|
|
13
|
+
@completed_tasks = [] # 已完成的任务
|
|
14
|
+
@task_locks = {
|
|
15
|
+
exclusive: Mutex.new,
|
|
16
|
+
type_locks: {}
|
|
17
|
+
}
|
|
18
|
+
@queue_mutex = Mutex.new
|
|
19
|
+
@queue_condition = ConditionVariable.new # 用于等待/通知机制
|
|
20
|
+
@running = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# 添加任务
|
|
24
|
+
def add_task(task, options = {})
|
|
25
|
+
raise ArgumentError, "Task must be a PindoTask" unless task.is_a?(PindoTask)
|
|
26
|
+
|
|
27
|
+
# 验证任务
|
|
28
|
+
unless task.validate
|
|
29
|
+
raise ArgumentError, "Task validation failed: #{task.name}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# 处理依赖
|
|
33
|
+
if options[:wait_for]
|
|
34
|
+
task.dependencies.concat(Array(options[:wait_for]))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@queue_mutex.synchronize do
|
|
38
|
+
@pending_queue << task
|
|
39
|
+
# 按优先级排序
|
|
40
|
+
@pending_queue.sort_by! { |t| -t.priority }
|
|
41
|
+
# 通知等待的线程有新任务
|
|
42
|
+
@queue_condition.signal
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
task.id
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# 批量添加任务
|
|
49
|
+
def add_tasks(tasks)
|
|
50
|
+
tasks.map { |task| add_task(task) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# 开始执行(主线程循环)
|
|
54
|
+
def start
|
|
55
|
+
return if @running
|
|
56
|
+
@running = true
|
|
57
|
+
|
|
58
|
+
puts "\n[TaskManager] 开始执行任务调度...".cyan if defined?(String.cyan)
|
|
59
|
+
|
|
60
|
+
# 主线程循环:负责触发任务
|
|
61
|
+
while @running
|
|
62
|
+
task = nil
|
|
63
|
+
|
|
64
|
+
@queue_mutex.synchronize do
|
|
65
|
+
# 等待直到有可执行的任务或应该停止
|
|
66
|
+
while @running && !should_stop_locked?
|
|
67
|
+
task = get_next_executable_task_locked
|
|
68
|
+
if task
|
|
69
|
+
break
|
|
70
|
+
else
|
|
71
|
+
# 没有可执行的任务,等待通知
|
|
72
|
+
# 设置超时避免死锁,同时定期检查依赖状态
|
|
73
|
+
@queue_condition.wait(@queue_mutex, 1.0)
|
|
74
|
+
|
|
75
|
+
# 检查是否有因依赖失败需要级联处理的任务
|
|
76
|
+
check_and_cascade_failures_locked
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# 如果应该停止且没有任务,退出循环
|
|
81
|
+
break if should_stop_locked? && task.nil?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# 在锁外触发任务
|
|
85
|
+
if task
|
|
86
|
+
trigger_task(task)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# 清理已完成的异步任务
|
|
90
|
+
cleanup_finished_tasks
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# 等待所有触发的任务完成
|
|
94
|
+
wait_all_triggered_tasks
|
|
95
|
+
|
|
96
|
+
puts "\n[TaskManager] 所有任务执行完毕".green if defined?(String.green)
|
|
97
|
+
@running = false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# 停止执行
|
|
101
|
+
def stop
|
|
102
|
+
@running = false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# 等待所有任务完成
|
|
106
|
+
def wait_all
|
|
107
|
+
while @pending_queue.any? || @running_tasks.any?
|
|
108
|
+
sleep(0.1)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# 获取任务状态
|
|
113
|
+
def task_status(task_id)
|
|
114
|
+
task = find_task(task_id)
|
|
115
|
+
task&.status
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# 取消任务
|
|
119
|
+
def cancel_task(task_id)
|
|
120
|
+
task = find_task(task_id)
|
|
121
|
+
task&.cancel
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# 获取执行报告
|
|
125
|
+
def execution_report
|
|
126
|
+
@queue_mutex.synchronize do
|
|
127
|
+
{
|
|
128
|
+
pending: @pending_queue.count,
|
|
129
|
+
triggered: @triggered_queue.count,
|
|
130
|
+
running: @running_tasks.count,
|
|
131
|
+
completed: @completed_tasks.count,
|
|
132
|
+
success: @completed_tasks.count { |t| t.status == TaskStatus::SUCCESS },
|
|
133
|
+
failed: @completed_tasks.count { |t| t.status == TaskStatus::FAILED },
|
|
134
|
+
tasks: (@pending_queue + @triggered_queue + @running_tasks + @completed_tasks).map do |task|
|
|
135
|
+
{
|
|
136
|
+
id: task.id,
|
|
137
|
+
name: task.name,
|
|
138
|
+
type: task.type,
|
|
139
|
+
status: task.status,
|
|
140
|
+
execution_type: task.execution_type,
|
|
141
|
+
execution_mode: task.execution_mode,
|
|
142
|
+
error: task.error&.message,
|
|
143
|
+
progress: task.progress,
|
|
144
|
+
execution_time: task.execution_time
|
|
145
|
+
}
|
|
146
|
+
end
|
|
147
|
+
}
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
private
|
|
152
|
+
|
|
153
|
+
# 获取下一个可执行的任务(需要在锁内调用)
|
|
154
|
+
def get_next_executable_task_locked
|
|
155
|
+
task = @pending_queue.find do |t|
|
|
156
|
+
can_execute?(t)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if task
|
|
160
|
+
@pending_queue.delete(task)
|
|
161
|
+
task
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# 获取下一个可执行的任务(带锁版本,向后兼容)
|
|
166
|
+
def get_next_executable_task
|
|
167
|
+
@queue_mutex.synchronize do
|
|
168
|
+
get_next_executable_task_locked
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# 检查并级联处理失败的依赖(需要在锁内调用)
|
|
173
|
+
def check_and_cascade_failures_locked
|
|
174
|
+
@pending_queue.each do |task|
|
|
175
|
+
dependency_check = check_dependencies(task)
|
|
176
|
+
if dependency_check == :failed || dependency_check == :cancelled
|
|
177
|
+
cascade_failure_locked(task, dependency_check)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# 级联失败处理(锁内版本)
|
|
183
|
+
def cascade_failure_locked(task, reason)
|
|
184
|
+
case reason
|
|
185
|
+
when :failed
|
|
186
|
+
task.status = TaskStatus::FAILED
|
|
187
|
+
task.error = RuntimeError.new("依赖任务失败")
|
|
188
|
+
if defined?(String.red)
|
|
189
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖失败而被标记为失败".red
|
|
190
|
+
else
|
|
191
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖失败而被标记为失败"
|
|
192
|
+
end
|
|
193
|
+
when :cancelled
|
|
194
|
+
task.status = TaskStatus::CANCELLED
|
|
195
|
+
task.error = RuntimeError.new("依赖任务被取消")
|
|
196
|
+
if defined?(String.yellow)
|
|
197
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖取消而被取消".yellow
|
|
198
|
+
else
|
|
199
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖取消而被取消"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# 将任务移到完成队列
|
|
204
|
+
@pending_queue.delete(task)
|
|
205
|
+
@completed_tasks << task
|
|
206
|
+
|
|
207
|
+
# 通知可能有新的可执行任务
|
|
208
|
+
@queue_condition.signal
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# 判断任务是否可以执行
|
|
212
|
+
def can_execute?(task)
|
|
213
|
+
# 1. 检查依赖状态
|
|
214
|
+
dependency_check = check_dependencies(task)
|
|
215
|
+
|
|
216
|
+
# 如果依赖检查返回 :failed 或 :cancelled,级联处理
|
|
217
|
+
if dependency_check == :failed || dependency_check == :cancelled
|
|
218
|
+
cascade_failure(task, dependency_check)
|
|
219
|
+
return false
|
|
220
|
+
elsif dependency_check == :waiting
|
|
221
|
+
return false # 依赖未完成,继续等待
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# 2. 根据执行模式检查并发限制
|
|
225
|
+
case task.execution_mode
|
|
226
|
+
when ExecutionMode::EXCLUSIVE
|
|
227
|
+
# 独占模式:没有其他任务在运行
|
|
228
|
+
@running_tasks.empty?
|
|
229
|
+
when ExecutionMode::TYPE_EXCLUSIVE
|
|
230
|
+
# 类型独占:没有相同类型的任务在运行
|
|
231
|
+
!@running_tasks.any? { |t| t.type == task.type }
|
|
232
|
+
when ExecutionMode::CONCURRENT
|
|
233
|
+
# 并发模式:可以执行
|
|
234
|
+
true
|
|
235
|
+
else
|
|
236
|
+
true
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# 检查依赖状态
|
|
241
|
+
def check_dependencies(task)
|
|
242
|
+
return :ready if task.dependencies.empty?
|
|
243
|
+
|
|
244
|
+
task.dependencies.each do |dep_id|
|
|
245
|
+
dep_task = find_task(dep_id)
|
|
246
|
+
|
|
247
|
+
# 依赖任务不存在
|
|
248
|
+
return :failed unless dep_task
|
|
249
|
+
|
|
250
|
+
# 检查依赖任务状态
|
|
251
|
+
case dep_task.status
|
|
252
|
+
when TaskStatus::SUCCESS
|
|
253
|
+
next # 这个依赖已完成
|
|
254
|
+
when TaskStatus::FAILED
|
|
255
|
+
return :failed # 依赖失败
|
|
256
|
+
when TaskStatus::CANCELLED
|
|
257
|
+
return :cancelled # 依赖被取消
|
|
258
|
+
else
|
|
259
|
+
return :waiting # 依赖未完成
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
:ready # 所有依赖都成功完成
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# 级联失败处理
|
|
267
|
+
def cascade_failure(task, reason)
|
|
268
|
+
@queue_mutex.synchronize do
|
|
269
|
+
case reason
|
|
270
|
+
when :failed
|
|
271
|
+
task.status = TaskStatus::FAILED
|
|
272
|
+
task.error = RuntimeError.new("依赖任务失败")
|
|
273
|
+
if defined?(String.red)
|
|
274
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖失败而被标记为失败".red
|
|
275
|
+
else
|
|
276
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖失败而被标记为失败"
|
|
277
|
+
end
|
|
278
|
+
when :cancelled
|
|
279
|
+
task.status = TaskStatus::CANCELLED
|
|
280
|
+
task.error = RuntimeError.new("依赖任务被取消")
|
|
281
|
+
if defined?(String.yellow)
|
|
282
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖取消而被取消".yellow
|
|
283
|
+
else
|
|
284
|
+
puts "[TaskManager] 任务 #{task.name} 因依赖取消而被取消"
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# 将任务移到完成队列
|
|
289
|
+
@pending_queue.delete(task)
|
|
290
|
+
@completed_tasks << task
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# 触发任务执行
|
|
295
|
+
def trigger_task(task)
|
|
296
|
+
# 获取任务锁
|
|
297
|
+
lock_acquired = acquire_lock(task)
|
|
298
|
+
|
|
299
|
+
unless lock_acquired
|
|
300
|
+
# 无法获取锁,任务返回队列
|
|
301
|
+
@queue_mutex.synchronize do
|
|
302
|
+
@pending_queue.unshift(task) # 放回队列前面
|
|
303
|
+
@queue_condition.signal
|
|
304
|
+
end
|
|
305
|
+
return
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
@queue_mutex.synchronize do
|
|
309
|
+
task.status = TaskStatus::TRIGGERED
|
|
310
|
+
@triggered_queue << task
|
|
311
|
+
@running_tasks << task
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# 显示触发信息
|
|
315
|
+
execution_type_str = task.execution_type == ExecutionType::SYNC ? "同步" : "异步"
|
|
316
|
+
if defined?(String.blue)
|
|
317
|
+
puts "\n[#{Time.now.strftime('%H:%M:%S')}] 触发任务: #{task.name} (#{execution_type_str})".blue
|
|
318
|
+
else
|
|
319
|
+
puts "\n[#{Time.now.strftime('%H:%M:%S')}] 触发任务: #{task.name} (#{execution_type_str})"
|
|
320
|
+
end
|
|
321
|
+
puts " 类型: #{task.type}, 模式: #{task.execution_mode}"
|
|
322
|
+
|
|
323
|
+
# 设置任务完成回调
|
|
324
|
+
task.on(:after) do |t|
|
|
325
|
+
on_task_finished(t)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# 设置进度回调
|
|
329
|
+
task.on(:on_progress) do |t|
|
|
330
|
+
if defined?(String.cyan)
|
|
331
|
+
puts " [#{t.progress}%] #{t.progress_message}".cyan if t.progress_message
|
|
332
|
+
else
|
|
333
|
+
puts " [#{t.progress}%] #{t.progress_message}" if t.progress_message
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# 根据执行类型触发任务
|
|
338
|
+
case task.execution_type
|
|
339
|
+
when ExecutionType::SYNC
|
|
340
|
+
# 同步执行:在当前线程(主线程)执行
|
|
341
|
+
if defined?(String.yellow)
|
|
342
|
+
puts " → 在主线程中同步执行".yellow
|
|
343
|
+
else
|
|
344
|
+
puts " → 在主线程中同步执行"
|
|
345
|
+
end
|
|
346
|
+
task.do_task
|
|
347
|
+
when ExecutionType::ASYNC
|
|
348
|
+
# 异步执行:在新线程执行
|
|
349
|
+
if defined?(String.yellow)
|
|
350
|
+
puts " → 在新线程中异步执行".yellow
|
|
351
|
+
else
|
|
352
|
+
puts " → 在新线程中异步执行"
|
|
353
|
+
end
|
|
354
|
+
task.async_do_task
|
|
355
|
+
else
|
|
356
|
+
# 默认异步
|
|
357
|
+
task.async_do_task
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# 任务完成回调
|
|
362
|
+
def on_task_finished(task)
|
|
363
|
+
@queue_mutex.synchronize do
|
|
364
|
+
@running_tasks.delete(task)
|
|
365
|
+
@triggered_queue.delete(task)
|
|
366
|
+
@completed_tasks << task
|
|
367
|
+
|
|
368
|
+
# 释放任务锁
|
|
369
|
+
release_lock(task)
|
|
370
|
+
|
|
371
|
+
# 通知等待的线程,可能有新的任务可以执行
|
|
372
|
+
@queue_condition.signal
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# 显示完成信息
|
|
376
|
+
if task.status == TaskStatus::SUCCESS
|
|
377
|
+
time_str = task.execution_time ? " (#{task.execution_time.round(2)}s)" : ""
|
|
378
|
+
if defined?(String.green)
|
|
379
|
+
puts "[#{Time.now.strftime('%H:%M:%S')}] ✅ 完成: #{task.name}#{time_str}".green
|
|
380
|
+
else
|
|
381
|
+
puts "[#{Time.now.strftime('%H:%M:%S')}] ✅ 完成: #{task.name}#{time_str}"
|
|
382
|
+
end
|
|
383
|
+
elsif task.status == TaskStatus::FAILED
|
|
384
|
+
if defined?(String.red)
|
|
385
|
+
puts "[#{Time.now.strftime('%H:%M:%S')}] ❌ 失败: #{task.name}".red
|
|
386
|
+
puts " 错误: #{task.error.message}".red if task.error
|
|
387
|
+
else
|
|
388
|
+
puts "[#{Time.now.strftime('%H:%M:%S')}] ❌ 失败: #{task.name}"
|
|
389
|
+
puts " 错误: #{task.error.message}" if task.error
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# 清理已完成的异步任务
|
|
395
|
+
def cleanup_finished_tasks
|
|
396
|
+
@queue_mutex.synchronize do
|
|
397
|
+
@running_tasks.select(&:finished?).each do |task|
|
|
398
|
+
# 任务已经通过回调处理,这里只是确保清理
|
|
399
|
+
unless @completed_tasks.include?(task)
|
|
400
|
+
on_task_finished(task)
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# 判断是否应该停止(需要在锁内调用)
|
|
407
|
+
def should_stop_locked?
|
|
408
|
+
@pending_queue.empty? && @running_tasks.empty?
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# 判断是否应该停止(带锁版本)
|
|
412
|
+
def should_stop?
|
|
413
|
+
@queue_mutex.synchronize do
|
|
414
|
+
should_stop_locked?
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
# 等待所有已触发的任务完成
|
|
419
|
+
def wait_all_triggered_tasks
|
|
420
|
+
if defined?(String.yellow)
|
|
421
|
+
puts "\n等待所有异步任务完成...".yellow
|
|
422
|
+
else
|
|
423
|
+
puts "\n等待所有异步任务完成..."
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
while true
|
|
427
|
+
@queue_mutex.synchronize do
|
|
428
|
+
break if @triggered_queue.empty? && @running_tasks.empty?
|
|
429
|
+
end
|
|
430
|
+
sleep(0.1)
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# 查找任务
|
|
435
|
+
def find_task(task_id)
|
|
436
|
+
all_tasks = []
|
|
437
|
+
@queue_mutex.synchronize do
|
|
438
|
+
all_tasks = @pending_queue + @triggered_queue + @running_tasks + @completed_tasks
|
|
439
|
+
end
|
|
440
|
+
all_tasks.find { |t| t.id == task_id }
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
# 获取类型锁
|
|
444
|
+
def type_lock(type)
|
|
445
|
+
@task_locks[:type_locks][type] ||= Mutex.new
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# 获取任务锁
|
|
449
|
+
def acquire_lock(task)
|
|
450
|
+
case task.execution_mode
|
|
451
|
+
when ExecutionMode::EXCLUSIVE
|
|
452
|
+
# 独占模式:尝试获取全局锁
|
|
453
|
+
@task_locks[:exclusive].try_lock
|
|
454
|
+
when ExecutionMode::TYPE_EXCLUSIVE
|
|
455
|
+
# 类型独占:尝试获取类型锁
|
|
456
|
+
type_lock(task.type).try_lock
|
|
457
|
+
when ExecutionMode::CONCURRENT
|
|
458
|
+
# 并发模式:不需要锁
|
|
459
|
+
true
|
|
460
|
+
else
|
|
461
|
+
true
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
# 释放任务锁
|
|
466
|
+
def release_lock(task)
|
|
467
|
+
case task.execution_mode
|
|
468
|
+
when ExecutionMode::EXCLUSIVE
|
|
469
|
+
# 释放全局锁
|
|
470
|
+
@task_locks[:exclusive].unlock rescue nil
|
|
471
|
+
when ExecutionMode::TYPE_EXCLUSIVE
|
|
472
|
+
# 释放类型锁
|
|
473
|
+
type_lock(task.type).unlock rescue nil
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# 清空所有队列(用于重置)
|
|
478
|
+
def clear_all
|
|
479
|
+
@queue_mutex.synchronize do
|
|
480
|
+
@pending_queue.clear
|
|
481
|
+
@triggered_queue.clear
|
|
482
|
+
@running_tasks.clear
|
|
483
|
+
@completed_tasks.clear
|
|
484
|
+
|
|
485
|
+
# 释放所有锁
|
|
486
|
+
@task_locks[:exclusive].unlock rescue nil
|
|
487
|
+
@task_locks[:type_locks].each_value do |lock|
|
|
488
|
+
lock.unlock rescue nil
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
end
|
|
@@ -308,7 +308,7 @@ module Pindo
|
|
|
308
308
|
# 检查是否有构建错误的关键词
|
|
309
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
310
|
build_success = false
|
|
311
|
-
puts "\n\e[31m检测到构建错误信息,构建可能失败\e[0m"
|
|
311
|
+
# puts "\n\e[31m检测到构建错误信息,构建可能失败\e[0m"
|
|
312
312
|
end
|
|
313
313
|
|
|
314
314
|
if build_success
|
|
@@ -442,51 +442,27 @@ module Pindo
|
|
|
442
442
|
puts result[:stdout]
|
|
443
443
|
end
|
|
444
444
|
else
|
|
445
|
-
|
|
446
|
-
puts "Unity
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
if !result[:stdout].empty?
|
|
450
|
-
puts "Unity标准输出:"
|
|
451
|
-
puts result[:stdout]
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
if !result[:stderr].empty?
|
|
455
|
-
puts "Unity错误输出:"
|
|
456
|
-
puts result[:stderr]
|
|
457
|
-
else
|
|
458
|
-
puts "Unity没有输出错误信息"
|
|
459
|
-
end
|
|
460
|
-
|
|
461
|
-
# 提供更详细的错误信息
|
|
462
|
-
error_msg = "Unity构建失败 (退出码: #{result[:exit_status]})"
|
|
445
|
+
# 简单输出失败信息,不显示详细调试信息
|
|
446
|
+
puts "Unity构建失败! "
|
|
447
|
+
|
|
448
|
+
# 构造简洁的错误信息
|
|
463
449
|
|
|
464
|
-
#
|
|
465
|
-
if !result[:stdout].empty? && result[:stdout].include?("Multiple Unity instances cannot open the same project")
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
#
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
error_msg += "1. 检查网络连接\n"
|
|
479
|
-
error_msg += "2. 使用VPN或代理\n"
|
|
480
|
-
error_msg += "3. 在Unity Editor中手动配置Android SDK路径\n"
|
|
481
|
-
error_msg += "4. 清理Unity缓存: rm -rf Library/BuildCache\n"
|
|
482
|
-
error_msg += "5. 重新运行构建命令"
|
|
483
|
-
elsif !result[:stderr].empty?
|
|
484
|
-
error_msg += "\n错误详情: #{result[:stderr].lines.first.strip}"
|
|
485
|
-
elsif !result[:stdout].empty?
|
|
486
|
-
error_msg += "\nUnity输出: #{result[:stdout].lines.first.strip}"
|
|
487
|
-
end
|
|
450
|
+
# # 检查特定错误类型,提供简洁的错误信息
|
|
451
|
+
# if !result[:stdout].empty? && result[:stdout].include?("Multiple Unity instances cannot open the same project")
|
|
452
|
+
# error_msg = "Unity实例冲突:另一个Unity正在使用此项目,请关闭所有Unity实例后重试"
|
|
453
|
+
# elsif !result[:stdout].empty? && (result[:stdout].include?("Failed to download package") || result[:stdout].include?("Install Android SDK Platform"))
|
|
454
|
+
# error_msg = "Android SDK下载失败:请检查网络连接或手动配置SDK路径"
|
|
455
|
+
# elsif !result[:stderr].empty?
|
|
456
|
+
# # 只取第一行错误信息
|
|
457
|
+
# first_error = result[:stderr].lines.first.strip
|
|
458
|
+
# error_msg = "Unity构建失败: #{first_error}"
|
|
459
|
+
# elsif !result[:stdout].empty?
|
|
460
|
+
# # 只取第一行输出信息,不添加"Unity输出:"前缀
|
|
461
|
+
# first_output = result[:stdout].lines.first.strip
|
|
462
|
+
# error_msg = "Unity构建失败: #{first_output}"
|
|
463
|
+
# end
|
|
488
464
|
|
|
489
|
-
raise
|
|
465
|
+
raise Informative, "GoodUnityBuild 导出时候失败!请确保GoodUnityBuild 能正常导出!!!"
|
|
490
466
|
end
|
|
491
467
|
|
|
492
468
|
result
|
data/lib/pindo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pindo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.11.
|
|
4
|
+
version: 5.11.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- wade
|
|
@@ -414,8 +414,8 @@ files:
|
|
|
414
414
|
- lib/pindo/command/web/run.rb
|
|
415
415
|
- lib/pindo/config/pindoconfig.rb
|
|
416
416
|
- lib/pindo/config/pindouserlocalconfig.rb
|
|
417
|
-
- lib/pindo/module/android/android_build_config_helper.rb
|
|
418
417
|
- lib/pindo/module/android/android_build_helper.rb
|
|
418
|
+
- lib/pindo/module/android/android_config_helper.rb
|
|
419
419
|
- lib/pindo/module/android/android_project_helper.rb
|
|
420
420
|
- lib/pindo/module/android/android_res_helper.rb
|
|
421
421
|
- lib/pindo/module/android/gp_compliance_helper.rb
|
|
@@ -437,6 +437,12 @@ files:
|
|
|
437
437
|
- lib/pindo/module/cert/provisioning_helper.rb
|
|
438
438
|
- lib/pindo/module/cert/xcodecerthelper.rb
|
|
439
439
|
- lib/pindo/module/pgyer/pgyerhelper.rb
|
|
440
|
+
- lib/pindo/module/task/model/build_task.rb
|
|
441
|
+
- lib/pindo/module/task/model/unity_export_task.rb
|
|
442
|
+
- lib/pindo/module/task/model/upload_task.rb
|
|
443
|
+
- lib/pindo/module/task/pindo_task.rb
|
|
444
|
+
- lib/pindo/module/task/task_config.rb
|
|
445
|
+
- lib/pindo/module/task/task_manager.rb
|
|
440
446
|
- lib/pindo/module/unity/nuget_helper.rb
|
|
441
447
|
- lib/pindo/module/unity/unity_helper.rb
|
|
442
448
|
- lib/pindo/module/webserver/brotli_file_handler.rb
|