taski 0.4.2 → 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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -0
  3. data/README.md +51 -33
  4. data/Steepfile +1 -0
  5. data/docs/GUIDE.md +340 -0
  6. data/examples/README.md +68 -20
  7. data/examples/{context_demo.rb → args_demo.rb} +27 -27
  8. data/examples/clean_demo.rb +204 -0
  9. data/examples/data_pipeline_demo.rb +3 -3
  10. data/examples/group_demo.rb +113 -0
  11. data/examples/nested_section_demo.rb +161 -0
  12. data/examples/parallel_progress_demo.rb +1 -1
  13. data/examples/reexecution_demo.rb +93 -80
  14. data/examples/system_call_demo.rb +56 -0
  15. data/examples/tree_progress_demo.rb +164 -0
  16. data/lib/taski/{context.rb → args.rb} +3 -3
  17. data/lib/taski/execution/execution_context.rb +379 -0
  18. data/lib/taski/execution/executor.rb +538 -0
  19. data/lib/taski/execution/registry.rb +26 -2
  20. data/lib/taski/execution/scheduler.rb +308 -0
  21. data/lib/taski/execution/task_output_pipe.rb +42 -0
  22. data/lib/taski/execution/task_output_router.rb +216 -0
  23. data/lib/taski/execution/task_wrapper.rb +295 -146
  24. data/lib/taski/execution/tree_progress_display.rb +793 -0
  25. data/lib/taski/execution/worker_pool.rb +104 -0
  26. data/lib/taski/section.rb +23 -0
  27. data/lib/taski/static_analysis/analyzer.rb +4 -2
  28. data/lib/taski/static_analysis/visitor.rb +86 -5
  29. data/lib/taski/task.rb +223 -120
  30. data/lib/taski/version.rb +1 -1
  31. data/lib/taski.rb +147 -28
  32. data/sig/taski.rbs +310 -67
  33. metadata +17 -8
  34. data/docs/advanced-features.md +0 -625
  35. data/docs/api-guide.md +0 -509
  36. data/docs/error-handling.md +0 -684
  37. data/lib/taski/execution/coordinator.rb +0 -63
  38. data/lib/taski/execution/parallel_progress_display.rb +0 -201
data/sig/taski.rbs CHANGED
@@ -2,7 +2,9 @@ module Taski
2
2
  VERSION: String
3
3
 
4
4
  self.@global_registry: Execution::Registry?
5
- self.@progress_display: Execution::ParallelProgressDisplay?
5
+ self.@progress_display: Execution::TreeProgressDisplay?
6
+ self.@args: Args?
7
+ self.@args_monitor: Monitor
6
8
 
7
9
  # Type alias for Task class (singleton type with class methods)
8
10
  # This represents a Class that inherits from Taski::Task
@@ -11,9 +13,13 @@ module Taski
11
13
  # Module-level methods
12
14
  def self.global_registry: () -> Execution::Registry
13
15
  def self.reset_global_registry!: () -> void
14
- def self.progress_display: () -> Execution::ParallelProgressDisplay?
15
- def self.progress_enabled?: () -> bool
16
+ def self.progress_display: () -> Execution::TreeProgressDisplay?
17
+ def self.progress_disabled?: () -> bool
16
18
  def self.reset_progress_display!: () -> void
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?
17
23
 
18
24
  # Custom exceptions
19
25
  class TaskAbortException < StandardError
@@ -27,55 +33,101 @@ module Taski
27
33
  def initialize: (Array[Array[Class]] cyclic_tasks) -> void
28
34
  end
29
35
 
30
- # Context class for execution context management
31
- class Context
32
- self.@monitor: Monitor
33
- self.@working_directory: String?
34
- self.@started_at: Time?
35
- self.@root_task: Class?
36
-
37
- def self.working_directory: () -> String
38
- def self.started_at: () -> Time
39
- def self.root_task: () -> Class?
40
- def self.set_root_task: (Class task) -> void
41
- def self.reset!: () -> void
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
82
+ @options: Hash[Symbol | String, untyped]
83
+ @root_task: Class
84
+ @started_at: Time
85
+ @working_directory: String
86
+
87
+ attr_reader started_at: Time
88
+ attr_reader working_directory: String
89
+ attr_reader root_task: Class
90
+
91
+ def initialize: (options: Hash[Symbol | String, untyped], root_task: Class) -> void
92
+ def []: (Symbol | String key) -> untyped
93
+ def fetch: (Symbol | String key, ?untyped default) ?{ () -> untyped } -> untyped
94
+ def key?: (Symbol | String key) -> bool
42
95
  end
