pindo 5.11.3 → 5.12.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/pindo/command/android/autobuild.rb +111 -184
  3. data/lib/pindo/command/android/build.rb +10 -2
  4. data/lib/pindo/command/ios/autobuild.rb +115 -210
  5. data/lib/pindo/command/ios/build.rb +12 -3
  6. data/lib/pindo/command/jps/upload.rb +257 -117
  7. data/lib/pindo/command/unity/autobuild.rb +308 -220
  8. data/lib/pindo/command/unity.rb +0 -3
  9. data/lib/pindo/command/utils/boss.rb +18 -15
  10. data/lib/pindo/command/utils/clearcert.rb +26 -18
  11. data/lib/pindo/command/utils/device.rb +28 -19
  12. data/lib/pindo/command/utils/feishu.rb +11 -4
  13. data/lib/pindo/command/utils/icon.rb +26 -20
  14. data/lib/pindo/command/utils/renewcert.rb +35 -29
  15. data/lib/pindo/command/utils/renewproj.rb +32 -25
  16. data/lib/pindo/command/utils/repoinit.rb +1 -1
  17. data/lib/pindo/command/utils/tag.rb +6 -180
  18. data/lib/pindo/command/utils/tgate.rb +34 -28
  19. data/lib/pindo/command/utils/xcassets.rb +30 -20
  20. data/lib/pindo/command/web/autobuild.rb +148 -128
  21. data/lib/pindo/module/android/android_build_helper.rb +0 -6
  22. data/lib/pindo/module/android/android_config_helper.rb +4 -26
  23. data/lib/pindo/module/build/build_helper.rb +18 -294
  24. data/lib/pindo/module/build/git_repo_helper.rb +519 -0
  25. data/lib/pindo/module/build/icon_downloader.rb +85 -0
  26. data/lib/pindo/module/pgyer/pgyerhelper.rb +16 -11
  27. data/lib/pindo/module/task/model/build/android_dev_build_task.rb +209 -0
  28. data/lib/pindo/module/task/model/build/android_release_build_task.rb +29 -0
  29. data/lib/pindo/module/task/model/build/ios_adhoc_build_task.rb +53 -0
  30. data/lib/pindo/module/task/model/build/ios_dev_build_task.rb +251 -0
  31. data/lib/pindo/module/task/model/build/ios_release_build_task.rb +53 -0
  32. data/lib/pindo/module/task/model/build/web_dev_build_task.rb +43 -0
  33. data/lib/pindo/module/task/model/build_task.rb +125 -301
  34. data/lib/pindo/module/task/model/git_tag_task.rb +80 -0
  35. data/lib/pindo/module/task/model/unity_export_task.rb +53 -41
  36. data/lib/pindo/module/task/model/upload_task.rb +149 -208
  37. data/lib/pindo/module/task/pindo_task.rb +135 -95
  38. data/lib/pindo/module/task/task_manager.rb +202 -352
  39. data/lib/pindo/module/unity/unity_helper.rb +7 -3
  40. data/lib/pindo/module/xcode/xcode_build_config.rb +4 -10
  41. data/lib/pindo/module/xcode/xcode_build_helper.rb +19 -0
  42. data/lib/pindo/version.rb +1 -1
  43. metadata +10 -4
  44. data/lib/pindo/command/unity/apk.rb +0 -185
  45. data/lib/pindo/command/unity/ipa.rb +0 -198
  46. data/lib/pindo/command/unity/web.rb +0 -163
@@ -1,27 +1,13 @@
1
1
  require 'securerandom'
2
- require 'thread'
3
2
 
4
3
  module Pindo
5
4
  module TaskSystem
6
5
  # 任务取消异常
7
6
  class TaskCancelledException < StandardError; end
8
- # 执行模式:控制并发策略
9
- module ExecutionMode
10
- EXCLUSIVE = :exclusive # 独占:阻塞所有其他任务
11
- TYPE_EXCLUSIVE = :type_exclusive # 类型独占:同类型串行
12
- CONCURRENT = :concurrent # 并发:可与任意任务并行
13
- end
14
-
15
- # 执行类型:控制在哪个线程执行
16
- module ExecutionType
17
- SYNC = :sync # 同步执行(在主线程)
18
- ASYNC = :async # 异步执行(在新线程)
19
- end
20
7
 
21
8
  # 任务状态
22
9
  module TaskStatus
23
10
  PENDING = :pending # 待执行
24
- TRIGGERED = :triggered # 已触发
25
11
  RUNNING = :running # 执行中
26
12
  SUCCESS = :success # 成功
27
13
  FAILED = :failed # 失败
@@ -36,77 +22,72 @@ module Pindo
36
22
  CRITICAL = 15
37
23
  end
38
24
 
39
- # PindoTask 基类
25
+ # 重试模式
26
+ module RetryMode
27
+ IMMEDIATE = :immediate # 立即重试
28
+ DELAYED = :delayed # 延迟重试
29
+ NEXT_TASK = :next_task # 下个任务重试
30
+ end
31
+
32
+ # PindoTask 基类(简化版,所有任务在主线程中执行)
40
33
  class PindoTask
