taski 0.3.1 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +101 -271
- data/Steepfile +19 -0
- data/docs/advanced-features.md +625 -0
- data/docs/api-guide.md +509 -0
- data/docs/error-handling.md +684 -0
- data/examples/README.md +98 -42
- data/examples/context_demo.rb +118 -0
- data/examples/data_pipeline_demo.rb +231 -0
- data/examples/parallel_progress_demo.rb +72 -0
- data/examples/quick_start.rb +4 -4
- data/examples/reexecution_demo.rb +127 -0
- data/examples/{section_configuration.rb → section_demo.rb} +49 -60
- data/lib/taski/context.rb +50 -0
- data/lib/taski/execution/coordinator.rb +63 -0
- data/lib/taski/execution/parallel_progress_display.rb +201 -0
- data/lib/taski/execution/registry.rb +72 -0
- data/lib/taski/execution/task_wrapper.rb +255 -0
- data/lib/taski/section.rb +26 -254
- data/lib/taski/static_analysis/analyzer.rb +46 -0
- data/lib/taski/static_analysis/dependency_graph.rb +90 -0
- data/lib/taski/static_analysis/visitor.rb +130 -0
- data/lib/taski/task.rb +199 -0
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +68 -39
- data/rbs_collection.lock.yaml +116 -0
- data/rbs_collection.yaml +19 -0
- data/sig/taski.rbs +269 -62
- metadata +36 -32
- data/examples/advanced_patterns.rb +0 -119
- data/examples/progress_demo.rb +0 -166
- data/examples/tree_demo.rb +0 -205
- data/lib/taski/dependency_analyzer.rb +0 -232
- data/lib/taski/exceptions.rb +0 -17
- data/lib/taski/logger.rb +0 -158
- data/lib/taski/logging/formatter_factory.rb +0 -34
- data/lib/taski/logging/formatter_interface.rb +0 -19
- data/lib/taski/logging/json_formatter.rb +0 -26
- data/lib/taski/logging/simple_formatter.rb +0 -16
- data/lib/taski/logging/structured_formatter.rb +0 -44
- data/lib/taski/progress/display_colors.rb +0 -17
- data/lib/taski/progress/display_manager.rb +0 -117
- data/lib/taski/progress/output_capture.rb +0 -105
- data/lib/taski/progress/spinner_animation.rb +0 -49
- data/lib/taski/progress/task_formatter.rb +0 -25
- data/lib/taski/progress/task_status.rb +0 -38
- data/lib/taski/progress/terminal_controller.rb +0 -35
- data/lib/taski/progress_display.rb +0 -57
- data/lib/taski/reference.rb +0 -40
- data/lib/taski/task/base.rb +0 -91
- data/lib/taski/task/define_api.rb +0 -156
- data/lib/taski/task/dependency_resolver.rb +0 -73
- data/lib/taski/task/exports_api.rb +0 -29
- data/lib/taski/task/instance_management.rb +0 -201
- data/lib/taski/tree_colors.rb +0 -91
- data/lib/taski/utils/dependency_resolver_helper.rb +0 -85
- data/lib/taski/utils/tree_display_helper.rb +0 -68
- data/lib/taski/utils.rb +0 -107
data/sig/taski.rbs
CHANGED
|
@@ -1,99 +1,306 @@
|
|
|
1
1
|
module Taski
|
|
2
2
|
VERSION: String
|
|
3
3
|
|
|
4
|
+
self.@global_registry: Execution::Registry?
|
|
5
|
+
self.@progress_display: Execution::ParallelProgressDisplay?
|
|
6
|
+
|
|
7
|
+
# Type alias for Task class (singleton type with class methods)
|
|
8
|
+
# This represents a Class that inherits from Taski::Task
|
|
9
|
+
type task_class = singleton(Task)
|
|
10
|
+
|
|
11
|
+
# Module-level methods
|
|
12
|
+
def self.global_registry: () -> Execution::Registry
|
|
13
|
+
def self.reset_global_registry!: () -> void
|
|
14
|
+
def self.progress_display: () -> Execution::ParallelProgressDisplay?
|
|
15
|
+
def self.progress_enabled?: () -> bool
|
|
16
|
+
def self.reset_progress_display!: () -> void
|
|
17
|
+
|
|
4
18
|
# Custom exceptions
|
|
5
|
-
class
|
|
19
|
+
class TaskAbortException < StandardError
|
|
6
20
|
end
|
|
7
21
|
|
|
8
|
-
class
|
|
9
|
-
|
|
22
|
+
class CircularDependencyError < StandardError
|
|
23
|
+
@cyclic_tasks: Array[Array[Class]]
|
|
24
|
+
|
|
25
|
+
attr_reader cyclic_tasks: Array[Array[Class]]
|
|
10
26
|
|
|
11
|
-
|
|
27
|
+
def initialize: (Array[Array[Class]] cyclic_tasks) -> void
|
|
12
28
|
end
|
|
13
29
|
|
|
14
|
-
#
|
|
15
|
-
class
|
|
16
|
-
|
|
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?
|
|
17
36
|
|
|
18
|
-
def
|
|
19
|
-
def
|
|
20
|
-
def
|
|
21
|
-
def
|
|
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
|
|
22
42
|
end
|
|
23
43
|
|
|
24
44
|
# Main Task class
|
|
25
45
|
class Task
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
46
|
+
self.@exported_methods: Array[Symbol]
|
|
47
|
+
self.@dependencies_cache: Set[task_class]?
|
|
48
|
+
self.@coordinator: Execution::Coordinator?
|
|
49
|
+
self.@circular_dependency_checked: bool
|
|
30
50
|
|
|
31
|
-
#
|
|
32
|
-
def self.method_added: (Symbol method_name) -> void
|
|
33
|
-
|
|
34
|
-
# Public API methods
|
|
51
|
+
# Class methods
|
|
35
52
|
def self.exports: (*Symbol names) -> void
|
|
36
|
-
def self.
|
|
37
|
-
def self.
|
|
53
|
+
def self.exported_methods: () -> Array[Symbol]
|
|
54
|
+
def self.new: () -> Execution::TaskWrapper
|
|
55
|
+
def self.cached_dependencies: () -> Set[task_class]
|
|
56
|
+
def self.clear_dependency_cache: () -> void
|
|
57
|
+
def self.run: () -> untyped
|
|
38
58
|
def self.clean: () -> void
|
|
39
|
-
def self.
|
|
40
|
-
def self.
|
|
41
|
-
def self.
|
|
42
|
-
def self.
|
|
43
|
-
def self.ensure_instance_built: () -> Task
|
|
44
|
-
|
|
45
|
-
# Define API methods
|
|
46
|
-
def self.__resolve__: () -> Hash[Symbol, untyped]
|
|
47
|
-
def self.resolve_dependencies: () -> void
|
|
59
|
+
def self.registry: () -> Execution::Registry
|
|
60
|
+
def self.coordinator: () -> Execution::Coordinator
|
|
61
|
+
def self.reset!: () -> void
|
|
62
|
+
def self.tree: () -> String
|
|
48
63
|
|
|
49
64
|
# Instance methods
|
|
50
|
-
def
|
|
65
|
+
def run: () -> void
|
|
51
66
|
def clean: () -> void
|
|
67
|
+
def reset!: () -> void
|
|
52
68
|
|
|
53
|
-
|
|
54
|
-
def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
|
|
55
|
-
def respond_to_missing?: (Symbol name, bool include_private) -> bool
|
|
69
|
+
private
|
|
56
70
|
|
|
57
|
-
#
|
|
58
|
-
def self.
|
|
59
|
-
def self.
|
|
71
|
+
# 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
|
+
def self.cached_wrapper: () -> Execution::TaskWrapper
|
|
76
|
+
def self.define_instance_reader: (Symbol method_name) -> void
|
|
77
|
+
def self.define_class_accessor: (Symbol method_name) -> void
|
|
78
|
+
def self.validate_no_circular_dependencies!: () -> void
|
|
79
|
+
end
|
|
60
80
|
|
|
61
|
-
|
|
81
|
+
# Section class for abstraction layers (inherits from Task)
|
|
82
|
+
class Section < Task
|
|
83
|
+
def self.interfaces: (*Symbol interface_methods) -> void
|
|
84
|
+
|
|
85
|
+
def run: () -> void
|
|
86
|
+
def impl: () -> task_class
|
|
62
87
|
|
|
63
|
-
|
|
64
|
-
def self.resolve_queue: (Array[Class] queue, Array[Class] resolved) -> Array[Class]
|
|
65
|
-
def self.detect_circular_dependencies: (Array[Class] queue, Array[Class] resolved) -> void
|
|
66
|
-
def self.build_instance: (Class task_class) -> void
|
|
88
|
+
private
|
|
67
89
|
|
|
68
|
-
|
|
69
|
-
def self.create_defined_method: (Symbol name) { () -> untyped } -> void
|
|
70
|
-
def self.create_ref_method_if_needed: () -> void
|
|
71
|
-
def self.method_defined_for_define?: (Symbol method_name) -> bool
|
|
72
|
-
def self.mark_method_as_defined: (Symbol method_name) -> void
|
|
90
|
+
def apply_interface_to_implementation: (task_class implementation_class) -> void
|
|
73
91
|
end
|
|
74
92
|
|
|
75
|
-
#
|
|
76
|
-
module
|
|
77
|
-
|
|
93
|
+
# Execution module
|
|
94
|
+
module Execution
|
|
95
|
+
# TaskTiming struct (Data.define)
|
|
96
|
+
class TaskTiming
|
|
97
|
+
attr_reader start_time: Time
|
|
98
|
+
attr_reader end_time: Time?
|
|
78
99
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
100
|
+
# Data.define provides both positional and keyword argument constructors
|
|
101
|
+
def initialize: (Time start_time, Time? end_time) -> void
|
|
102
|
+
| (start_time: Time, end_time: Time?) -> void
|
|
103
|
+
|
|
104
|
+
def self.new: (Time start_time, Time? end_time) -> TaskTiming
|
|
105
|
+
| (start_time: Time, end_time: Time?) -> TaskTiming
|
|
106
|
+
|
|
107
|
+
def self.start_now: () -> TaskTiming
|
|
108
|
+
def duration_ms: () -> (Integer | Float)?
|
|
109
|
+
def with_end_now: () -> TaskTiming
|
|
110
|
+
def with: (?start_time: Time, ?end_time: Time?) -> TaskTiming
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Registry class for task instance management
|
|
114
|
+
class Registry
|
|
115
|
+
@tasks: Hash[Class, TaskWrapper]
|
|
116
|
+
@threads: Array[Thread]
|
|
117
|
+
@monitor: Monitor
|
|
118
|
+
@abort_requested: bool
|
|
82
119
|
|
|
83
120
|
def initialize: () -> void
|
|
84
|
-
def
|
|
85
|
-
def
|
|
121
|
+
def get_or_create: (Class task_class) { () -> TaskWrapper } -> TaskWrapper
|
|
122
|
+
def get_task: (Class task_class) -> TaskWrapper
|
|
123
|
+
def register_thread: (Thread thread) -> void
|
|
124
|
+
def wait_all: () -> void
|
|
125
|
+
def reset!: () -> void
|
|
126
|
+
def request_abort!: () -> void
|
|
127
|
+
def abort_requested?: () -> bool
|
|
128
|
+
def run: (Class task_class, Array[Symbol] exported_methods) -> untyped
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Coordinator class for dependency management
|
|
132
|
+
class Coordinator
|
|
133
|
+
@registry: Registry
|
|
134
|
+
@analyzer: singleton(StaticAnalysis::Analyzer)
|
|
135
|
+
|
|
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]
|
|
86
140
|
|
|
87
141
|
private
|
|
88
142
|
|
|
89
|
-
def
|
|
90
|
-
def
|
|
91
|
-
def
|
|
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
|
|
92
146
|
end
|
|
93
147
|
|
|
94
|
-
|
|
148
|
+
# TaskWrapper class for task execution
|
|
149
|
+
class TaskWrapper
|
|
150
|
+
attr_reader task: Task
|
|
151
|
+
attr_reader result: untyped
|
|
152
|
+
|
|
153
|
+
@task: Task
|
|
154
|
+
@registry: Registry
|
|
155
|
+
@coordinator: Coordinator
|
|
156
|
+
@result: untyped
|
|
157
|
+
@clean_result: untyped
|
|
158
|
+
@error: StandardError?
|
|
159
|
+
@monitor: Monitor
|
|
160
|
+
@condition: MonitorMixin::ConditionVariable
|
|
161
|
+
@clean_condition: MonitorMixin::ConditionVariable
|
|
162
|
+
@state: Symbol
|
|
163
|
+
@clean_state: Symbol
|
|
164
|
+
@timing: TaskTiming?
|
|
165
|
+
|
|
166
|
+
STATE_PENDING: Symbol
|
|
167
|
+
STATE_RUNNING: Symbol
|
|
168
|
+
STATE_COMPLETED: Symbol
|
|
169
|
+
|
|
170
|
+
def initialize: (Task task, registry: Registry, coordinator: Coordinator) -> void
|
|
171
|
+
def run: () -> untyped
|
|
172
|
+
def clean: () -> void
|
|
173
|
+
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
|
|
187
|
+
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
|
+
def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
|
|
196
|
+
def respond_to_missing?: (Symbol name, ?bool include_private) -> bool
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# ParallelProgressDisplay class for progress visualization
|
|
200
|
+
class ParallelProgressDisplay
|
|
201
|
+
SPINNER_FRAMES: Array[String]
|
|
202
|
+
|
|
203
|
+
@output: IO
|
|
204
|
+
@tasks: Hash[Class, TaskProgress]
|
|
205
|
+
@monitor: Monitor
|
|
206
|
+
@spinner_index: Integer
|
|
207
|
+
@renderer_thread: Thread?
|
|
208
|
+
@running: bool
|
|
95
209
|
|
|
96
|
-
|
|
97
|
-
|
|
210
|
+
class TaskProgress
|
|
211
|
+
attr_accessor state: Symbol
|
|
212
|
+
attr_accessor start_time: Time?
|
|
213
|
+
attr_accessor end_time: Time?
|
|
214
|
+
attr_accessor error: Exception?
|
|
215
|
+
attr_accessor duration: Numeric?
|
|
216
|
+
|
|
217
|
+
def initialize: () -> void
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def initialize: (?output: IO) -> void
|
|
221
|
+
def register_task: (Class task_class) -> void
|
|
222
|
+
def task_registered?: (Class task_class) -> bool
|
|
223
|
+
def update_task: (Class task_class, state: Symbol, ?duration: Numeric?, ?error: Exception?) -> void
|
|
224
|
+
def task_state: (Class task_class) -> Symbol?
|
|
225
|
+
def render: () -> void
|
|
226
|
+
def start: () -> void
|
|
227
|
+
def stop: () -> void
|
|
228
|
+
|
|
229
|
+
private
|
|
230
|
+
|
|
231
|
+
def collect_task_lines: () -> Array[String]
|
|
232
|
+
def render_live: () -> void
|
|
233
|
+
def render_final: () -> void
|
|
234
|
+
def format_task_line: (Class task_class, TaskProgress progress) -> String
|
|
235
|
+
def task_icon: (Symbol state) -> String
|
|
236
|
+
def spinner_char: () -> String
|
|
237
|
+
def task_details: (TaskProgress progress) -> String
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# StaticAnalysis module
|
|
242
|
+
module StaticAnalysis
|
|
243
|
+
# Analyzer class for dependency analysis
|
|
244
|
+
class Analyzer
|
|
245
|
+
def self.analyze: (Class task_class) -> Set[task_class]
|
|
246
|
+
|
|
247
|
+
private
|
|
248
|
+
|
|
249
|
+
def self.extract_run_method_location: (Class task_class) -> [String, Integer]?
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Visitor class for AST traversal
|
|
253
|
+
class Visitor < Prism::Visitor
|
|
254
|
+
@target_task_class: Class
|
|
255
|
+
@dependencies: Set[task_class]
|
|
256
|
+
@in_target_run_method: bool
|
|
257
|
+
@current_namespace_path: Array[String?]
|
|
258
|
+
|
|
259
|
+
attr_reader dependencies: Set[task_class]
|
|
260
|
+
|
|
261
|
+
def initialize: (Class task_class) -> void
|
|
262
|
+
def visit_class_node: (Prism::ClassNode node) -> untyped
|
|
263
|
+
def visit_module_node: (Prism::ModuleNode node) -> untyped
|
|
264
|
+
def visit_def_node: (Prism::DefNode node) -> untyped
|
|
265
|
+
def visit_call_node: (Prism::CallNode node) -> untyped
|
|
266
|
+
|
|
267
|
+
private
|
|
268
|
+
|
|
269
|
+
def within_namespace: (String? name) { () -> void } -> void
|
|
270
|
+
def in_target_class?: () -> bool
|
|
271
|
+
def extract_constant_name: (untyped node) -> String?
|
|
272
|
+
def detect_task_dependency: (Prism::CallNode node) -> void
|
|
273
|
+
def extract_receiver_constant: (untyped receiver) -> String?
|
|
274
|
+
def resolve_and_add_dependency: (String constant_name) -> void
|
|
275
|
+
def resolve_constant: (String name) -> task_class?
|
|
276
|
+
def resolve_with_namespace_prefix: (String name) -> task_class?
|
|
277
|
+
def valid_dependency?: (task_class klass) -> bool
|
|
278
|
+
def is_parallel_task?: (task_class klass) -> boolish
|
|
279
|
+
def is_parallel_section?: (task_class klass) -> boolish
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# DependencyGraph class for topological sorting and cycle detection
|
|
283
|
+
class DependencyGraph
|
|
284
|
+
include TSort[Class]
|
|
285
|
+
|
|
286
|
+
@graph: Hash[Class, Set[Class]]
|
|
287
|
+
|
|
288
|
+
def initialize: () -> void
|
|
289
|
+
def build_from: (Class root_task_class) -> self
|
|
290
|
+
def sorted: () -> Array[Class]
|
|
291
|
+
def cyclic?: () -> bool
|
|
292
|
+
def strongly_connected_components: () -> Array[Array[Class]]
|
|
293
|
+
def cyclic_components: () -> Array[Array[Class]]
|
|
294
|
+
def all_tasks: () -> Array[Class]
|
|
295
|
+
def dependencies_for: (Class task) -> Set[Class]
|
|
296
|
+
|
|
297
|
+
# TSort interface methods (required by TSort module)
|
|
298
|
+
def tsort_each_node: () { (Class) -> void } -> void
|
|
299
|
+
def tsort_each_child: (Class node) { (Class) -> void } -> void
|
|
300
|
+
|
|
301
|
+
private
|
|
302
|
+
|
|
303
|
+
def collect_dependencies: (Class task_class) -> void
|
|
304
|
+
end
|
|
98
305
|
end
|
|
99
|
-
end
|
|
306
|
+
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.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ahogappa
|
|
@@ -23,6 +23,20 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '1.4'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: tsort
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
26
40
|
description: Taski is a Ruby-based task runner currently under development. It allows
|
|
27
41
|
you to define small, composable tasks along with the outputs they depend on. Taski
|
|
28
42
|
statically resolves dependencies and executes tasks in the correct topological order,
|
|
@@ -39,41 +53,31 @@ files:
|
|
|
39
53
|
- LICENSE
|
|
40
54
|
- README.md
|
|
41
55
|
- Rakefile
|
|
56
|
+
- Steepfile
|
|
57
|
+
- docs/advanced-features.md
|
|
58
|
+
- docs/api-guide.md
|
|
59
|
+
- docs/error-handling.md
|
|
42
60
|
- examples/README.md
|
|
43
|
-
- examples/
|
|
44
|
-
- examples/
|
|
61
|
+
- examples/context_demo.rb
|
|
62
|
+
- examples/data_pipeline_demo.rb
|
|
63
|
+
- examples/parallel_progress_demo.rb
|
|
45
64
|
- examples/quick_start.rb
|
|
46
|
-
- examples/
|
|
47
|
-
- examples/
|
|
65
|
+
- examples/reexecution_demo.rb
|
|
66
|
+
- examples/section_demo.rb
|
|
48
67
|
- lib/taski.rb
|
|
49
|
-
- lib/taski/
|
|
50
|
-
- lib/taski/
|
|
51
|
-
- lib/taski/
|
|
52
|
-
- lib/taski/
|
|
53
|
-
- lib/taski/
|
|
54
|
-
- lib/taski/logging/json_formatter.rb
|
|
55
|
-
- lib/taski/logging/simple_formatter.rb
|
|
56
|
-
- lib/taski/logging/structured_formatter.rb
|
|
57
|
-
- lib/taski/progress/display_colors.rb
|
|
58
|
-
- lib/taski/progress/display_manager.rb
|
|
59
|
-
- lib/taski/progress/output_capture.rb
|
|
60
|
-
- lib/taski/progress/spinner_animation.rb
|
|
61
|
-
- lib/taski/progress/task_formatter.rb
|
|
62
|
-
- lib/taski/progress/task_status.rb
|
|
63
|
-
- lib/taski/progress/terminal_controller.rb
|
|
64
|
-
- lib/taski/progress_display.rb
|
|
65
|
-
- lib/taski/reference.rb
|
|
68
|
+
- lib/taski/context.rb
|
|
69
|
+
- lib/taski/execution/coordinator.rb
|
|
70
|
+
- lib/taski/execution/parallel_progress_display.rb
|
|
71
|
+
- lib/taski/execution/registry.rb
|
|
72
|
+
- lib/taski/execution/task_wrapper.rb
|
|
66
73
|
- lib/taski/section.rb
|
|
67
|
-
- lib/taski/
|
|
68
|
-
- lib/taski/
|
|
69
|
-
- lib/taski/
|
|
70
|
-
- lib/taski/task
|
|
71
|
-
- lib/taski/task/instance_management.rb
|
|
72
|
-
- lib/taski/tree_colors.rb
|
|
73
|
-
- lib/taski/utils.rb
|
|
74
|
-
- lib/taski/utils/dependency_resolver_helper.rb
|
|
75
|
-
- lib/taski/utils/tree_display_helper.rb
|
|
74
|
+
- lib/taski/static_analysis/analyzer.rb
|
|
75
|
+
- lib/taski/static_analysis/dependency_graph.rb
|
|
76
|
+
- lib/taski/static_analysis/visitor.rb
|
|
77
|
+
- lib/taski/task.rb
|
|
76
78
|
- lib/taski/version.rb
|
|
79
|
+
- rbs_collection.lock.yaml
|
|
80
|
+
- rbs_collection.yaml
|
|
77
81
|
- sig/taski.rbs
|
|
78
82
|
homepage: https://github.com/ahogappa/taski
|
|
79
83
|
licenses: []
|
|
@@ -95,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
95
99
|
- !ruby/object:Gem::Version
|
|
96
100
|
version: '0'
|
|
97
101
|
requirements: []
|
|
98
|
-
rubygems_version: 3.6.
|
|
102
|
+
rubygems_version: 3.6.9
|
|
99
103
|
specification_version: 4
|
|
100
104
|
summary: A simple yet powerful Ruby task runner with static dependency resolution
|
|
101
105
|
(in development).
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# Taski Advanced Patterns
|
|
5
|
-
#
|
|
6
|
-
# This example demonstrates advanced Taski patterns:
|
|
7
|
-
# - Mixed usage of Exports API and Define API
|
|
8
|
-
# - Environment-specific dependency resolution
|
|
9
|
-
# - Feature flag integration with dynamic dependencies
|
|
10
|
-
# - Task reset and rebuild scenarios
|
|
11
|
-
# - Conditional dependency evaluation
|
|
12
|
-
#
|
|
13
|
-
# Run: ruby examples/advanced_patterns.rb
|
|
14
|
-
|
|
15
|
-
require_relative "../lib/taski"
|
|
16
|
-
|
|
17
|
-
puts "⚡ Advanced Taski Patterns"
|
|
18
|
-
puts "=" * 40
|
|
19
|
-
|
|
20
|
-
# Mock classes for the example
|
|
21
|
-
class ProductionDB < Taski::Task
|
|
22
|
-
exports :connection_string
|
|
23
|
-
def build
|
|
24
|
-
@connection_string = "postgres://prod-server/app"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
class TestDB < Taski::Task
|
|
29
|
-
exports :connection_string
|
|
30
|
-
def build
|
|
31
|
-
@connection_string = "postgres://test-server/app_test"
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
module FeatureFlag
|
|
36
|
-
def self.enabled?(flag)
|
|
37
|
-
ENV["FEATURE_#{flag.to_s.upcase}"] == "true"
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
class RedisService < Taski::Task
|
|
42
|
-
exports :configuration
|
|
43
|
-
def build
|
|
44
|
-
@configuration = "redis://localhost:6379"
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Environment configuration using Define API
|
|
49
|
-
class Environment < Taski::Task
|
|
50
|
-
define :database_url, -> {
|
|
51
|
-
case ENV["RAILS_ENV"]
|
|
52
|
-
when "production"
|
|
53
|
-
ProductionDB.connection_string
|
|
54
|
-
when "test"
|
|
55
|
-
TestDB.connection_string
|
|
56
|
-
else
|
|
57
|
-
"sqlite3://development.db"
|
|
58
|
-
end
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
define :redis_config, -> {
|
|
62
|
-
if FeatureFlag.enabled?(:redis_cache)
|
|
63
|
-
RedisService.configuration
|
|
64
|
-
end
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
def build
|
|
68
|
-
# Environment configuration is handled by define blocks
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Static configuration using Exports API
|
|
73
|
-
class AppConfig < Taski::Task
|
|
74
|
-
exports :app_name, :version, :port
|
|
75
|
-
|
|
76
|
-
def build
|
|
77
|
-
@app_name = "MyWebApp"
|
|
78
|
-
@version = "2.1.0"
|
|
79
|
-
@port = ENV.fetch("PORT", 3000).to_i
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Application startup combining both APIs
|
|
84
|
-
class Application < Taski::Task
|
|
85
|
-
def build
|
|
86
|
-
puts "Starting #{AppConfig.app_name} v#{AppConfig.version}"
|
|
87
|
-
puts "Database: #{Environment.database_url}"
|
|
88
|
-
puts "Redis: #{Environment.redis_config || "disabled"}"
|
|
89
|
-
puts "Port: #{AppConfig.port}"
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def clean
|
|
93
|
-
puts "Shutting down #{AppConfig.app_name}..."
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Test different environments
|
|
98
|
-
puts "\n1. Development Environment (default):"
|
|
99
|
-
ENV.delete("RAILS_ENV")
|
|
100
|
-
ENV.delete("FEATURE_REDIS_CACHE")
|
|
101
|
-
Application.build
|
|
102
|
-
Application.reset!
|
|
103
|
-
|
|
104
|
-
puts "\n2. Test Environment:"
|
|
105
|
-
ENV["RAILS_ENV"] = "test"
|
|
106
|
-
# Reset Environment to re-evaluate define blocks
|
|
107
|
-
Environment.reset!
|
|
108
|
-
Application.build
|
|
109
|
-
Application.reset!
|
|
110
|
-
|
|
111
|
-
puts "\n3. Production with Redis:"
|
|
112
|
-
ENV["RAILS_ENV"] = "production"
|
|
113
|
-
ENV["FEATURE_REDIS_CACHE"] = "true"
|
|
114
|
-
# Reset Environment to re-evaluate define blocks
|
|
115
|
-
Environment.reset!
|
|
116
|
-
Application.build
|
|
117
|
-
|
|
118
|
-
puts "\n4. Cleanup:"
|
|
119
|
-
Application.clean
|