43
96
 
44
97
  # Main Task class
45
98
  class Task
46
99
  self.@exported_methods: Array[Symbol]
47
100
  self.@dependencies_cache: Set[task_class]?
48
- self.@coordinator: Execution::Coordinator?
49
101
  self.@circular_dependency_checked: bool
50
102
 
51
103
  # Class methods
104
+ def self.inherited: (Class subclass) -> void
52
105
  def self.exports: (*Symbol names) -> void
53
106
  def self.exported_methods: () -> Array[Symbol]
54
107
  def self.new: () -> Execution::TaskWrapper
55
108
  def self.cached_dependencies: () -> Set[task_class]
56
109
  def self.clear_dependency_cache: () -> void
57
- def self.run: () -> untyped
58
- def self.clean: () -> void
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
59
113
  def self.registry: () -> Execution::Registry
60
- def self.coordinator: () -> Execution::Coordinator
61
114
  def self.reset!: () -> void
62
115
  def self.tree: () -> String
63
116
 
64
117
  # Instance methods
65
118
  def run: () -> void
66
119
  def clean: () -> void
120
+ def system: (*untyped args, **untyped opts) -> bool?
67
121
  def reset!: () -> void
68
122
 
69
123
  private
70
124
 
71
125
  # Private class methods
72
- def self.build_tree: (task_class task_class, String prefix, Set[task_class] visited) -> String
73
- def self.format_dependency_branch: (task_class dep, String prefix, bool is_last, Set[task_class] visited) -> String
74
- def self.tree_connector_chars: (bool is_last) -> [String, String]
75
126
  def self.cached_wrapper: () -> Execution::TaskWrapper
76
127
  def self.define_instance_reader: (Symbol method_name) -> void
77
128
  def self.define_class_accessor: (Symbol method_name) -> void
78
129
  def self.validate_no_circular_dependencies!: () -> void
130
+ def self.validate_workers!: (untyped workers) -> void
79
131
  end
80
132
 
81
133
  # Section class for abstraction layers (inherits from Task)
@@ -119,43 +171,191 @@ module Taski
119
171
 
120
172
  def initialize: () -> void
121
173
  def get_or_create: (Class task_class) { () -> TaskWrapper } -> TaskWrapper
122
- def get_task: (Class task_class) -> TaskWrapper
174
+ def get_task: (Class task_class) -> TaskWrapper?
175
+ def register: (Class task_class, TaskWrapper wrapper) -> void
123
176
  def register_thread: (Thread thread) -> void
124
177
  def wait_all: () -> void
125
178
  def reset!: () -> void
126
179
  def request_abort!: () -> void
127
180
  def abort_requested?: () -> bool
128
181
  def run: (Class task_class, Array[Symbol] exported_methods) -> untyped
182
+ def failed_wrappers: () -> Array[TaskWrapper]
183
+ def failed_clean_wrappers: () -> Array[TaskWrapper]
129
184
  end
130
185
 
131
- # Coordinator class for dependency management
132
- class Coordinator
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
241
+ STATE_PENDING: Symbol
242
+ STATE_ENQUEUED: Symbol
243
+ STATE_COMPLETED: Symbol
244
+ CLEAN_STATE_PENDING: Symbol
245
+ CLEAN_STATE_ENQUEUED: Symbol
246
+ CLEAN_STATE_COMPLETED: Symbol
247
+
248
+ @dependencies: Hash[Class, Set[Class]]
249
+ @task_states: Hash[Class, Symbol]
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]
254
+
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
133
281
  @registry: Registry
134
- @analyzer: singleton(StaticAnalysis::Analyzer)
282
+ @on_execute: ^(Class, TaskWrapper) -> void
283
+ @execution_queue: Thread::Queue
284
+ @workers: Array[Thread]
135
285
 