41
- attr_accessor :id, :name, :status, :error, :result, :progress, :progress_message
42
- attr_reader :type, :execution_mode, :execution_type, :priority, :dependencies
43
- attr_accessor :context, :metadata, :thread
34
+ attr_accessor :id, :name, :status, :error, :result
35
+ attr_reader :type, :priority, :dependencies
36
+ attr_accessor :context, :metadata
44
37
  attr_reader :created_at, :started_at, :finished_at
38
+ attr_accessor :retry_count # 剩余重试次数
39
+ attr_reader :retry_mode, :retry_delay
40
+ attr_accessor :callbacks_setup # 标记回调是否已经设置
45
41
 
46
42
  def initialize(name, options = {})
47
43
  @id = SecureRandom.uuid
48
44
  @name = name
49
45
  @type = self.class.task_type
50
- @execution_mode = options[:execution_mode] || self.class.execution_mode
51
- @execution_type = options[:execution_type] || self.class.execution_type
52
- @priority = options[:priority] || TaskPriority::NORMAL
46
+ @priority = options[:priority] || TaskPriority::HIGH
53
47
  @status = TaskStatus::PENDING
54
48
  @dependencies = options[:dependencies] || []
55
49
  @context = options[:context] || {}
56
50
  @metadata = options[:metadata] || {}
57
- @progress = 0
58
- @progress_message = nil
59
51
  @error = nil
60
52
  @result = nil
61
- @thread = nil # 执行线程
62
53
  @created_at = Time.now
63
54
  @started_at = nil
64
55
  @finished_at = nil
65
- @mutex = Mutex.new
66
- @condition = ConditionVariable.new
67
56
  @callbacks = {
68
57
  before: [],
69
58
  after: [],
70
59
  on_success: [],
71
- on_failure: [],
72
- on_progress: []
60
+ on_failure: []
73
61
  }
62
+ @callbacks_setup = false
63
+
64
+ # 重试配置
65
+ @retry_mode = options[:retry_mode] || self.class.default_retry_mode
66
+ @retry_count = options[:retry_count] || self.class.default_retry_count
67
+ @retry_delay = options[:retry_delay] || self.class.default_retry_delay
74
68
  end
75
69
 
76
- # 子类配置
70
+ # 子类必须实现的方法
77
71
  def self.task_type
78
72
  raise NotImplementedError, "Subclass must define task_type"
79
73
  end
80
74
 
81
- def self.execution_mode
82
- ExecutionMode::TYPE_EXCLUSIVE # 默认同类型串行
75
+ # 默认重试配置
76
+ def self.default_retry_mode
77
+ RetryMode::IMMEDIATE
83
78
  end
84
79
 
85
- def self.execution_type
86
- ExecutionType::ASYNC # 默认异步执行
80
+ def self.default_retry_count
81
+ 0 # 默认不重试
87
82
  end
88
83
 
89
- # 同步执行(在当前线程)
90
- def do_task
91
- execute_internal
84
+ def self.default_retry_delay
85
+ 10 # 默认延迟 10 秒
92
86
  end
93
87
 
94
- # 异步执行(在新线程)
95
- def async_do_task
96
- @thread = Thread.new do
97
- begin
98
- execute_internal
99
- rescue => e
100
- @error = e
101
- @status = TaskStatus::FAILED
102
- puts "[Task Error] #{@name}: #{e.message}".red if defined?(String.red)
103
- end
104
- end
105
- end
106
-
107
- # 等待异步任务完成
108
- def wait
109
- @thread&.join
88
+ # 执行任务(在主线程中同步执行)
89
+ def do_task
90
+ execute_internal
110
91
  end
111
92
 
112
93
  # 检查是否完成
@@ -126,14 +107,11 @@ module Pindo
126
107
 
127
108
  # 取消任务
128
109
  def cancel
129
- @mutex.synchronize do
130
- if @status == TaskStatus::PENDING || @status == TaskStatus::TRIGGERED
131
- @status = TaskStatus::CANCELLED
132
- @condition.signal
133
- true
134
- else
135
- false
136
- end
110
+ if @status == TaskStatus::PENDING
111
+ @status = TaskStatus::CANCELLED
112
+ true
113
+ else
114
+ false
137
115
  end
138
116
  end
139
117
 
@@ -144,16 +122,6 @@ module Pindo
144
122
  end_time - @started_at
145
123
  end
146
124
 
147
- # 更新进度
148
- def update_progress(value, message = nil)
149
- # 检查是否已取消
150
- check_cancelled!
151
-
152
- @progress = value.clamp(0, 100)
153
- @progress_message = message
154
- run_callbacks(:on_progress)
155
- end
156
-
157
125
  # 检查是否已取消,如果已取消则抛出异常
158
126
  def check_cancelled!
159
127
  if @status == TaskStatus::CANCELLED
@@ -171,6 +139,26 @@ module Pindo
171
139
  @callbacks[event] << block if @callbacks[event]
172
140
  end
