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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/base/githelper.rb +16 -0
  3. data/lib/pindo/base/pindocontext.rb +13 -4
  4. data/lib/pindo/command/android/autobuild.rb +108 -185
  5. data/lib/pindo/command/android/build.rb +10 -2
  6. data/lib/pindo/command/ios/autobuild.rb +116 -213
  7. data/lib/pindo/command/ios/build.rb +12 -3
  8. data/lib/pindo/command/jps/upload.rb +253 -118
  9. data/lib/pindo/command/unity/autobuild.rb +297 -227
  10. data/lib/pindo/command/unity.rb +0 -3
  11. data/lib/pindo/command/utils/boss.rb +18 -15
  12. data/lib/pindo/command/utils/clearcert.rb +26 -18
  13. data/lib/pindo/command/utils/device.rb +28 -19
  14. data/lib/pindo/command/utils/feishu.rb +11 -4
  15. data/lib/pindo/command/utils/icon.rb +26 -20
  16. data/lib/pindo/command/utils/renewcert.rb +35 -29
  17. data/lib/pindo/command/utils/renewproj.rb +32 -25
  18. data/lib/pindo/command/utils/repoinit.rb +1 -1
  19. data/lib/pindo/command/utils/tag.rb +6 -180
  20. data/lib/pindo/command/utils/tgate.rb +34 -28
  21. data/lib/pindo/command/utils/xcassets.rb +30 -20
  22. data/lib/pindo/command/web/autobuild.rb +148 -128
  23. data/lib/pindo/module/android/android_build_helper.rb +0 -6
  24. data/lib/pindo/module/android/android_config_helper.rb +4 -26
  25. data/lib/pindo/module/build/build_helper.rb +18 -294
  26. data/lib/pindo/module/build/git_repo_helper.rb +530 -0
  27. data/lib/pindo/module/build/icon_downloader.rb +85 -0
  28. data/lib/pindo/module/pgyer/pgyerhelper.rb +16 -11
  29. data/lib/pindo/module/task/model/build/android_dev_build_task.rb +209 -0
  30. data/lib/pindo/module/task/model/build/android_release_build_task.rb +29 -0
  31. data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +53 -0
  32. data/lib/pindo/module/task/model/build/ios_dev_build_task.rb +251 -0
  33. data/lib/pindo/module/task/model/build/ios_release_build_task.rb +53 -0
  34. data/lib/pindo/module/task/model/build/web_dev_build_task.rb +43 -0
  35. data/lib/pindo/module/task/model/build_task.rb +125 -301
  36. data/lib/pindo/module/task/model/git_tag_task.rb +80 -0
  37. data/lib/pindo/module/task/model/unity_export_task.rb +53 -41
  38. data/lib/pindo/module/task/model/upload_task.rb +149 -208
  39. data/lib/pindo/module/task/pindo_task.rb +135 -95
  40. data/lib/pindo/module/task/task_manager.rb +202 -352
  41. data/lib/pindo/module/unity/unity_helper.rb +7 -3
  42. data/lib/pindo/module/xcode/xcode_build_config.rb +4 -10
  43. data/lib/pindo/module/xcode/xcode_build_helper.rb +19 -0
  44. data/lib/pindo/version.rb +1 -1
  45. metadata +10 -4
  46. data/lib/pindo/command/unity/apk.rb +0 -185
  47. data/lib/pindo/command/unity/ipa.rb +0 -198
  48. data/lib/pindo/command/unity/web.rb +0 -163
@@ -1,23 +1,17 @@
1
1
  require 'singleton'
2
- require 'thread'
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
- @task_locks = {
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
- @queue_mutex.synchronize do
38
- @pending_queue << task
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
- 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
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
- break if should_stop_locked? && task.nil?
82
- end
83
-
84
- # 在锁外触发任务
85
- if task
86
- trigger_task(task)
59
+ # 没有可执行的任务,短暂休眠后重试
60
+ sleep(0.1)
61
+ next
87
62
  end
88
63
 
89
- # 清理已完成的异步任务
90
- cleanup_finished_tasks
64
+ # 执行任务
65
+ execute_task(task)
91
66
  end
92
67
 
93
- # 等待所有触发的任务完成
94
- wait_all_triggered_tasks
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 stop
102
- @running = false
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 wait_all
107
- while @pending_queue.any? || @running_tasks.any?
108
- sleep(0.1)
109
- end
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
- @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
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
- # 1. 检查依赖状态
122
+ # 检查依赖状态
214
123
  dependency_check = check_dependencies(task)
215
124
 
216
- # 如果依赖检查返回 :failed 或 :cancelled,级联处理
217
- if dependency_check == :failed || dependency_check == :cancelled
218
- cascade_failure(task, dependency_check)
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
- # 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
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 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
167
+ # 执行任务
168
+ def execute_task(task)
169
+ @current_task = task
287
170
 
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)
171
+ # 设置任务进度回调
172
+ setup_task_callbacks(task)
298
173
 
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
174
+ # 显示任务开始信息
175
+ print_task_header(task)
307
176
 
308
- @queue_mutex.synchronize do
309
- task.status = TaskStatus::TRIGGERED
310
- @triggered_queue << task
311
- @running_tasks << task
312
- end
177
+ begin
178
+ # 在主线程中执行任务
179
+ task.do_task
313
180
 
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}"
181
+ # 任务成功
182
+ print_task_success(task)
322
183
 
323
- # 设置任务完成回调
324
- task.on(:after) do |t|
325
- on_task_finished(t)
184
+ rescue => e
185
+ # 任务失败
186
+ print_task_failure(task, e)
326
187
  end
327
188
 
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
189
+ # 将任务移到完成队列
190
+ @completed_tasks << task
191
+ @current_task = nil
336
192
 
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
193
+ # 任务完成后输出分隔线
194
+ print_task_footer
359
195
  end
360
196
 
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
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
- @queue_condition.signal
373
- end
204
+ task.callbacks_setup = true
205
+ end
374
206
 
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
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 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
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 should_stop_locked?
408
- @pending_queue.empty? && @running_tasks.empty?
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 should_stop?
413
- @queue_mutex.synchronize do
414
- should_stop_locked?
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 wait_all_triggered_tasks
420
- if defined?(String.yellow)
421
- puts "\n等待所有异步任务完成...".yellow
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
- puts "\n等待所有异步任务完成..."
264
+ type.to_s.capitalize
424
265
  end
266
+ end
425
267
 
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
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 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 }
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 type_lock(type)
445
- @task_locks[:type_locks][type] ||= Mutex.new
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 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
290
+ # 输出任务底部分隔线
291
+ def print_task_footer
292
+ puts "\e[34m" + "*" * 60 + "\e[0m"
293
+ puts ""
463
294
  end
464
295
 
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
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
- 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
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