136
- def initialize: (registry: Registry, analyzer: singleton(StaticAnalysis::Analyzer)) -> void
137
- def start_dependencies: (task_class task_class) -> void
138
- def start_clean_dependencies: (task_class task_class) -> void
139
- def get_dependencies: (task_class task_class) -> Set[task_class]
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
140
291
 
141
292
  private
142
293
 
143
- def start_thread_with: () { () -> void } -> void
144
- def start_dependency_execution: (task_class dep_class) -> void
145
- def start_dependency_clean: (task_class dep_class) -> void
294
+ def default_worker_count: () -> Integer
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
+
317
+ def enqueue_ready_tasks: () -> void
318
+ def enqueue_task: (Class task_class) -> void
319
+ def get_or_create_wrapper: (Class task_class) -> TaskWrapper
320
+ def execute_task: (Class task_class, TaskWrapper wrapper) -> void
321
+ def run_main_loop: (Class root_task_class) -> void
322
+ def handle_completion: (Hash[Symbol, untyped] event) -> void
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
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
146
342
  end
147
343
 
148
344
  # TaskWrapper class for task execution
149
345
  class TaskWrapper
150
346
  attr_reader task: Task
151
347
  attr_reader result: untyped
348
+ attr_reader error: StandardError?
349
+ attr_reader clean_error: StandardError?
350
+ attr_reader timing: TaskTiming?
152
351
 
153
352
  @task: Task
154
353
  @registry: Registry
155
- @coordinator: Coordinator
354
+ @execution_context: ExecutionContext?
156
355
  @result: untyped
157
356
  @clean_result: untyped
158
357
  @error: StandardError?
358
+ @clean_error: StandardError?
159
359
  @monitor: Monitor
160
360
  @condition: MonitorMixin::ConditionVariable
161
361
  @clean_condition: MonitorMixin::ConditionVariable
@@ -166,39 +366,45 @@ module Taski
166
366
  STATE_PENDING: Symbol
167
367
  STATE_RUNNING: Symbol
168
368
  STATE_COMPLETED: Symbol
169
-
170
- def initialize: (Task task, registry: Registry, coordinator: Coordinator) -> void
369
+ STATE_FAILED: Symbol
370
+
371
+ def initialize: (Task task, registry: Registry, ?execution_context: ExecutionContext?) -> void
372
+ def state: () -> Symbol
373
+ def pending?: () -> bool
374
+ def completed?: () -> bool
375
+ def failed?: () -> bool
376
+ def clean_failed?: () -> bool
171
377
  def run: () -> untyped
172
- def clean: () -> void
378
+ def clean: () -> untyped
379
+ def run_and_clean: () -> untyped
173
380
  def get_exported_value: (Symbol method_name) -> untyped
174
- def start_thread_with: () { () -> void } -> void
175
- def execute_with_state_pattern: (state_getter: ^() -> Symbol, starter: ^() -> void, waiter: ^() -> void, ?pre_start_check: (^() -> void)?) -> void
176
- def execute_task_if_needed: () -> void
177
- def start_async_execution: () -> void
178
- def execute_task: () -> void
179
- def wait_for_dependencies: () -> void
180
- def execute_clean_if_needed: () -> void
181
- def start_async_clean: () -> void
182
- def execute_clean: () -> void
183
- def wait_for_clean_dependencies: () -> void
184
- def mark_completed: () -> void
185
- def mark_clean_completed: () -> void
186
- def wait_for_completion: () -> untyped
381
+ def mark_running: () -> bool
382
+ def mark_completed: (untyped result) -> void
383
+ def mark_failed: (StandardError error) -> void
384
+ def mark_clean_running: () -> bool
385
+ def mark_clean_completed: (untyped result) -> void
386
+ def mark_clean_failed: (StandardError error) -> void
387
+ def wait_for_completion: () -> void
187
388
  def wait_for_clean_completion: () -> void
