taski 0.8.3 → 0.9.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 +39 -0
- data/README.md +65 -50
- data/docs/GUIDE.md +41 -56
- data/examples/README.md +10 -29
- data/examples/clean_demo.rb +25 -65
- data/examples/large_tree_demo.rb +356 -0
- data/examples/message_demo.rb +0 -1
- data/examples/progress_demo.rb +13 -24
- data/examples/reexecution_demo.rb +8 -44
- data/lib/taski/execution/execution_facade.rb +150 -0
- data/lib/taski/execution/executor.rb +156 -357
- data/lib/taski/execution/registry.rb +15 -19
- data/lib/taski/execution/scheduler.rb +161 -140
- data/lib/taski/execution/task_observer.rb +41 -0
- data/lib/taski/execution/task_output_router.rb +41 -58
- data/lib/taski/execution/task_wrapper.rb +123 -219
- data/lib/taski/execution/worker_pool.rb +238 -64
- data/lib/taski/logging.rb +105 -0
- data/lib/taski/progress/layout/base.rb +600 -0
- data/lib/taski/progress/layout/filters.rb +126 -0
- data/lib/taski/progress/layout/log.rb +27 -0
- data/lib/taski/progress/layout/simple.rb +166 -0
- data/lib/taski/progress/layout/tags.rb +76 -0
- data/lib/taski/progress/layout/theme_drop.rb +84 -0
- data/lib/taski/progress/layout/tree.rb +300 -0
- data/lib/taski/progress/theme/base.rb +224 -0
- data/lib/taski/progress/theme/compact.rb +58 -0
- data/lib/taski/progress/theme/default.rb +25 -0
- data/lib/taski/progress/theme/detail.rb +48 -0
- data/lib/taski/progress/theme/plain.rb +40 -0
- data/lib/taski/static_analysis/analyzer.rb +5 -17
- data/lib/taski/static_analysis/dependency_graph.rb +19 -1
- data/lib/taski/static_analysis/visitor.rb +1 -39
- data/lib/taski/task.rb +44 -58
- data/lib/taski/test_helper/errors.rb +1 -1
- data/lib/taski/test_helper.rb +21 -35
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +60 -61
- data/sig/taski.rbs +194 -203
- metadata +31 -8
- data/examples/section_demo.rb +0 -195
- data/lib/taski/execution/base_progress_display.rb +0 -393
- data/lib/taski/execution/execution_context.rb +0 -390
- data/lib/taski/execution/plain_progress_display.rb +0 -76
- data/lib/taski/execution/simple_progress_display.rb +0 -247
- data/lib/taski/execution/tree_progress_display.rb +0 -643
- data/lib/taski/section.rb +0 -74
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ad85c90c371fc1ea2f61e1d7e9817c7a9cc3fa9f258be2bf1154ced5f4c0349
|
|
4
|
+
data.tar.gz: a56399d990f0a3ecfddff0f24b5a45c8319ea88e58299a3d3a22a2336295f5cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6969545ce4924434c3e031dca9fff39a974dfd53ee73fb610979cdc3fd09842f50b8871efec23a79dd40d1985bb97c92b651744655a38a12edbdeb9c0f05daa
|
|
7
|
+
data.tar.gz: 94a9f76f2da179d4b202b788f3abf27531b8a1df4ccd186eb84a5c695dfcbca3c78f75f2350ba052dcb98b68da7427e60b0a493e67340c1d04440278b4c3ab7f
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-02-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Fiber-based lazy dependency resolution replacing Monitor-based approach ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
14
|
+
- Layout/Theme architecture for progress display ([#150](https://github.com/ahogappa/taski/pull/150))
|
|
15
|
+
- Layout::Tree for hierarchical task display with TTY/non-TTY dual mode ([#151](https://github.com/ahogappa/taski/pull/151))
|
|
16
|
+
- Structured logging support for debugging and monitoring ([#141](https://github.com/ahogappa/taski/pull/141))
|
|
17
|
+
- Skipped task reporting in progress display and logging ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
18
|
+
- `clean_on_failure` option for `run_and_clean` ([#169](https://github.com/ahogappa/taski/pull/169))
|
|
19
|
+
- `short_name` filter for template name formatting ([#151](https://github.com/ahogappa/taski/pull/151))
|
|
20
|
+
- TaskDrop and ExecutionDrop for structured template variables ([#151](https://github.com/ahogappa/taski/pull/151))
|
|
21
|
+
- Group duration computation in Layout::Base ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
22
|
+
- `mark_clean_failed` in Scheduler for symmetric failure tracking ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
23
|
+
- Ruby 4.0 support in CI ([#160](https://github.com/ahogappa/taski/pull/160))
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- Replace ExecutionContext with ExecutionFacade/TaskObserver architecture ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
27
|
+
- Remove SharedState, unify task state in TaskWrapper ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
28
|
+
- Remove Section API in favor of simple if-statement selection (BREAKING) ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
29
|
+
- Simplify clean API by removing `Task.clean` and `Task.new` (BREAKING) ([#163](https://github.com/ahogappa/taski/pull/163))
|
|
30
|
+
- Simplify progress display configuration to single setter API ([#161](https://github.com/ahogappa/taski/pull/161))
|
|
31
|
+
- Rename `completed?`/`clean_completed?` to `finished?`/`clean_finished?` (BREAKING) ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
32
|
+
- Unify `STATE_ERROR` to `STATE_FAILED` across execution layer (BREAKING) ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
33
|
+
- Rename Template to Theme, Layout::Plain to Layout::Log ([#151](https://github.com/ahogappa/taski/pull/151))
|
|
34
|
+
- Rename `execution_context` to `execution_facade` across codebase ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
35
|
+
- Merge FiberExecutor into Executor, rename FiberWorkerPool to WorkerPool ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
36
|
+
- Replace inline `Class.new(Taski::Task)` with named fixture classes in tests ([#166](https://github.com/ahogappa/taski/pull/166))
|
|
37
|
+
- Drop Ruby 3.2 from CI ([#160](https://github.com/ahogappa/taski/pull/160))
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- Recursively add transitive dependencies in `merge_runtime_dependencies` ([#142](https://github.com/ahogappa/taski/pull/142))
|
|
41
|
+
- Handle `Errno::EBADF` in TaskOutputRouter pipe operations ([#159](https://github.com/ahogappa/taski/pull/159))
|
|
42
|
+
- Truncate simple progress line to terminal width ([#152](https://github.com/ahogappa/taski/pull/152))
|
|
43
|
+
- Improve thread safety in Registry and WorkerPool ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
44
|
+
- Restore fiber context on resume, scope output capture per-fiber ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
45
|
+
- Prevent duplicate `:start` responses and ensure observer event ordering ([#157](https://github.com/ahogappa/taski/pull/157))
|
|
46
|
+
- Route observer errors through structured logger instead of `warn` ([#167](https://github.com/ahogappa/taski/pull/167))
|
|
47
|
+
- Resolve Bundler permission error on Ruby 4.0 CI ([#162](https://github.com/ahogappa/taski/pull/162))
|
|
48
|
+
|
|
10
49
|
## [0.8.3] - 2026-01-26
|
|
11
50
|
|
|
12
51
|
### Fixed
|
data/README.md
CHANGED
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
- **Automatic Dependency Resolution**: Dependencies detected via static analysis
|
|
14
14
|
- **Parallel Execution**: Independent tasks run concurrently for maximum performance
|
|
15
|
-
- **
|
|
15
|
+
- **Exports API**: Simple value sharing between tasks
|
|
16
16
|
- **Real-time Progress**: Visual feedback with parallel task progress display
|
|
17
|
-
- **
|
|
17
|
+
- **Fiber-Based Execution**: Lightweight Fiber-based dependency resolution for efficient parallel execution
|
|
18
18
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
@@ -77,42 +77,32 @@ class Server < Taski::Task
|
|
|
77
77
|
end
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
###
|
|
80
|
+
### Conditional Logic - Runtime Selection
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
Use `if` statements to switch behavior based on environment:
|
|
83
83
|
|
|
84
84
|
```ruby
|
|
85
|
-
class
|
|
86
|
-
|
|
85
|
+
class DatabaseConfig < Taski::Task
|
|
86
|
+
exports :host, :port
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
def run
|
|
89
|
+
if ENV['RAILS_ENV'] == 'production'
|
|
90
90
|
@host = "prod.example.com"
|
|
91
91
|
@port = 5432
|
|
92
|
-
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
class Development < Taski::Task
|
|
96
|
-
def run
|
|
92
|
+
else
|
|
97
93
|
@host = "localhost"
|
|
98
94
|
@port = 5432
|
|
99
95
|
end
|
|
100
96
|
end
|
|
101
|
-
|
|
102
|
-
def impl
|
|
103
|
-
ENV['RAILS_ENV'] == 'production' ? Production : Development
|
|
104
|
-
end
|
|
105
97
|
end
|
|
106
98
|
|
|
107
99
|
class App < Taski::Task
|
|
108
100
|
def run
|
|
109
|
-
puts "Connecting to #{
|
|
101
|
+
puts "Connecting to #{DatabaseConfig.host}:#{DatabaseConfig.port}"
|
|
110
102
|
end
|
|
111
103
|
end
|
|
112
104
|
```
|
|
113
105
|
|
|
114
|
-
> **Note**: Nested implementation classes automatically inherit Section's `interfaces` as `exports`.
|
|
115
|
-
|
|
116
106
|
## Best Practices
|
|
117
107
|
|
|
118
108
|
### Keep Tasks Small and Focused
|
|
@@ -236,16 +226,47 @@ Env API (execution environment):
|
|
|
236
226
|
RandomTask.value # => 42
|
|
237
227
|
RandomTask.value # => 99 (different value - fresh execution)
|
|
238
228
|
|
|
239
|
-
# Instance-level caching
|
|
240
|
-
instance = RandomTask.new
|
|
241
|
-
instance.run # => 42
|
|
242
|
-
instance.run # => 42 (cached within instance)
|
|
243
|
-
instance.value # => 42
|
|
244
|
-
|
|
245
229
|
# Dependencies within same execution share results
|
|
246
230
|
DoubleConsumer.run # RandomTask runs once, both accesses get same value
|
|
247
231
|
```
|
|
248
232
|
|
|
233
|
+
### Error Handling
|
|
234
|
+
|
|
235
|
+
When a task fails, Taski wraps the error with task-specific context. Each task class automatically gets a `::Error` subclass for targeted rescue:
|
|
236
|
+
|
|
237
|
+
```ruby
|
|
238
|
+
class FetchData < Taski::Task
|
|
239
|
+
exports :data
|
|
240
|
+
def run
|
|
241
|
+
@data = API.fetch # may raise
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
class ProcessData < Taski::Task
|
|
246
|
+
def run
|
|
247
|
+
FetchData.data
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Rescue a specific task's error
|
|
252
|
+
begin
|
|
253
|
+
ProcessData.run
|
|
254
|
+
rescue FetchData::Error => e
|
|
255
|
+
puts "FetchData failed: #{e.cause.message}"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Rescue all task failures with AggregateError
|
|
259
|
+
begin
|
|
260
|
+
ProcessData.run
|
|
261
|
+
rescue Taski::AggregateError => e
|
|
262
|
+
e.errors.each do |failure|
|
|
263
|
+
puts "#{failure.task_class}: #{failure.error.message}"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`AggregateError` collects all failures from parallel execution. Task-specific `::Error` classes work transparently with `rescue` — even when errors are wrapped inside an `AggregateError`.
|
|
269
|
+
|
|
249
270
|
### Aborting Execution
|
|
250
271
|
|
|
251
272
|
Stop all pending tasks when a critical error occurs:
|
|
@@ -282,17 +303,24 @@ end
|
|
|
282
303
|
# Run then clean in one call
|
|
283
304
|
DatabaseSetup.run_and_clean
|
|
284
305
|
|
|
285
|
-
#
|
|
286
|
-
DatabaseSetup.
|
|
287
|
-
|
|
288
|
-
|
|
306
|
+
# Run, do something with exported values, then clean
|
|
307
|
+
DatabaseSetup.run_and_clean do
|
|
308
|
+
deploy(DatabaseSetup.connection)
|
|
309
|
+
end
|
|
289
310
|
```
|
|
290
311
|
|
|
291
|
-
See [docs/
|
|
312
|
+
See [docs/GUIDE.md](docs/GUIDE.md#lifecycle-management) for details.
|
|
292
313
|
|
|
293
314
|
### Progress Display
|
|
294
315
|
|
|
295
|
-
|
|
316
|
+
Simple progress display is enabled by default:
|
|
317
|
+
|
|
318
|
+
```text
|
|
319
|
+
⠹ [3/5] DeployTask | Uploading files...
|
|
320
|
+
✓ [5/5] All tasks completed (1234ms)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Tree mode** provides full dependency tree visualization:
|
|
296
324
|
|
|
297
325
|
```
|
|
298
326
|
WebServer (Task)
|
|
@@ -302,14 +330,7 @@ WebServer (Task)
|
|
|
302
330
|
└── ◻ Server (Task)
|
|
303
331
|
```
|
|
304
332
|
|
|
305
|
-
**
|
|
306
|
-
|
|
307
|
-
```
|
|
308
|
-
⠹ [3/5] DeployTask | Uploading files...
|
|
309
|
-
✓ [5/5] All tasks completed (1234ms)
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
**Plain mode** provides text output without escape codes (for CI/logs):
|
|
333
|
+
**Log mode** provides text output without escape codes (for CI/logs):
|
|
313
334
|
|
|
314
335
|
```
|
|
315
336
|
[START] DatabaseSetup
|
|
@@ -322,18 +343,12 @@ WebServer (Task)
|
|
|
322
343
|
**Configuration:**
|
|
323
344
|
|
|
324
345
|
```ruby
|
|
325
|
-
#
|
|
326
|
-
Taski.
|
|
327
|
-
Taski.
|
|
328
|
-
Taski.
|
|
329
|
-
|
|
330
|
-
# Via environment variable
|
|
331
|
-
TASKI_PROGRESS_MODE=simple ruby your_script.rb
|
|
332
|
-
TASKI_PROGRESS_MODE=plain ruby your_script.rb
|
|
346
|
+
Taski.progress_display = Taski::Progress::Layout::Simple.new # Simple display (default)
|
|
347
|
+
Taski.progress_display = Taski::Progress::Layout::Tree.new # Tree display
|
|
348
|
+
Taski.progress_display = Taski::Progress::Layout::Log.new # Log output (CI/logs)
|
|
349
|
+
Taski.progress_display = nil # Disable
|
|
333
350
|
```
|
|
334
351
|
|
|
335
|
-
To disable: `TASKI_PROGRESS_DISABLE=1 ruby your_script.rb`
|
|
336
|
-
|
|
337
352
|
### Tree Visualization
|
|
338
353
|
|
|
339
354
|
```ruby
|
data/docs/GUIDE.md
CHANGED
|
@@ -87,7 +87,9 @@ rescue DatabaseTask::Error => e
|
|
|
87
87
|
end
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
This works transparently with `AggregateError`
|
|
90
|
+
This works transparently with `AggregateError` — when you rescue `DatabaseTask::Error`, it matches an `AggregateError` that contains a `DatabaseTask::Error`.
|
|
91
|
+
|
|
92
|
+
**How this works:** Ruby's `rescue` uses the `===` operator to match exceptions. Taski's `AggregateAware` module (extended by `TaskError` and all `TaskClass::Error` classes) overrides `===` to check whether an `AggregateError` *contains* an error of that type. This means `rescue Taski::TaskError` will match an `AggregateError` wrapping TaskError instances, even though `AggregateError` does not inherit from `TaskError`.
|
|
91
93
|
|
|
92
94
|
### TaskAbortException
|
|
93
95
|
|
|
@@ -140,7 +142,7 @@ end
|
|
|
140
142
|
|
|
141
143
|
## Lifecycle Management
|
|
142
144
|
|
|
143
|
-
Taski supports resource cleanup with `
|
|
145
|
+
Taski supports resource cleanup with `run_and_clean`, which executes the run phase followed by the clean phase in a single operation.
|
|
144
146
|
|
|
145
147
|
### Basic Lifecycle
|
|
146
148
|
|
|
@@ -168,27 +170,24 @@ class WebServer < Taski::Task
|
|
|
168
170
|
end
|
|
169
171
|
end
|
|
170
172
|
|
|
171
|
-
#
|
|
172
|
-
WebServer.
|
|
173
|
+
# Run then clean in one call
|
|
174
|
+
WebServer.run_and_clean
|
|
173
175
|
# => Database connected
|
|
174
|
-
# => Server started
|
|
175
|
-
|
|
176
|
-
# Clean (reverse dependency order)
|
|
177
|
-
WebServer.clean
|
|
176
|
+
# => Server started
|
|
178
177
|
# => Server stopped
|
|
179
178
|
# => Database disconnected
|
|
180
179
|
```
|
|
181
180
|
|
|
182
|
-
### run_and_clean
|
|
181
|
+
### run_and_clean with Block
|
|
183
182
|
|
|
184
|
-
|
|
183
|
+
Use a block to execute code between run and clean phases. This is useful when you need to use exported values before cleanup:
|
|
185
184
|
|
|
186
185
|
```ruby
|
|
187
|
-
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
#
|
|
186
|
+
DatabaseSetup.run_and_clean do
|
|
187
|
+
# Exported values are accessible here
|
|
188
|
+
deploy(DatabaseSetup.connection)
|
|
189
|
+
end
|
|
190
|
+
# Clean runs automatically after the block
|
|
192
191
|
```
|
|
193
192
|
|
|
194
193
|
### Idempotent Clean Methods
|
|
@@ -289,21 +288,9 @@ After completion:
|
|
|
289
288
|
|
|
290
289
|
### Display Modes
|
|
291
290
|
|
|
292
|
-
Taski supports
|
|
293
|
-
|
|
294
|
-
#### Tree Mode (Default)
|
|
291
|
+
Taski supports three progress display modes:
|
|
295
292
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
```
|
|
299
|
-
WebServer (Task)
|
|
300
|
-
├── ⠋ Config (Task) | Reading config.yml...
|
|
301
|
-
│ ├── ✅ Database (Task) 45.2ms
|
|
302
|
-
│ └── ⠙ Cache (Task) | Connecting...
|
|
303
|
-
└── ◻ Server (Task)
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
#### Simple Mode
|
|
293
|
+
#### Simple Mode (Default)
|
|
307
294
|
|
|
308
295
|
Compact single-line display showing current progress:
|
|
309
296
|
|
|
@@ -324,7 +311,19 @@ On failure:
|
|
|
324
311
|
✗ [3/5] DeployTask failed: Connection refused
|
|
325
312
|
```
|
|
326
313
|
|
|
327
|
-
####
|
|
314
|
+
#### Tree Mode
|
|
315
|
+
|
|
316
|
+
Full dependency tree visualization with status for each task:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
WebServer (Task)
|
|
320
|
+
├── ⠋ Config (Task) | Reading config.yml...
|
|
321
|
+
│ ├── ✅ Database (Task) 45.2ms
|
|
322
|
+
│ └── ⠙ Cache (Task) | Connecting...
|
|
323
|
+
└── ◻ Server (Task)
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
#### Log Mode
|
|
328
327
|
|
|
329
328
|
Plain text output without escape codes, designed for CI/logs:
|
|
330
329
|
|
|
@@ -336,28 +335,13 @@ Plain text output without escape codes, designed for CI/logs:
|
|
|
336
335
|
[TASKI] Completed: 2/2 tasks (165ms)
|
|
337
336
|
```
|
|
338
337
|
|
|
339
|
-
### Configuring Progress
|
|
340
|
-
|
|
341
|
-
**Via API:**
|
|
338
|
+
### Configuring Progress Display
|
|
342
339
|
|
|
343
340
|
```ruby
|
|
344
|
-
Taski.
|
|
345
|
-
Taski.
|
|
346
|
-
Taski.
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
**Via environment variable:**
|
|
350
|
-
|
|
351
|
-
```bash
|
|
352
|
-
TASKI_PROGRESS_MODE=tree ruby your_script.rb
|
|
353
|
-
TASKI_PROGRESS_MODE=simple ruby your_script.rb
|
|
354
|
-
TASKI_PROGRESS_MODE=plain ruby your_script.rb
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
### Disabling Progress Display
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
TASKI_PROGRESS_DISABLE=1 ruby your_script.rb
|
|
341
|
+
Taski.progress_display = Taski::Progress::Layout::Simple.new # Simple display (default)
|
|
342
|
+
Taski.progress_display = Taski::Progress::Layout::Tree.new # Tree display
|
|
343
|
+
Taski.progress_display = Taski::Progress::Layout::Log.new # Log output (CI/logs)
|
|
344
|
+
Taski.progress_display = nil # Disable
|
|
361
345
|
```
|
|
362
346
|
|
|
363
347
|
### File Output Mode
|
|
@@ -372,13 +356,14 @@ ruby build.rb > build.log 2>&1
|
|
|
372
356
|
|
|
373
357
|
## Debugging
|
|
374
358
|
|
|
375
|
-
###
|
|
359
|
+
### Structured Logging
|
|
360
|
+
|
|
361
|
+
```ruby
|
|
362
|
+
require "logger"
|
|
363
|
+
Taski.logger = Logger.new($stdout, level: Logger::DEBUG)
|
|
364
|
+
```
|
|
376
365
|
|
|
377
|
-
|
|
378
|
-
|----------|---------|
|
|
379
|
-
| `TASKI_PROGRESS_DISABLE=1` | Disable progress display |
|
|
380
|
-
| `TASKI_PROGRESS_MODE=tree\|simple\|plain` | Set progress display mode (default: tree) |
|
|
381
|
-
| `TASKI_DEBUG=1` | Enable debug output |
|
|
366
|
+
Set `Taski.logger` to a Ruby `Logger` instance to enable structured logging of execution events.
|
|
382
367
|
|
|
383
368
|
### Dependency Tree Visualization
|
|
384
369
|
|
data/examples/README.md
CHANGED
|
@@ -19,22 +19,7 @@ ruby examples/quick_start.rb
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
### 2.
|
|
23
|
-
|
|
24
|
-
Switch implementations based on environment using the Section API.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
ruby examples/section_demo.rb
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**Covers:**
|
|
31
|
-
- `interfaces` for defining contracts
|
|
32
|
-
- Environment-specific implementations
|
|
33
|
-
- Dependency tree visualization with `.tree`
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
### 3. args_demo.rb - Runtime Args and Options
|
|
22
|
+
### 2. args_demo.rb - Runtime Args and Options
|
|
38
23
|
|
|
39
24
|
Access execution args and pass custom options to tasks.
|
|
40
25
|
|
|
@@ -52,22 +37,21 @@ ruby examples/args_demo.rb
|
|
|
52
37
|
|
|
53
38
|
---
|
|
54
39
|
|
|
55
|
-
###
|
|
40
|
+
### 3. reexecution_demo.rb - Scope-Based Execution
|
|
56
41
|
|
|
57
42
|
Understand scope-based execution and caching behavior.
|
|
58
43
|
|
|
59
44
|
```bash
|
|
60
|
-
|
|
45
|
+
ruby examples/reexecution_demo.rb
|
|
61
46
|
```
|
|
62
47
|
|
|
63
48
|
**Covers:**
|
|
64
49
|
- Fresh execution for each class method call
|
|
65
|
-
- Instance-level caching with `Task.new`
|
|
66
50
|
- Scope-based dependency caching
|
|
67
51
|
|
|
68
52
|
---
|
|
69
53
|
|
|
70
|
-
###
|
|
54
|
+
### 4. clean_demo.rb - Lifecycle Management
|
|
71
55
|
|
|
72
56
|
Demonstrates resource cleanup with clean methods.
|
|
73
57
|
|
|
@@ -79,10 +63,11 @@ ruby examples/clean_demo.rb
|
|
|
79
63
|
- Defining `clean` methods for resource cleanup
|
|
80
64
|
- Reverse dependency order execution
|
|
81
65
|
- `run_and_clean` combined operation
|
|
66
|
+
- `run_and_clean` with block support
|
|
82
67
|
|
|
83
68
|
---
|
|
84
69
|
|
|
85
|
-
###
|
|
70
|
+
### 5. group_demo.rb - Task Output Grouping
|
|
86
71
|
|
|
87
72
|
Organize task output into logical phases with groups.
|
|
88
73
|
|
|
@@ -97,7 +82,7 @@ ruby examples/group_demo.rb
|
|
|
97
82
|
|
|
98
83
|
---
|
|
99
84
|
|
|
100
|
-
###
|
|
85
|
+
### 6. message_demo.rb - User-Facing Messages
|
|
101
86
|
|
|
102
87
|
Output messages that bypass the progress display capture.
|
|
103
88
|
|
|
@@ -112,14 +97,12 @@ ruby examples/message_demo.rb
|
|
|
112
97
|
|
|
113
98
|
---
|
|
114
99
|
|
|
115
|
-
###
|
|
100
|
+
### 7. progress_demo.rb - Progress Display Modes
|
|
116
101
|
|
|
117
102
|
Real-time progress visualization during parallel execution.
|
|
118
103
|
|
|
119
104
|
```bash
|
|
120
|
-
ruby examples/progress_demo.rb
|
|
121
|
-
TASKI_PROGRESS_MODE=simple ruby examples/progress_demo.rb # Simple mode
|
|
122
|
-
TASKI_PROGRESS_DISABLE=1 ruby examples/progress_demo.rb # Disabled
|
|
105
|
+
ruby examples/progress_demo.rb # Simple mode (default)
|
|
123
106
|
```
|
|
124
107
|
|
|
125
108
|
**Covers:**
|
|
@@ -136,7 +119,6 @@ TASKI_PROGRESS_DISABLE=1 ruby examples/progress_demo.rb # Disabled
|
|
|
136
119
|
| Example | Feature | Complexity |
|
|
137
120
|
|---------|---------|------------|
|
|
138
121
|
| quick_start | Exports API | Basic |
|
|
139
|
-
| section_demo | Section API | Intermediate |
|
|
140
122
|
| args_demo | Args/Env API | Intermediate |
|
|
141
123
|
| reexecution_demo | Scope-Based Execution | Intermediate |
|
|
142
124
|
| clean_demo | Lifecycle Management | Intermediate |
|
|
@@ -150,8 +132,7 @@ TASKI_PROGRESS_DISABLE=1 ruby examples/progress_demo.rb # Disabled
|
|
|
150
132
|
# Run each example
|
|
151
133
|
for f in examples/*.rb; do echo "=== $f ===" && ruby "$f" && echo; done
|
|
152
134
|
|
|
153
|
-
# Disable progress display if needed
|
|
154
|
-
TASKI_PROGRESS_DISABLE=1 ruby examples/progress_demo.rb
|
|
135
|
+
# Disable progress display if needed (add Taski.progress_display = nil in script)
|
|
155
136
|
```
|
|
156
137
|
|
|
157
138
|
## Next Steps
|
data/examples/clean_demo.rb
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# This example demonstrates the clean functionality:
|
|
7
7
|
# - Defining clean methods for resource cleanup
|
|
8
8
|
# - Reverse dependency order execution (dependents cleaned before dependencies)
|
|
9
|
-
# -
|
|
9
|
+
# - run_and_clean with block support
|
|
10
10
|
#
|
|
11
11
|
# Run: ruby examples/clean_demo.rb
|
|
12
12
|
|
|
@@ -22,24 +22,14 @@ BUILD_DIR = "/tmp/taski_clean_demo"
|
|
|
22
22
|
class SetupBuildDir < Taski::Task
|
|
23
23
|
exports :build_path
|
|
24
24
|
|
|
25
|
-
##
|
|
26
|
-
# Prepares the task's build directory and simulates its creation.
|
|
27
|
-
#
|
|
28
|
-
# Sets the task's exported `build_path` to the "build" subdirectory under `BUILD_DIR`
|
|
29
|
-
# and performs a simulated creation step with informational output.
|
|
30
25
|
def run
|
|
31
26
|
@build_path = "#{BUILD_DIR}/build"
|
|
32
27
|
puts "[SetupBuildDir] Creating build directory: #{@build_path}"
|
|
33
|
-
# Simulated directory creation
|
|
34
28
|
sleep 0.8
|
|
35
29
|
end
|
|
36
30
|
|
|
37
|
-
##
|
|
38
|
-
# Removes the directory referenced by @build_path.
|
|
39
|
-
# Cleans up build artifacts created by this task.
|
|
40
31
|
def clean
|
|
41
32
|
puts "[SetupBuildDir] Removing build directory: #{@build_path}"
|
|
42
|
-
# Simulated directory removal
|
|
43
33
|
sleep 0.8
|
|
44
34
|
end
|
|
45
35
|
end
|
|
@@ -48,9 +38,6 @@ end
|
|
|
48
38
|
class CompileSource < Taski::Task
|
|
49
39
|
exports :binary_path
|
|
50
40
|
|
|
51
|
-
##
|
|
52
|
-
# Compiles source artifacts and sets the compiled binary path for downstream tasks.
|
|
53
|
-
# This method sets @binary_path to the build directory's "app.bin" file and emits a console message indicating the compilation target.
|
|
54
41
|
def run
|
|
55
42
|
build_dir = SetupBuildDir.build_path
|
|
56
43
|
@binary_path = "#{build_dir}/app.bin"
|
|
@@ -58,9 +45,6 @@ class CompileSource < Taski::Task
|
|
|
58
45
|
sleep 1.5
|
|
59
46
|
end
|
|
60
47
|
|
|
61
|
-
##
|
|
62
|
-
# Removes the compiled binary produced by this task.
|
|
63
|
-
# Performs the task's cleanup step and simulates the deletion process.
|
|
64
48
|
def clean
|
|
65
49
|
puts "[CompileSource] Removing compiled binary: #{@binary_path}"
|
|
66
50
|
sleep 0.6
|
|
@@ -71,11 +55,6 @@ end
|
|
|
71
55
|
class GenerateDocs < Taski::Task
|
|
72
56
|
exports :docs_path
|
|
73
57
|
|
|
74
|
-
##
|
|
75
|
-
# Generates documentation for the build and records the output path.
|
|
76
|
-
#
|
|
77
|
-
# Sets the task's `@docs_path` to the "docs" subdirectory under `SetupBuildDir.build_path`
|
|
78
|
-
# and prints a progress message to STDOUT.
|
|
79
58
|
def run
|
|
80
59
|
build_dir = SetupBuildDir.build_path
|
|
81
60
|
@docs_path = "#{build_dir}/docs"
|
|
@@ -83,9 +62,6 @@ class GenerateDocs < Taski::Task
|
|
|
83
62
|
sleep 1.2
|
|
84
63
|
end
|
|
85
64
|
|
|
86
|
-
##
|
|
87
|
-
# Removes the generated documentation at the task's docs_path.
|
|
88
|
-
# Prints a removal message for @docs_path and simulates its deletion.
|
|
89
65
|
def clean
|
|
90
66
|
puts "[GenerateDocs] Removing generated docs: #{@docs_path}"
|
|
91
67
|
sleep 0.5
|
|
@@ -96,9 +72,6 @@ end
|
|
|
96
72
|
class CreateRelease < Taski::Task
|
|
97
73
|
exports :release_path
|
|
98
74
|
|
|
99
|
-
##
|
|
100
|
-
# Creates the release package path and announces the included artifacts.
|
|
101
|
-
# Uses CompileSource.binary_path and GenerateDocs.docs_path to determine the package inputs, sets @release_path to "#{BUILD_DIR}/release.zip", and prints the binary, docs, and output paths.
|
|
102
75
|
def run
|
|
103
76
|
binary = CompileSource.binary_path
|
|
104
77
|
docs = GenerateDocs.docs_path
|
|
@@ -110,9 +83,6 @@ class CreateRelease < Taski::Task
|
|
|
110
83
|
sleep 0.7
|
|
111
84
|
end
|
|
112
85
|
|
|
113
|
-
##
|
|
114
|
-
# Removes the release package produced by this task.
|
|
115
|
-
# Uses the task's `@release_path` as the target for cleanup.
|
|
116
86
|
def clean
|
|
117
87
|
puts "[CreateRelease] Removing release package: #{@release_path}"
|
|
118
88
|
sleep 0.5
|
|
@@ -123,54 +93,44 @@ puts "\n--- Task Tree Structure ---"
|
|
|
123
93
|
puts CreateRelease.tree
|
|
124
94
|
puts
|
|
125
95
|
|
|
126
|
-
puts "---
|
|
127
|
-
|
|
96
|
+
puts "--- run_and_clean Demo ---"
|
|
97
|
+
puts "The run_and_clean method executes both phases in a single operation."
|
|
98
|
+
puts "Key benefits:"
|
|
99
|
+
puts " - Single progress display session for both phases"
|
|
100
|
+
puts " - Clean always runs, even if run fails (resource release)"
|
|
101
|
+
puts " - Cleaner API for the common use case"
|
|
128
102
|
puts
|
|
129
103
|
|
|
130
|
-
|
|
131
|
-
puts " Release: #{CreateRelease.release_path}"
|
|
132
|
-
puts
|
|
104
|
+
CreateRelease.run_and_clean
|
|
133
105
|
|
|
134
|
-
puts
|
|
135
|
-
puts "
|
|
136
|
-
puts " and finally SetupBuildDir cleans last."
|
|
106
|
+
puts
|
|
107
|
+
puts "Both run and clean phases completed in a single call!"
|
|
137
108
|
puts
|
|
138
109
|
|
|
139
|
-
#
|
|
110
|
+
# Demonstrate block support
|
|
140
111
|
Taski::Task.reset!
|
|
141
112
|
|
|
142
|
-
# Re-run to set up state for clean
|
|
143
|
-
CreateRelease.run
|
|
144
|
-
|
|
145
|
-
puts "\nNow cleaning..."
|
|
146
|
-
CreateRelease.clean
|
|
147
|
-
|
|
148
|
-
puts
|
|
149
|
-
puts "Clean completed! All artifacts removed."
|
|
150
|
-
|
|
151
|
-
puts
|
|
152
113
|
puts "=" * 40
|
|
153
|
-
puts "run_and_clean Demo"
|
|
114
|
+
puts "run_and_clean with Block Demo"
|
|
154
115
|
puts "=" * 40
|
|
155
116
|
puts
|
|
156
|
-
puts "
|
|
157
|
-
puts "
|
|
158
|
-
puts " - Single progress display session for both phases"
|
|
159
|
-
puts " - Clean always runs, even if run fails (resource release)"
|
|
160
|
-
puts " - Cleaner API for the common use case"
|
|
117
|
+
puts "Use a block to execute code between run and clean phases."
|
|
118
|
+
puts "Exported values are accessible within the block."
|
|
161
119
|
puts
|
|
162
120
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
puts "
|
|
167
|
-
puts "
|
|
168
|
-
puts
|
|
169
|
-
|
|
170
|
-
|
|
121
|
+
CreateRelease.run_and_clean do
|
|
122
|
+
puts
|
|
123
|
+
puts "[Block] Release created at: #{CreateRelease.release_path}"
|
|
124
|
+
puts "[Block] Binary: #{CompileSource.binary_path}"
|
|
125
|
+
puts "[Block] Docs: #{GenerateDocs.docs_path}"
|
|
126
|
+
puts "[Block] Deploying release..."
|
|
127
|
+
sleep 0.3
|
|
128
|
+
puts "[Block] Deploy complete!"
|
|
129
|
+
puts
|
|
130
|
+
end
|
|
171
131
|
|
|
172
132
|
puts
|
|
173
|
-
puts "
|
|
133
|
+
puts "Block executed between run and clean phases!"
|
|
174
134
|
puts
|
|
175
135
|
|
|
176
136
|
# Demonstrate error handling
|