173
141
 
142
+ # 重试相关方法
143
+ def retryable?
144
+ @retry_count > 0
145
+ end
146
+
147
+ def should_retry?(error)
148
+ true # 默认所有错误都重试,子类可重写
149
+ end
150
+
151
+ def before_retry
152
+ # 子类可重写,进行重试前的清理工作
153
+ end
154
+
155
+ def reset_for_retry
156
+ @status = TaskStatus::PENDING
157
+ @result = nil
158
+ @started_at = nil
159
+ @finished_at = nil
160
+ end
161
+
174
162
  protected
175
163
 
176
164
  # 子类必须实现
@@ -183,48 +171,100 @@ module Pindo
183
171
  # 内部执行逻辑
184
172
  def execute_internal
185
173
  begin
186
- @mutex.synchronize do
187
- return if @status == TaskStatus::CANCELLED
188
- @status = TaskStatus::RUNNING
189
- @started_at = Time.now
190
- end
174
+ @status = TaskStatus::RUNNING
175
+ @started_at = Time.now
191
176
 
192
177
  run_callbacks(:before)
193
178
 
194
179
  # 子类实现具体逻辑
195
180
  @result = do_work
196
181
 
197
- @mutex.synchronize do
198
- @status = TaskStatus::SUCCESS
199
- @condition.signal
200
- end
182
+ @status = TaskStatus::SUCCESS
201
183
 
202
184
  run_callbacks(:on_success)
203
185
  rescue TaskCancelledException => e
204
186
  # 任务被取消
205
- @mutex.synchronize do
206
- @status = TaskStatus::CANCELLED
207
- @error = e
208
- @condition.signal
209
- end
210
-
187
+ @status = TaskStatus::CANCELLED
188
+ @error = e
211
189
  puts "[Task] #{@name} 已被取消".yellow if defined?(String.yellow)
212
- # 不抛出异常,正常结束
213
190
  rescue => e
214
- @mutex.synchronize do
215
- @error = e
216
- @status = TaskStatus::FAILED
217
- @condition.signal
218
- end
219
-
220
- run_callbacks(:on_failure)
221
- raise if should_raise_on_failure?
191
+ handle_failure(e)
222
192
  ensure
223
193
  @finished_at = Time.now
224
194
  run_callbacks(:after)
225
195
  end
226
196
  end
227
197
 
198
+ # 处理失败
199
+ def handle_failure(error)
200
+ @error = error
201
+
202
+ # 判断是否可以重试
203
+ if retryable? && should_retry?(error)
204
+ # 递减重试次数
205
+ @retry_count -= 1
206
+
207
+ # 根据重试模式处理
208
+ case @retry_mode
209
+ when RetryMode::IMMEDIATE
210
+ handle_immediate_retry
211
+ when RetryMode::DELAYED
212
+ handle_delayed_retry
213
+ when RetryMode::NEXT_TASK
214
+ handle_next_task_retry
215
+ else
216
+ finalize_failure
217
+ end
218
+ else
219
+ finalize_failure
220
+ end
221
+ end
222
+
223
+ # 立即重试
224
+ def handle_immediate_retry
225
+ puts "⚠️ 任务失败,立即重试 (剩余#{@retry_count}次)".yellow if defined?(String.yellow)
226
+ puts " 错误: #{@error.message}"
227
+
228
+ before_retry
229
+ reset_for_retry
230
+ execute_internal
231
+ end
232
+
233
+ # 延迟重试
234
+ def handle_delayed_retry
235
+ puts "⚠️ 任务失败,延迟重试 (剩余#{@retry_count}次)".yellow if defined?(String.yellow)
236
+ puts " 错误: #{@error.message}"
237
+ puts " 延迟: #{@retry_delay}秒"
238
+
239
+ before_retry
240
+ sleep(@retry_delay) if @retry_delay > 0
241
+
242
+ reset_for_retry
243
+ execute_internal
244
+ end
245
+
246
+ # 下个任务重试
247
+ def handle_next_task_retry
248
+ puts "⚠️ 任务失败,下个任务重试 (剩余#{@retry_count}次)".yellow if defined?(String.yellow)
249
+ puts " 错误: #{@error.message}"
250
+
251
+ before_retry
252
+ @status = TaskStatus::FAILED
253
+ run_callbacks(:on_failure)
254
+ raise @error if should_raise_on_failure?
255
+ end
256
+
257
+ # 最终失败
258
+ def finalize_failure
259
+ @status = TaskStatus::FAILED
260
+
261
+ puts "[Task] #{@name} 最终失败".red if defined?(String.red)
262
+ puts " 错误: #{@error.message}".red if defined?(String.red)
263
+
264
+ run_callbacks(:on_failure)
265
+ raise @error if should_raise_on_failure?
266
+ end
267
+
228
268
  def run_callbacks(event)
229
269
  @callbacks[event].each { |cb| cb.call(self) }
230
270
  end
@@ -234,4 +274,4 @@ module Pindo
234
274
  end
235
275
  end
236
276
  end
237
- end
277
+ end