188
- def debug_log: (String message) -> void
189
- def log_start: () -> void
190
- def log_completion: () -> void
191
- def log_clean_start: () -> void
192
- def log_clean_completion: () -> void
193
- def register_with_progress_display: () -> void
194
- def update_progress: (Symbol state, ?duration: Numeric?, ?error: Exception?) -> void
195
389
  def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
196
390
  def respond_to_missing?: (Symbol name, ?bool include_private) -> bool
391
+
392
+ private
393
+
394
+ def trigger_execution_and_wait: () -> void
395
+ def trigger_clean_and_wait: () -> void
396
+ def execute_clean: () -> void
397
+ def wait_for_clean_dependencies: () -> void
398
+ def check_abort!: () -> void
399
+ def update_progress: (Symbol state, ?duration: Numeric?, ?error: Exception?) -> void
400
+ def debug_log: (String message) -> void
197
401
  end
198
402
 
199
- # ParallelProgressDisplay class for progress visualization
200
- class ParallelProgressDisplay
403
+ # TreeProgressDisplay class for tree-based progress visualization
404
+ class TreeProgressDisplay
201
405
  SPINNER_FRAMES: Array[String]
406
+ COLORS: Hash[Symbol, String]
407
+ ICONS: Hash[Symbol, String]
202
408
 
203
409
  @output: IO
204
410
  @tasks: Hash[Class, TaskProgress]
@@ -206,6 +412,30 @@ module Taski
206
412
  @spinner_index: Integer
207
413
  @renderer_thread: Thread?
208
414
  @running: bool
415
+ @nest_level: Integer
416
+ @root_task_class: Class?
417
+ @tree_structure: Hash[Symbol, untyped]?
418
+ @section_impl_map: Hash[Class, Class]
419
+ @last_line_count: Integer
420
+
421
+ # Shared class methods
422
+ def self.section_class?: (Class klass) -> bool
423
+ def self.nested_class?: (Class child_class, Class parent_class) -> bool
424
+ def self.render_static_tree: (Class root_task_class) -> String
425
+
426
+ # Static tree renderer (internal class)
427
+ class StaticTreeRenderer
428
+ @task_index_map: Hash[Class, Integer]
429
+
430
+ def render: (Class root_task_class) -> String
431
+
432
+ private
433
+
434
+ def build_tree: (Class task_class, String prefix, bool is_impl, Set[Class] ancestors) -> String
435
+ def render_dependency_branch: (Class dep, String prefix, bool is_last, bool is_impl, Set[Class] ancestors) -> String
436
+ def get_task_number: (Class task_class) -> String
437
+ def colored_type_label: (Class klass) -> String
438
+ end
209
439
 
210
440
  class TaskProgress
211
441
  attr_accessor state: Symbol
@@ -213,28 +443,37 @@ module Taski
213
443
  attr_accessor end_time: Time?
214
444
  attr_accessor error: Exception?
215
445
  attr_accessor duration: Numeric?
446
+ attr_accessor is_impl_candidate: bool
216
447
 
217
448
  def initialize: () -> void
218
449
  end
219
450
 
220
451
  def initialize: (?output: IO) -> void
452
+ def set_root_task: (Class root_task_class) -> void
453
+ def register_section_impl: (Class section_class, Class impl_class) -> void
221
454
  def register_task: (Class task_class) -> void
222
455
  def task_registered?: (Class task_class) -> bool
223
456
  def update_task: (Class task_class, state: Symbol, ?duration: Numeric?, ?error: Exception?) -> void
224
457
  def task_state: (Class task_class) -> Symbol?
225
- def render: () -> void
226
458
  def start: () -> void
227
459
  def stop: () -> void
228
460
 
229
461
  private
230
462
 
231
- def collect_task_lines: () -> Array[String]
463
+ def build_tree_structure: () -> void
464
+ def build_tree_node: (Class task_class, Set[Class] ancestors) -> Hash[Symbol, untyped]?
465
+ def register_tasks_from_tree: (Hash[Symbol, untyped] node) -> void
232
466
  def render_live: () -> void
233
467
  def render_final: () -> void
