pindo 5.11.4 → 5.12.2
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/githelper.rb +16 -0
- data/lib/pindo/base/pindocontext.rb +13 -4
- data/lib/pindo/command/android/autobuild.rb +108 -185
- data/lib/pindo/command/android/build.rb +10 -2
- data/lib/pindo/command/ios/autobuild.rb +116 -213
- data/lib/pindo/command/ios/build.rb +12 -3
- data/lib/pindo/command/jps/upload.rb +253 -118
- data/lib/pindo/command/unity/autobuild.rb +297 -227
- data/lib/pindo/command/unity.rb +0 -3
- data/lib/pindo/command/utils/boss.rb +18 -15
- data/lib/pindo/command/utils/clearcert.rb +26 -18
- data/lib/pindo/command/utils/device.rb +28 -19
- data/lib/pindo/command/utils/feishu.rb +11 -4
- data/lib/pindo/command/utils/icon.rb +26 -20
- data/lib/pindo/command/utils/renewcert.rb +35 -29
- data/lib/pindo/command/utils/renewproj.rb +32 -25
- data/lib/pindo/command/utils/repoinit.rb +1 -1
- data/lib/pindo/command/utils/tag.rb +6 -180
- data/lib/pindo/command/utils/tgate.rb +34 -28
- data/lib/pindo/command/utils/xcassets.rb +30 -20
- data/lib/pindo/command/web/autobuild.rb +148 -128
- data/lib/pindo/module/android/android_build_helper.rb +0 -6
- data/lib/pindo/module/android/android_config_helper.rb +4 -26
- data/lib/pindo/module/build/build_helper.rb +18 -294
- data/lib/pindo/module/build/git_repo_helper.rb +530 -0
- data/lib/pindo/module/build/icon_downloader.rb +85 -0
- data/lib/pindo/module/pgyer/pgyerhelper.rb +16 -11
- data/lib/pindo/module/task/model/build/android_dev_build_task.rb +209 -0
- data/lib/pindo/module/task/model/build/android_release_build_task.rb +29 -0
- data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +53 -0
- data/lib/pindo/module/task/model/build/ios_dev_build_task.rb +251 -0
- data/lib/pindo/module/task/model/build/ios_release_build_task.rb +53 -0
- data/lib/pindo/module/task/model/build/web_dev_build_task.rb +43 -0
- data/lib/pindo/module/task/model/build_task.rb +125 -301
- data/lib/pindo/module/task/model/git_tag_task.rb +80 -0
- data/lib/pindo/module/task/model/unity_export_task.rb +53 -41
- data/lib/pindo/module/task/model/upload_task.rb +149 -208
- data/lib/pindo/module/task/pindo_task.rb +135 -95
- data/lib/pindo/module/task/task_manager.rb +202 -352
- data/lib/pindo/module/unity/unity_helper.rb +7 -3
- data/lib/pindo/module/xcode/xcode_build_config.rb +4 -10
- data/lib/pindo/module/xcode/xcode_build_helper.rb +19 -0
- data/lib/pindo/version.rb +1 -1
- metadata +10 -4
- data/lib/pindo/command/unity/apk.rb +0 -185
- data/lib/pindo/command/unity/ipa.rb +0 -198
- data/lib/pindo/command/unity/web.rb +0 -163
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
require 'singleton'
|
|
2
|
-
require '
|
|
2
|
+
require 'pindo/base/funlog'
|
|
3
3
|
|
|
4
4
|
module Pindo
|
|
5
5
|
module TaskSystem
|
|
6
|
+
# 简化版任务管理器
|
|
7
|
+
# 所有任务在主线程中按顺序执行
|
|
6
8
|
class TaskManager
|
|
7
9
|
include Singleton
|
|
8
10
|
|
|
9
11
|
def initialize
|
|
10
12
|
@pending_queue = [] # 待执行队列
|
|
11
|
-
@triggered_queue = [] # 已触发队列
|
|
12
|
-
@running_tasks = [] # 正在运行的任务
|
|
13
13
|
@completed_tasks = [] # 已完成的任务
|
|
14
|
-
@
|
|
15
|
-
exclusive: Mutex.new,
|
|
16
|
-
type_locks: {}
|
|
17
|
-
}
|
|
18
|
-
@queue_mutex = Mutex.new
|
|
19
|
-
@queue_condition = ConditionVariable.new # 用于等待/通知机制
|
|
20
|
-
@running = false
|
|
14
|
+
@current_task = nil # 当前正在执行的任务
|
|
21
15
|
end
|
|
22
16
|
|
|
23
17
|
# 添加任务
|
|
@@ -34,13 +28,9 @@ module Pindo
|
|
|
34
28
|
task.dependencies.concat(Array(options[:wait_for]))
|
|
35
29
|
end
|
|
36
30
|
|
|
37
|
-
@
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@pending_queue.sort_by! { |t| -t.priority }
|
|
41
|
-
# 通知等待的线程有新任务
|
|
42
|
-
@queue_condition.signal
|
|
43
|
-
end
|
|
31
|
+
@pending_queue << task
|
|
32
|
+
# 按优先级排序
|
|
33
|
+
@pending_queue.sort_by! { |t| -t.priority }
|
|
44
34
|
|
|
45
35
|
task.id
|
|
46
36
|
end
|
|
@@ -50,63 +40,60 @@ module Pindo
|
|
|
50
40
|
tasks.map { |task| add_task(task) }
|
|
51
41
|
end
|
|
52
42
|
|
|
53
|
-
#
|
|
43
|
+
# 开始执行(在主线程中顺序执行所有任务)
|
|
54
44
|
def start
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
task
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
45
|
+
# 输出任务执行计划
|
|
46
|
+
print_execution_plan
|
|
47
|
+
|
|
48
|
+
# 主循环:按顺序执行所有任务
|
|
49
|
+
while @pending_queue.any?
|
|
50
|
+
task = get_next_executable_task
|
|
51
|
+
|
|
52
|
+
unless task
|
|
53
|
+
# 检查是否所有任务都因依赖问题无法执行
|
|
54
|
+
if @pending_queue.all? { |t| check_dependencies(t) != :ready }
|
|
55
|
+
Funlog.warning("所有剩余任务都因依赖问题无法执行")
|
|
56
|
+
break
|
|
78
57
|
end
|
|
79
58
|
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
# 在锁外触发任务
|
|
85
|
-
if task
|
|
86
|
-
trigger_task(task)
|
|
59
|
+
# 没有可执行的任务,短暂休眠后重试
|
|
60
|
+
sleep(0.1)
|
|
61
|
+
next
|
|
87
62
|
end
|
|
88
63
|
|
|
89
|
-
#
|
|
90
|
-
|
|
64
|
+
# 执行任务
|
|
65
|
+
execute_task(task)
|
|
91
66
|
end
|
|
92
67
|
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
puts "\n[TaskManager] 所有任务执行完毕".green if defined?(String.green)
|
|
97
|
-
@running = false
|
|
68
|
+
# 输出执行摘要
|
|
69
|
+
print_execution_summary
|
|
98
70
|
end
|
|
99
71
|
|
|
100
|
-
#
|
|
101
|
-
def
|
|
102
|
-
|
|
72
|
+
# 获取执行报告
|
|
73
|
+
def execution_report
|
|
74
|
+
{
|
|
75
|
+
pending: @pending_queue.count,
|
|
76
|
+
completed: @completed_tasks.count,
|
|
77
|
+
success: @completed_tasks.count { |t| t.status == TaskStatus::SUCCESS },
|
|
78
|
+
failed: @completed_tasks.count { |t| t.status == TaskStatus::FAILED },
|
|
79
|
+
tasks: (@pending_queue + @completed_tasks).map do |task|
|
|
80
|
+
{
|
|
81
|
+
id: task.id,
|
|
82
|
+
name: task.name,
|
|
83
|
+
type: task.type,
|
|
84
|
+
status: task.status,
|
|
85
|
+
error: task.error&.message,
|
|
86
|
+
execution_time: task.execution_time
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
}
|
|
103
90
|
end
|
|
104
91
|
|
|
105
|
-
#
|
|
106
|
-
def
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
92
|
+
# 清空所有队列(用于重置)
|
|
93
|
+
def clear_all
|
|
94
|
+
@pending_queue.clear
|
|
95
|
+
@completed_tasks.clear
|
|
96
|
+
@current_task = nil
|
|
110
97
|
end
|
|
111
98
|
|
|
112
99
|
# 获取任务状态
|
|
@@ -121,120 +108,34 @@ module Pindo
|
|
|
121
108
|
task&.cancel
|
|
122
109
|
end
|
|
123
110
|
|
|
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
111
|
private
|
|
152
112
|
|
|
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
|
-
# 获取下一个可执行的任务(带锁版本,向后兼容)
|
|
113
|
+
# 获取下一个可执行的任务
|
|
166
114
|
def get_next_executable_task
|
|
167
|
-
@
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
115
|
+
task = @pending_queue.find { |t| can_execute?(t) }
|
|
116
|
+
@pending_queue.delete(task) if task
|
|
117
|
+
task
|
|
209
118
|
end
|
|
210
119
|
|
|
211
120
|
# 判断任务是否可以执行
|
|
212
121
|
def can_execute?(task)
|
|
213
|
-
#
|
|
122
|
+
# 检查依赖状态
|
|
214
123
|
dependency_check = check_dependencies(task)
|
|
215
124
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
125
|
+
if dependency_check == :failed
|
|
126
|
+
# 依赖失败,标记任务为失败
|
|
127
|
+
mark_task_failed(task, "依赖任务失败")
|
|
128
|
+
return false
|
|
129
|
+
elsif dependency_check == :cancelled
|
|
130
|
+
# 依赖被取消,标记任务为取消
|
|
131
|
+
mark_task_cancelled(task, "依赖任务被取消")
|
|
219
132
|
return false
|
|
220
133
|
elsif dependency_check == :waiting
|
|
221
134
|
return false # 依赖未完成,继续等待
|
|
222
135
|
end
|
|
223
136
|
|
|
224
|
-
#
|
|
225
|
-
|
|
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
|
|
137
|
+
# 依赖已满足,可以执行
|
|
138
|
+
true
|
|
238
139
|
end
|
|
239
140
|
|
|
240
141
|
# 检查依赖状态
|
|
@@ -263,232 +164,181 @@ module Pindo
|
|
|
263
164
|
:ready # 所有依赖都成功完成
|
|
264
165
|
end
|
|
265
166
|
|
|
266
|
-
#
|
|
267
|
-
def
|
|
268
|
-
@
|
|
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
|
|
167
|
+
# 执行任务
|
|
168
|
+
def execute_task(task)
|
|
169
|
+
@current_task = task
|
|
287
170
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
@completed_tasks << task
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# 触发任务执行
|
|
295
|
-
def trigger_task(task)
|
|
296
|
-
# 获取任务锁
|
|
297
|
-
lock_acquired = acquire_lock(task)
|
|
171
|
+
# 设置任务进度回调
|
|
172
|
+
setup_task_callbacks(task)
|
|
298
173
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
@queue_mutex.synchronize do
|
|
302
|
-
@pending_queue.unshift(task) # 放回队列前面
|
|
303
|
-
@queue_condition.signal
|
|
304
|
-
end
|
|
305
|
-
return
|
|
306
|
-
end
|
|
174
|
+
# 显示任务开始信息
|
|
175
|
+
print_task_header(task)
|
|
307
176
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
@running_tasks << task
|
|
312
|
-
end
|
|
177
|
+
begin
|
|
178
|
+
# 在主线程中执行任务
|
|
179
|
+
task.do_task
|
|
313
180
|
|
|
314
|
-
|
|
315
|
-
|
|
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}"
|
|
181
|
+
# 任务成功
|
|
182
|
+
print_task_success(task)
|
|
322
183
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
184
|
+
rescue => e
|
|
185
|
+
# 任务失败
|
|
186
|
+
print_task_failure(task, e)
|
|
326
187
|
end
|
|
327
188
|
|
|
328
|
-
#
|
|
329
|
-
|
|
330
|
-
|
|
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
|
|
189
|
+
# 将任务移到完成队列
|
|
190
|
+
@completed_tasks << task
|
|
191
|
+
@current_task = nil
|
|
336
192
|
|
|
337
|
-
#
|
|
338
|
-
|
|
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
|
|
193
|
+
# 任务完成后输出分隔线
|
|
194
|
+
print_task_footer
|
|
359
195
|
end
|
|
360
196
|
|
|
361
|
-
#
|
|
362
|
-
def
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
@triggered_queue.delete(task)
|
|
366
|
-
@completed_tasks << task
|
|
197
|
+
# 设置任务回调
|
|
198
|
+
def setup_task_callbacks(task)
|
|
199
|
+
# 只在第一次设置回调
|
|
200
|
+
return if task.callbacks_setup
|
|
367
201
|
|
|
368
|
-
|
|
369
|
-
release_lock(task)
|
|
202
|
+
# 主线程执行不需要进度回调
|
|
370
203
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
end
|
|
204
|
+
task.callbacks_setup = true
|
|
205
|
+
end
|
|
374
206
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
|
207
|
+
# 标记任务为失败
|
|
208
|
+
def mark_task_failed(task, reason)
|
|
209
|
+
@pending_queue.delete(task)
|
|
210
|
+
task.status = TaskStatus::FAILED
|
|
211
|
+
task.error = RuntimeError.new(reason)
|
|
212
|
+
@completed_tasks << task
|
|
213
|
+
|
|
214
|
+
Funlog.error("任务 #{task.name} 因#{reason}而被标记为失败")
|
|
392
215
|
end
|
|
393
216
|
|
|
394
|
-
#
|
|
395
|
-
def
|
|
396
|
-
@
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
end
|
|
403
|
-
end
|
|
217
|
+
# 标记任务为取消
|
|
218
|
+
def mark_task_cancelled(task, reason)
|
|
219
|
+
@pending_queue.delete(task)
|
|
220
|
+
task.status = TaskStatus::CANCELLED
|
|
221
|
+
task.error = RuntimeError.new(reason)
|
|
222
|
+
@completed_tasks << task
|
|
223
|
+
|
|
224
|
+
Funlog.warning("任务 #{task.name} 因#{reason}而被取消")
|
|
404
225
|
end
|
|
405
226
|
|
|
406
|
-
#
|
|
407
|
-
def
|
|
408
|
-
@pending_queue
|
|
227
|
+
# 查找任务
|
|
228
|
+
def find_task(task_id)
|
|
229
|
+
all_tasks = @pending_queue + @completed_tasks
|
|
230
|
+
all_tasks << @current_task if @current_task
|
|
231
|
+
all_tasks.find { |t| t.id == task_id }
|
|
409
232
|
end
|
|
410
233
|
|
|
411
|
-
#
|
|
412
|
-
def
|
|
413
|
-
|
|
414
|
-
|
|
234
|
+
# 输出任务执行计划
|
|
235
|
+
def print_execution_plan
|
|
236
|
+
# 按类型分组统计
|
|
237
|
+
tasks_by_type = @pending_queue.group_by(&:type)
|
|
238
|
+
|
|
239
|
+
puts "\n"
|
|
240
|
+
puts "\e[34m" + "=" * 60
|
|
241
|
+
puts " 任务执行计划"
|
|
242
|
+
puts "=" * 60
|
|
243
|
+
|
|
244
|
+
tasks_by_type.each do |type, tasks|
|
|
245
|
+
type_name = get_type_display_name(type)
|
|
246
|
+
puts " #{type_name}: #{tasks.count} 个任务"
|
|
415
247
|
end
|
|
248
|
+
|
|
249
|
+
puts " 总计: #{@pending_queue.count} 个任务"
|
|
250
|
+
puts "=" * 60 + "\e[0m"
|
|
251
|
+
puts "\n"
|
|
416
252
|
end
|
|
417
253
|
|
|
418
|
-
#
|
|
419
|
-
def
|
|
420
|
-
|
|
421
|
-
|
|
254
|
+
# 获取任务类型的显示名称
|
|
255
|
+
def get_type_display_name(type)
|
|
256
|
+
case type
|
|
257
|
+
when :unity_export
|
|
258
|
+
"Unity 导出"
|
|
259
|
+
when :build
|
|
260
|
+
"编译构建"
|
|
261
|
+
when :upload
|
|
262
|
+
"上传发布"
|
|
422
263
|
else
|
|
423
|
-
|
|
264
|
+
type.to_s.capitalize
|
|
424
265
|
end
|
|
266
|
+
end
|
|
425
267
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
268
|
+
# 输出任务执行头部
|
|
269
|
+
def print_task_header(task)
|
|
270
|
+
puts "\n"
|
|
271
|
+
puts "\e[34m" + "*" * 60
|
|
272
|
+
puts " ▶ #{task.name}"
|
|
273
|
+
puts "*" * 60 + "\e[0m"
|
|
432
274
|
end
|
|
433
275
|
|
|
434
|
-
#
|
|
435
|
-
def
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
end
|
|
440
|
-
all_tasks.find { |t| t.id == task_id }
|
|
276
|
+
# 输出任务成功信息
|
|
277
|
+
def print_task_success(task)
|
|
278
|
+
time_str = task.execution_time ? task.execution_time.round(2) : 0
|
|
279
|
+
puts "\n"
|
|
280
|
+
puts "\e[34m" + " ✓ 任务完成: #{task.name} (耗时: #{time_str}秒)" + "\e[0m"
|
|
441
281
|
end
|
|
442
282
|
|
|
443
|
-
#
|
|
444
|
-
def
|
|
445
|
-
|
|
283
|
+
# 输出任务失败信息
|
|
284
|
+
def print_task_failure(task, error)
|
|
285
|
+
puts "\n"
|
|
286
|
+
Funlog.error("任务失败: #{task.name}")
|
|
287
|
+
Funlog.error("错误信息: #{error.message}")
|
|
446
288
|
end
|
|
447
289
|
|
|
448
|
-
#
|
|
449
|
-
def
|
|
450
|
-
|
|
451
|
-
|
|
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
|
|
290
|
+
# 输出任务底部分隔线
|
|
291
|
+
def print_task_footer
|
|
292
|
+
puts "\e[34m" + "*" * 60 + "\e[0m"
|
|
293
|
+
puts ""
|
|
463
294
|
end
|
|
464
295
|
|
|
465
|
-
#
|
|
466
|
-
def
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
296
|
+
# 输出执行摘要
|
|
297
|
+
def print_execution_summary
|
|
298
|
+
success_count = @completed_tasks.count { |t| t.status == TaskStatus::SUCCESS }
|
|
299
|
+
failed_count = @completed_tasks.count { |t| t.status == TaskStatus::FAILED }
|
|
300
|
+
cancelled_count = @completed_tasks.count { |t| t.status == TaskStatus::CANCELLED }
|
|
301
|
+
|
|
302
|
+
# 获取失败和取消的任务
|
|
303
|
+
failed_tasks = @completed_tasks.select { |t| t.status == TaskStatus::FAILED }
|
|
304
|
+
cancelled_tasks = @completed_tasks.select { |t| t.status == TaskStatus::CANCELLED }
|
|
305
|
+
|
|
306
|
+
# 计算总耗时
|
|
307
|
+
total_time = @completed_tasks.map(&:execution_time).compact.sum
|
|
308
|
+
minutes = (total_time / 60).to_i
|
|
309
|
+
seconds = (total_time % 60).to_i
|
|
310
|
+
|
|
311
|
+
puts "\n"
|
|
312
|
+
puts "\e[34m" + "=" * 60
|
|
313
|
+
puts "\e[34m" + " 任务执行完成"
|
|
314
|
+
puts "\e[34m" + "=" * 60
|
|
315
|
+
|
|
316
|
+
# 显示统计信息
|
|
317
|
+
puts "\e[34m" + " 成功: #{success_count} 个任务" + "\e[0m" if success_count > 0
|
|
318
|
+
|
|
319
|
+
if failed_count > 0
|
|
320
|
+
puts "\e[31m" + " 失败: #{failed_count} 个任务" + "\e[0m"
|
|
321
|
+
failed_tasks.each do |task|
|
|
322
|
+
puts "\e[31m" + " - #{task.name}" + "\e[0m"
|
|
323
|
+
end
|
|
474
324
|
end
|
|
475
|
-
end
|
|
476
325
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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
|
|
326
|
+
if cancelled_count > 0
|
|
327
|
+
puts "\e[33m" + " 取消: #{cancelled_count} 个任务" + "\e[0m"
|
|
328
|
+
cancelled_tasks.each do |task|
|
|
329
|
+
puts "\e[33m" + " - #{task.name}" + "\e[0m"
|
|
489
330
|
end
|
|
490
331
|
end
|
|
332
|
+
|
|
333
|
+
if minutes > 0
|
|
334
|
+
puts "\e[34m" + " 总耗时: #{minutes}分#{seconds}秒" + "\e[0m"
|
|
335
|
+
else
|
|
336
|
+
puts "\e[34m" + " 总耗时: #{seconds}秒" + "\e[0m"
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
puts "\e[34m" + "=" * 60 + "\e[0m"
|
|
340
|
+
puts "\n"
|
|
491
341
|
end
|
|
492
342
|
end
|
|
493
343
|
end
|
|
494
|
-
end
|
|
344
|
+
end
|