taski 0.5.0 → 0.7.0
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/CHANGELOG.md +50 -0
- data/README.md +40 -21
- data/docs/GUIDE.md +340 -0
- data/examples/README.md +65 -17
- data/examples/{context_demo.rb → args_demo.rb} +27 -27
- data/examples/clean_demo.rb +204 -0
- data/examples/group_demo.rb +113 -0
- data/examples/reexecution_demo.rb +93 -80
- data/examples/system_call_demo.rb +56 -0
- data/lib/taski/{context.rb → args.rb} +3 -3
- data/lib/taski/execution/execution_context.rb +379 -0
- data/lib/taski/execution/executor.rb +408 -117
- data/lib/taski/execution/registry.rb +17 -1
- data/lib/taski/execution/scheduler.rb +308 -0
- data/lib/taski/execution/task_output_pipe.rb +42 -0
- data/lib/taski/execution/task_output_router.rb +216 -0
- data/lib/taski/execution/task_wrapper.rb +210 -40
- data/lib/taski/execution/tree_progress_display.rb +385 -98
- data/lib/taski/execution/worker_pool.rb +104 -0
- data/lib/taski/section.rb +16 -3
- data/lib/taski/task.rb +222 -36
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +138 -23
- data/sig/taski.rbs +207 -27
- metadata +13 -7
- data/docs/advanced-features.md +0 -625
- data/docs/api-guide.md +0 -509
- data/docs/error-handling.md +0 -684
- data/examples/section_progress_demo.rb +0 -78
data/sig/taski.rbs
CHANGED
|
@@ -3,7 +3,8 @@ module Taski
|
|
|
3
3
|
|
|
4
4
|
self.@global_registry: Execution::Registry?
|
|
5
5
|
self.@progress_display: Execution::TreeProgressDisplay?
|
|
6
|
-
self.@
|
|
6
|
+
self.@args: Args?
|
|
7
|
+
self.@args_monitor: Monitor
|
|
7
8
|
|
|
8
9
|
# Type alias for Task class (singleton type with class methods)
|
|
9
10
|
# This represents a Class that inherits from Taski::Task
|
|
@@ -15,9 +16,10 @@ module Taski
|
|
|
15
16
|
def self.progress_display: () -> Execution::TreeProgressDisplay?
|
|
16
17
|
def self.progress_disabled?: () -> bool
|
|
17
18
|
def self.reset_progress_display!: () -> void
|
|
18
|
-
def self.
|
|
19
|
-
def self.
|
|
20
|
-
def self.
|
|
19
|
+
def self.args: () -> Args?
|
|
20
|
+
def self.start_args: (options: Hash[Symbol, untyped], root_task: Class) -> void
|
|
21
|
+
def self.reset_args!: () -> void
|
|
22
|
+
def self.args_worker_count: () -> Integer?
|
|
21
23
|
|
|
22
24
|
# Custom exceptions
|
|
23
25
|
class TaskAbortException < StandardError
|
|
@@ -31,8 +33,52 @@ module Taski
|
|
|
31
33
|
def initialize: (Array[Array[Class]] cyclic_tasks) -> void
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
#
|
|
35
|
-
class
|
|
36
|
+
# Represents a single task failure with its context
|
|
37
|
+
class TaskFailure
|
|
38
|
+
@task_class: Class
|
|
39
|
+
@error: Exception
|
|
40
|
+
|
|
41
|
+
attr_reader task_class: Class
|
|
42
|
+
attr_reader error: Exception
|
|
43
|
+
|
|
44
|
+
def initialize: (task_class: Class, error: Exception) -> void
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Mixin for exception classes to enable transparent rescue matching with AggregateError
|
|
48
|
+
module AggregateAware
|
|
49
|
+
def ===: (untyped other) -> bool
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Base class for task-specific error wrappers
|
|
53
|
+
class TaskError < StandardError
|
|
54
|
+
extend AggregateAware
|
|
55
|
+
|
|
56
|
+
@cause: Exception
|
|
57
|
+
@task_class: Class
|
|
58
|
+
|
|
59
|
+
attr_reader cause: Exception
|
|
60
|
+
attr_reader task_class: Class
|
|
61
|
+
|
|
62
|
+
def initialize: (Exception cause, task_class: Class) -> void
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Raised when multiple tasks fail during parallel execution
|
|
66
|
+
class AggregateError < StandardError
|
|
67
|
+
@errors: Array[TaskFailure]
|
|
68
|
+
|
|
69
|
+
attr_reader errors: Array[TaskFailure]
|
|
70
|
+
|
|
71
|
+
def initialize: (Array[TaskFailure] errors) -> void
|
|
72
|
+
def cause: () -> Exception?
|
|
73
|
+
def includes?: (Class exception_class) -> bool
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def build_message: () -> String
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Args class for execution arguments management
|
|
81
|
+
class Args
|
|
36
82
|
@options: Hash[Symbol | String, untyped]
|
|
37
83
|
@root_task: Class
|
|
38
84
|
@started_at: Time
|
|
@@ -55,13 +101,15 @@ module Taski
|
|
|
55
101
|
self.@circular_dependency_checked: bool
|
|
56
102
|
|
|
57
103
|
# Class methods
|
|
104
|
+
def self.inherited: (Class subclass) -> void
|
|
58
105
|
def self.exports: (*Symbol names) -> void
|
|
59
106
|
def self.exported_methods: () -> Array[Symbol]
|
|
60
107
|
def self.new: () -> Execution::TaskWrapper
|
|
61
108
|
def self.cached_dependencies: () -> Set[task_class]
|
|
62
109
|
def self.clear_dependency_cache: () -> void
|
|
63
|
-
def self.run: (?
|
|
64
|
-
def self.clean: (?
|
|
110
|
+
def self.run: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> untyped
|
|
111
|
+
def self.clean: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> void
|
|
112
|
+
def self.run_and_clean: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> untyped
|
|
65
113
|
def self.registry: () -> Execution::Registry
|
|
66
114
|
def self.reset!: () -> void
|
|
67
115
|
def self.tree: () -> String
|
|
@@ -69,6 +117,7 @@ module Taski
|
|
|
69
117
|
# Instance methods
|
|
70
118
|
def run: () -> void
|
|
71
119
|
def clean: () -> void
|
|
120
|
+
def system: (*untyped args, **untyped opts) -> bool?
|
|
72
121
|
def reset!: () -> void
|
|
73
122
|
|
|
74
123
|
private
|
|
@@ -78,6 +127,7 @@ module Taski
|
|
|
78
127
|
def self.define_instance_reader: (Symbol method_name) -> void
|
|
79
128
|
def self.define_class_accessor: (Symbol method_name) -> void
|
|
80
129
|
def self.validate_no_circular_dependencies!: () -> void
|
|
130
|
+
def self.validate_workers!: (untyped workers) -> void
|
|
81
131
|
end
|
|
82
132
|
|
|
83
133
|
# Section class for abstraction layers (inherits from Task)
|
|
@@ -129,43 +179,166 @@ module Taski
|
|
|
129
179
|
def request_abort!: () -> void
|
|
130
180
|
def abort_requested?: () -> bool
|
|
131
181
|
def run: (Class task_class, Array[Symbol] exported_methods) -> untyped
|
|
182
|
+
def failed_wrappers: () -> Array[TaskWrapper]
|
|
183
|
+
def failed_clean_wrappers: () -> Array[TaskWrapper]
|
|
132
184
|
end
|
|
133
185
|
|
|
134
|
-
#
|
|
135
|
-
class
|
|
186
|
+
# ExecutionContext manages execution state and notifies observers about execution events
|
|
187
|
+
class ExecutionContext
|
|
188
|
+
THREAD_LOCAL_KEY: Symbol
|
|
189
|
+
|
|
190
|
+
@monitor: Monitor
|
|
191
|
+
@observers: Array[untyped]
|
|
192
|
+
@execution_trigger: (^(Class, Registry) -> void)?
|
|
193
|
+
@clean_trigger: (^(Class, Registry) -> void)?
|
|
194
|
+
@output_capture: TaskOutputRouter?
|
|
195
|
+
@original_stdout: IO?
|
|
196
|
+
@runtime_dependencies: Hash[Class, Set[Class]]
|
|
197
|
+
|
|
198
|
+
def self.current: () -> ExecutionContext?
|
|
199
|
+
def self.current=: (ExecutionContext? context) -> void
|
|
200
|
+
|
|
201
|
+
def initialize: () -> void
|
|
202
|
+
def output_capture_active?: () -> bool
|
|
203
|
+
def setup_output_capture: (IO output_io) -> void
|
|
204
|
+
def teardown_output_capture: () -> void
|
|
205
|
+
def output_capture: () -> TaskOutputRouter?
|
|
206
|
+
def execution_trigger=: ((^(Class, Registry) -> void)? trigger) -> void
|
|
207
|
+
def clean_trigger=: ((^(Class, Registry) -> void)? trigger) -> void
|
|
208
|
+
def trigger_execution: (Class task_class, registry: Registry) -> void
|
|
209
|
+
def trigger_clean: (Class task_class, registry: Registry) -> untyped
|
|
210
|
+
def register_runtime_dependency: (Class from_class, Class to_class) -> void
|
|
211
|
+
def runtime_dependencies: () -> Hash[Class, Set[Class]]
|
|
212
|
+
def add_observer: (untyped observer) -> void
|
|
213
|
+
def remove_observer: (untyped observer) -> void
|
|
214
|
+
def observers: () -> Array[untyped]
|
|
215
|
+
def notify_task_registered: (Class task_class) -> void
|
|
216
|
+
def notify_task_started: (Class task_class) -> void
|
|
217
|
+
def notify_task_completed: (Class task_class, ?duration: Float?, ?error: Exception?) -> void
|
|
218
|
+
def notify_section_impl_selected: (Class section_class, Class impl_class) -> void
|
|
219
|
+
def notify_set_root_task: (Class task_class) -> void
|
|
220
|
+
def notify_set_output_capture: (TaskOutputRouter output_capture) -> void
|
|
221
|
+
def notify_start: () -> void
|
|
222
|
+
def notify_stop: () -> void
|
|
223
|
+
def notify_clean_started: (Class task_class) -> void
|
|
224
|
+
def notify_clean_completed: (Class task_class, ?duration: Float?, ?error: Exception?) -> void
|
|
225
|
+
|
|
226
|
+
private
|
|
227
|
+
|
|
228
|
+
def dispatch: (Symbol method_name, *untyped args, **untyped kwargs) -> void
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# TaskOutputRouter for routing task output
|
|
232
|
+
class TaskOutputRouter
|
|
233
|
+
def initialize: (IO original_io) -> void
|
|
234
|
+
def current_write_io: () -> IO?
|
|
235
|
+
def start_capture: (Class task_class) -> void
|
|
236
|
+
def stop_capture: () -> void
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Scheduler manages task dependency state and determines execution order
|
|
240
|
+
class Scheduler
|
|
136
241
|
STATE_PENDING: Symbol
|
|
137
242
|
STATE_ENQUEUED: Symbol
|
|
138
243
|
STATE_COMPLETED: Symbol
|
|
244
|
+
CLEAN_STATE_PENDING: Symbol
|
|
245
|
+
CLEAN_STATE_ENQUEUED: Symbol
|
|
246
|
+
CLEAN_STATE_COMPLETED: Symbol
|
|
139
247
|
|
|
140
|
-
@registry: Registry
|
|
141
|
-
@worker_count: Integer
|
|
142
|
-
@execution_queue: Thread::Queue
|
|
143
|
-
@completion_queue: Thread::Queue
|
|
144
|
-
@workers: Array[Thread]
|
|
145
248
|
@dependencies: Hash[Class, Set[Class]]
|
|
146
249
|
@task_states: Hash[Class, Symbol]
|
|
147
250
|
@completed_tasks: Set[Class]
|
|
251
|
+
@reverse_dependencies: Hash[Class, Set[Class]]
|
|
252
|
+
@clean_task_states: Hash[Class, Symbol]
|
|
253
|
+
@clean_completed_tasks: Set[Class]
|
|
148
254
|
|
|
149
|
-
def
|
|
150
|
-
def
|
|
151
|
-
def
|
|
255
|
+
def initialize: () -> void
|
|
256
|
+
def build_dependency_graph: (Class root_task_class) -> void
|
|
257
|
+
def next_ready_tasks: () -> Array[Class]
|
|
258
|
+
def mark_enqueued: (Class task_class) -> void
|
|
259
|
+
def mark_completed: (Class task_class) -> void
|
|
260
|
+
def completed?: (Class task_class) -> bool
|
|
261
|
+
def running_tasks?: () -> bool
|
|
262
|
+
def merge_runtime_dependencies: (Hash[Class, Set[Class]] runtime_deps) -> void
|
|
263
|
+
def build_reverse_dependency_graph: (Class root_task_class) -> void
|
|
264
|
+
def next_ready_clean_tasks: () -> Array[Class]
|
|
265
|
+
def mark_clean_enqueued: (Class task_class) -> void
|
|
266
|
+
def mark_clean_completed: (Class task_class) -> void
|
|
267
|
+
def clean_completed?: (Class task_class) -> bool
|
|
268
|
+
def running_clean_tasks?: () -> bool
|
|
269
|
+
|
|
270
|
+
private
|
|
271
|
+
|
|
272
|
+
def ready_to_execute?: (Class task_class) -> bool
|
|
273
|
+
def ready_to_clean?: (Class task_class) -> bool
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# WorkerPool manages a pool of worker threads that execute tasks
|
|
277
|
+
class WorkerPool
|
|
278
|
+
attr_reader execution_queue: Thread::Queue
|
|
279
|
+
|
|
280
|
+
@worker_count: Integer
|
|
281
|
+
@registry: Registry
|
|
282
|
+
@on_execute: ^(Class, TaskWrapper) -> void
|
|
283
|
+
@execution_queue: Thread::Queue
|
|
284
|
+
@workers: Array[Thread]
|
|
285
|
+
|
|
286
|
+
def initialize: (registry: Registry, ?worker_count: Integer?) { (Class, TaskWrapper) -> void } -> void
|
|
287
|
+
def start: () -> void
|
|
288
|
+
def enqueue: (Class task_class, TaskWrapper wrapper) -> void
|
|
289
|
+
def shutdown: () -> void
|
|
290
|
+
def enqueue_shutdown_signals: () -> void
|
|
152
291
|
|
|
153
292
|
private
|
|
154
293
|
|
|
155
294
|
def default_worker_count: () -> Integer
|
|
156
|
-
def
|
|
295
|
+
def worker_loop: () -> void
|
|
296
|
+
def debug_log: (String message) -> void
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Executor class for parallel task execution (Producer-Consumer pattern)
|
|
300
|
+
class Executor
|
|
301
|
+
@registry: Registry
|
|
302
|
+
@completion_queue: Thread::Queue
|
|
303
|
+
@execution_context: ExecutionContext
|
|
304
|
+
@scheduler: Scheduler
|
|
305
|
+
@effective_worker_count: Integer?
|
|
306
|
+
@worker_pool: WorkerPool
|
|
307
|
+
@clean_worker_pool: WorkerPool?
|
|
308
|
+
|
|
309
|
+
def self.execute: (Class root_task_class, registry: Registry, ?execution_context: ExecutionContext?) -> void
|
|
310
|
+
def self.execute_clean: (Class root_task_class, registry: Registry, ?execution_context: ExecutionContext?) -> void
|
|
311
|
+
def initialize: (registry: Registry, ?worker_count: Integer?, ?execution_context: ExecutionContext?) -> void
|
|
312
|
+
def execute: (Class root_task_class) -> void
|
|
313
|
+
def execute_clean: (Class root_task_class) -> void
|
|
314
|
+
|
|
315
|
+
private
|
|
316
|
+
|
|
157
317
|
def enqueue_ready_tasks: () -> void
|
|
158
|
-
def ready_to_execute?: (Class task_class) -> bool
|
|
159
318
|
def enqueue_task: (Class task_class) -> void
|
|
160
319
|
def get_or_create_wrapper: (Class task_class) -> TaskWrapper
|
|
161
|
-
def start_workers: () -> void
|
|
162
|
-
def worker_loop: () -> void
|
|
163
320
|
def execute_task: (Class task_class, TaskWrapper wrapper) -> void
|
|
164
321
|
def run_main_loop: (Class root_task_class) -> void
|
|
165
|
-
def no_running_tasks?: () -> bool
|
|
166
322
|
def handle_completion: (Hash[Symbol, untyped] event) -> void
|
|
167
|
-
def
|
|
323
|
+
def enqueue_ready_clean_tasks: () -> void
|
|
324
|
+
def enqueue_clean_task: (Class task_class) -> void
|
|
325
|
+
def execute_clean_task: (Class task_class, TaskWrapper wrapper) -> void
|
|
326
|
+
def run_clean_main_loop: (Class root_task_class) -> void
|
|
327
|
+
def handle_clean_completion: (Hash[Symbol, untyped] event) -> void
|
|
328
|
+
def all_tasks_cleaned?: () -> bool
|
|
329
|
+
def setup_progress_display: (Class root_task_class) -> void
|
|
330
|
+
def setup_output_capture_if_needed: () -> bool
|
|
331
|
+
def teardown_output_capture: () -> void
|
|
332
|
+
def start_progress_display: () -> void
|
|
333
|
+
def stop_progress_display: () -> void
|
|
334
|
+
def create_default_execution_context: () -> ExecutionContext
|
|
168
335
|
def debug_log: (String message) -> void
|
|
336
|
+
def raise_if_any_failures: () -> void
|
|
337
|
+
def flatten_failures: (Array[TaskWrapper] failed_wrappers) -> Array[TaskFailure]
|
|
338
|
+
def wrap_with_task_error: (Class task_class, Exception error) -> TaskError
|
|
339
|
+
def raise_if_any_clean_failures: () -> void
|
|
340
|
+
def flatten_clean_failures: (Array[TaskWrapper] failed_wrappers) -> Array[TaskFailure]
|
|
341
|
+
def error_identity: (Exception error) -> Integer
|
|
169
342
|
end
|
|
170
343
|
|
|
171
344
|
# TaskWrapper class for task execution
|
|
@@ -173,13 +346,16 @@ module Taski
|
|
|
173
346
|
attr_reader task: Task
|
|
174
347
|
attr_reader result: untyped
|
|
175
348
|
attr_reader error: StandardError?
|
|
349
|
+
attr_reader clean_error: StandardError?
|
|
176
350
|
attr_reader timing: TaskTiming?
|
|
177
351
|
|
|
178
352
|
@task: Task
|
|
179
353
|
@registry: Registry
|
|
354
|
+
@execution_context: ExecutionContext?
|
|
180
355
|
@result: untyped
|
|
181
356
|
@clean_result: untyped
|
|
182
357
|
@error: StandardError?
|
|
358
|
+
@clean_error: StandardError?
|
|
183
359
|
@monitor: Monitor
|
|
184
360
|
@condition: MonitorMixin::ConditionVariable
|
|
185
361
|
@clean_condition: MonitorMixin::ConditionVariable
|
|
@@ -190,18 +366,24 @@ module Taski
|
|
|
190
366
|
STATE_PENDING: Symbol
|
|
191
367
|
STATE_RUNNING: Symbol
|
|
192
368
|
STATE_COMPLETED: Symbol
|
|
369
|
+
STATE_FAILED: Symbol
|
|
193
370
|
|
|
194
|
-
def initialize: (Task task, registry: Registry) -> void
|
|
371
|
+
def initialize: (Task task, registry: Registry, ?execution_context: ExecutionContext?) -> void
|
|
195
372
|
def state: () -> Symbol
|
|
196
373
|
def pending?: () -> bool
|
|
197
374
|
def completed?: () -> bool
|
|
375
|
+
def failed?: () -> bool
|
|
376
|
+
def clean_failed?: () -> bool
|
|
198
377
|
def run: () -> untyped
|
|
199
378
|
def clean: () -> untyped
|
|
379
|
+
def run_and_clean: () -> untyped
|
|
200
380
|
def get_exported_value: (Symbol method_name) -> untyped
|
|
201
381
|
def mark_running: () -> bool
|
|
202
382
|
def mark_completed: (untyped result) -> void
|
|
203
383
|
def mark_failed: (StandardError error) -> void
|
|
384
|
+
def mark_clean_running: () -> bool
|
|
204
385
|
def mark_clean_completed: (untyped result) -> void
|
|
386
|
+
def mark_clean_failed: (StandardError error) -> void
|
|
205
387
|
def wait_for_completion: () -> void
|
|
206
388
|
def wait_for_clean_completion: () -> void
|
|
207
389
|
def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
|
|
@@ -288,10 +470,8 @@ module Taski
|
|
|
288
470
|
def render_children: (Hash[Symbol, untyped] node, String prefix, Array[String] lines, Class parent_task_class, bool ancestor_selected) -> void
|
|
289
471
|
def format_tree_line: (Class task_class, TaskProgress? progress, bool is_impl, bool is_selected) -> String
|
|
290
472
|
def format_unknown_task: (Class task_class, ?bool is_selected) -> String
|
|
291
|
-
def task_status_icon: (Symbol state, bool is_selected) -> String
|
|
292
473
|
def spinner_char: () -> String
|
|
293
474
|
def type_label_for: (Class task_class, ?bool is_selected) -> String
|
|
294
|
-
def task_details: (TaskProgress progress) -> String
|
|
295
475
|
def section_class?: (Class klass) -> bool
|
|
296
476
|
def nested_class?: (Class child_class, Class parent_class) -> bool
|
|
297
477
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: taski
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ahogappa
|
|
@@ -50,29 +50,35 @@ extensions: []
|
|
|
50
50
|
extra_rdoc_files: []
|
|
51
51
|
files:
|
|
52
52
|
- ".standard.yml"
|
|
53
|
+
- CHANGELOG.md
|
|
53
54
|
- LICENSE
|
|
54
55
|
- README.md
|
|
55
56
|
- Rakefile
|
|
56
57
|
- Steepfile
|
|
57
|
-
- docs/
|
|
58
|
-
- docs/api-guide.md
|
|
59
|
-
- docs/error-handling.md
|
|
58
|
+
- docs/GUIDE.md
|
|
60
59
|
- examples/README.md
|
|
61
|
-
- examples/
|
|
60
|
+
- examples/args_demo.rb
|
|
61
|
+
- examples/clean_demo.rb
|
|
62
62
|
- examples/data_pipeline_demo.rb
|
|
63
|
+
- examples/group_demo.rb
|
|
63
64
|
- examples/nested_section_demo.rb
|
|
64
65
|
- examples/parallel_progress_demo.rb
|
|
65
66
|
- examples/quick_start.rb
|
|
66
67
|
- examples/reexecution_demo.rb
|
|
67
68
|
- examples/section_demo.rb
|
|
68
|
-
- examples/
|
|
69
|
+
- examples/system_call_demo.rb
|
|
69
70
|
- examples/tree_progress_demo.rb
|
|
70
71
|
- lib/taski.rb
|
|
71
|
-
- lib/taski/
|
|
72
|
+
- lib/taski/args.rb
|
|
73
|
+
- lib/taski/execution/execution_context.rb
|
|
72
74
|
- lib/taski/execution/executor.rb
|
|
73
75
|
- lib/taski/execution/registry.rb
|
|
76
|
+
- lib/taski/execution/scheduler.rb
|
|
77
|
+
- lib/taski/execution/task_output_pipe.rb
|
|
78
|
+
- lib/taski/execution/task_output_router.rb
|
|
74
79
|
- lib/taski/execution/task_wrapper.rb
|
|
75
80
|
- lib/taski/execution/tree_progress_display.rb
|
|
81
|
+
- lib/taski/execution/worker_pool.rb
|
|
76
82
|
- lib/taski/section.rb
|
|
77
83
|
- lib/taski/static_analysis/analyzer.rb
|
|
78
84
|
- lib/taski/static_analysis/dependency_graph.rb
|