234
- def format_task_line: (Class task_class, TaskProgress progress) -> String
235
- def task_icon: (Symbol state) -> String
468
+ def build_tree_display: () -> Array[String]
469
+ def build_root_tree_lines: (Hash[Symbol, untyped] node, String prefix, Array[String] lines) -> void
470
+ def render_children: (Hash[Symbol, untyped] node, String prefix, Array[String] lines, Class parent_task_class, bool ancestor_selected) -> void
471
+ def format_tree_line: (Class task_class, TaskProgress? progress, bool is_impl, bool is_selected) -> String
472
+ def format_unknown_task: (Class task_class, ?bool is_selected) -> String
236
473
  def spinner_char: () -> String
237
- def task_details: (TaskProgress progress) -> String
474
+ def type_label_for: (Class task_class, ?bool is_selected) -> String
475
+ def section_class?: (Class klass) -> bool
476
+ def nested_class?: (Class child_class, Class parent_class) -> bool
238
477
  end
239
478
  end
240
479
 
@@ -246,19 +485,21 @@ module Taski
246
485
 
247
486
  private
248
487
 
249
- def self.extract_run_method_location: (Class task_class) -> [String, Integer]?
488
+ def self.target_method_for: (Class task_class) -> Symbol
489
+ def self.extract_method_location: (Class task_class, Symbol method_name) -> [String, Integer]?
250
490
  end
251
491
 
252
492
  # Visitor class for AST traversal
253
493
  class Visitor < Prism::Visitor
254
494
  @target_task_class: Class
495
+ @target_method: Symbol
255
496
  @dependencies: Set[task_class]
256
- @in_target_run_method: bool
497
+ @in_target_method: bool
257
498
  @current_namespace_path: Array[String?]
258
499
 
259
500
  attr_reader dependencies: Set[task_class]
260
501
 
261
- def initialize: (Class task_class) -> void
502
+ def initialize: (Class task_class, Symbol target_method) -> void
262
503
  def visit_class_node: (Prism::ClassNode node) -> untyped
263
504
  def visit_module_node: (Prism::ModuleNode node) -> untyped
264
505
  def visit_def_node: (Prism::DefNode node) -> untyped
@@ -268,8 +509,10 @@ module Taski
268
509
 
269
510
  def within_namespace: (String? name) { () -> void } -> void
270
511
  def in_target_class?: () -> bool
512
+ def in_impl_method?: () -> bool
271
513
  def extract_constant_name: (untyped node) -> String?
272
514
  def detect_task_dependency: (Prism::CallNode node) -> void
515
+ def detect_impl_candidate: (untyped node) -> void
273
516
  def extract_receiver_constant: (untyped receiver) -> String?
274
517
  def resolve_and_add_dependency: (String constant_name) -> void
275
518
  def resolve_constant: (String name) -> task_class?
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.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ahogappa
@@ -50,26 +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/advanced-features.md
58
- - docs/api-guide.md
59
- - docs/error-handling.md
58
+ - docs/GUIDE.md
60
59
  - examples/README.md
61
- - examples/context_demo.rb
60
+ - examples/args_demo.rb
61
+ - examples/clean_demo.rb
62
62
  - examples/data_pipeline_demo.rb
63
+ - examples/group_demo.rb
64
+ - examples/nested_section_demo.rb
63
65
  - examples/parallel_progress_demo.rb
64
66
  - examples/quick_start.rb
65
67
  - examples/reexecution_demo.rb
66
68
  - examples/section_demo.rb
69
+ - examples/system_call_demo.rb
70
+ - examples/tree_progress_demo.rb
67
71
  - lib/taski.rb
68
- - lib/taski/context.rb
69
- - lib/taski/execution/coordinator.rb
70
- - lib/taski/execution/parallel_progress_display.rb
72
+ - lib/taski/args.rb
73
+ - lib/taski/execution/execution_context.rb
74
+ - lib/taski/execution/executor.rb
71
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
72
79
  - lib/taski/execution/task_wrapper.rb
80
+ - lib/taski/execution/tree_progress_display.rb
81
+ - lib/taski/execution/worker_pool.rb
73
82
  - lib/taski/section.rb
74
83
  - lib/taski/static_analysis/analyzer.rb
75
84
  - lib/taski/static_analysis/dependency_graph.rb