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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +65 -50
  4. data/docs/GUIDE.md +41 -56
  5. data/examples/README.md +10 -29
  6. data/examples/clean_demo.rb +25 -65
  7. data/examples/large_tree_demo.rb +356 -0
  8. data/examples/message_demo.rb +0 -1
  9. data/examples/progress_demo.rb +13 -24
  10. data/examples/reexecution_demo.rb +8 -44
  11. data/lib/taski/execution/execution_facade.rb +150 -0
  12. data/lib/taski/execution/executor.rb +156 -357
  13. data/lib/taski/execution/registry.rb +15 -19
  14. data/lib/taski/execution/scheduler.rb +161 -140
  15. data/lib/taski/execution/task_observer.rb +41 -0
  16. data/lib/taski/execution/task_output_router.rb +41 -58
  17. data/lib/taski/execution/task_wrapper.rb +123 -219
  18. data/lib/taski/execution/worker_pool.rb +238 -64
  19. data/lib/taski/logging.rb +105 -0
  20. data/lib/taski/progress/layout/base.rb +600 -0
  21. data/lib/taski/progress/layout/filters.rb +126 -0
  22. data/lib/taski/progress/layout/log.rb +27 -0
  23. data/lib/taski/progress/layout/simple.rb +166 -0
  24. data/lib/taski/progress/layout/tags.rb +76 -0
  25. data/lib/taski/progress/layout/theme_drop.rb +84 -0
  26. data/lib/taski/progress/layout/tree.rb +300 -0
  27. data/lib/taski/progress/theme/base.rb +224 -0
  28. data/lib/taski/progress/theme/compact.rb +58 -0
  29. data/lib/taski/progress/theme/default.rb +25 -0
  30. data/lib/taski/progress/theme/detail.rb +48 -0
  31. data/lib/taski/progress/theme/plain.rb +40 -0
  32. data/lib/taski/static_analysis/analyzer.rb +5 -17
  33. data/lib/taski/static_analysis/dependency_graph.rb +19 -1
  34. data/lib/taski/static_analysis/visitor.rb +1 -39
  35. data/lib/taski/task.rb +44 -58
  36. data/lib/taski/test_helper/errors.rb +1 -1
  37. data/lib/taski/test_helper.rb +21 -35
  38. data/lib/taski/version.rb +1 -1
  39. data/lib/taski.rb +60 -61
  40. data/sig/taski.rbs +194 -203
  41. metadata +31 -8
  42. data/examples/section_demo.rb +0 -195
  43. data/lib/taski/execution/base_progress_display.rb +0 -393
  44. data/lib/taski/execution/execution_context.rb +0 -390
  45. data/lib/taski/execution/plain_progress_display.rb +0 -76
  46. data/lib/taski/execution/simple_progress_display.rb +0 -247
  47. data/lib/taski/execution/tree_progress_display.rb +0 -643
  48. data/lib/taski/section.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cddae184fb1f55c69b42995e51c3bf5711d31f978ec383a00a73d2ce3531ca15
4
- data.tar.gz: 3e79ca2bf3a6cd163272bbff98ff3b980f3a3b69293607dd45879501d50904c4
3
+ metadata.gz: 1ad85c90c371fc1ea2f61e1d7e9817c7a9cc3fa9f258be2bf1154ced5f4c0349
4
+ data.tar.gz: a56399d990f0a3ecfddff0f24b5a45c8319ea88e58299a3d3a22a2336295f5cc
5
5
  SHA512:
6
- metadata.gz: 9310e8b52be98d9087de88b4b7f5d105896edd85137c2f43e6c968c8daaf00dc6b4843ff9d1f228a089dcd7ceb379715c2b640d3c547ce173659dc7130cd1768
7
- data.tar.gz: 65bade2024691c9c7527f6249294d01714563ff35c211472e6d984e82ba5acd0767251d33e05d8ade4208eabc8b1326eb47fc4f932b4699bf0b986e208fffcea
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
- - **Two Simple APIs**: Exports (value sharing) and Section (runtime selection)
15
+ - **Exports API**: Simple value sharing between tasks
16
16
  - **Real-time Progress**: Visual feedback with parallel task progress display
17
- - **Thread-Safe**: Built on Monitor-based synchronization for reliable concurrent execution
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
- ### Section - Runtime Implementation Selection
80
+ ### Conditional Logic - Runtime Selection
81
81
 
82
- Switch implementations based on environment:
82
+ Use `if` statements to switch behavior based on environment:
83
83
 
84
84
  ```ruby
85
- class DatabaseSection < Taski::Section
86
- interfaces :host, :port
85
+ class DatabaseConfig < Taski::Task
86
+ exports :host, :port
87
87
 
88
- class Production < Taski::Task
89
- def run
88
+ def run
89
+ if ENV['RAILS_ENV'] == 'production'
90
90
  @host = "prod.example.com"
91
91
  @port = 5432
92
- end
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 #{DatabaseSection.host}:#{DatabaseSection.port}"
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
- # Or separately
286
- DatabaseSetup.run
287
- # ... do work ...
288
- DatabaseSetup.clean
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/guide.md](docs/guide.md#lifecycle-management) for details.
312
+ See [docs/GUIDE.md](docs/GUIDE.md#lifecycle-management) for details.
292
313
 
293
314
  ### Progress Display
294
315
 
295
- Tree-based progress visualization is enabled by default:
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
- **Simple mode** provides a compact single-line display:
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
- # Via API
326
- Taski.progress_mode = :tree # Tree display (default)
327
- Taski.progress_mode = :simple # Single-line display
328
- Taski.progress_mode = :plain # Plain text (CI/logs)
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` - when you rescue `DatabaseTask::Error`, it matches an `AggregateError` that contains a `DatabaseTask::Error`.
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 `run`, `clean`, and `run_and_clean` methods.
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
- # Start
172
- WebServer.run
173
+ # Run then clean in one call
174
+ WebServer.run_and_clean
173
175
  # => Database connected
174
- # => Server started with postgresql://localhost:5432/myapp
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
- Execute run followed by clean in a single operation:
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
- WebServer.run_and_clean
188
- # => Database connected
189
- # => Server started
190
- # => Server stopped
191
- # => Database disconnected
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 two progress display modes:
293
-
294
- #### Tree Mode (Default)
291
+ Taski supports three progress display modes:
295
292
 
296
- Full dependency tree visualization with status for each task:
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
- #### Plain Mode
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 Mode
340
-
341
- **Via API:**
338
+ ### Configuring Progress Display
342
339
 
343
340
  ```ruby
344
- Taski.progress_mode = :tree # Tree display (default)
345
- Taski.progress_mode = :simple # Single-line display
346
- Taski.progress_mode = :plain # Plain text (CI/logs)
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
- ### Environment Variables
359
+ ### Structured Logging
360
+
361
+ ```ruby
362
+ require "logger"
363
+ Taski.logger = Logger.new($stdout, level: Logger::DEBUG)
364
+ ```
376
365
 
377
- | Variable | Purpose |
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. section_demo.rb - Runtime Implementation Selection
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
- ### 4. reexecution_demo.rb - Scope-Based Execution
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
- TASKI_PROGRESS_DISABLE=1 ruby examples/reexecution_demo.rb
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
- ### 5. clean_demo.rb - Lifecycle Management
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
- ### 6. group_demo.rb - Task Output Grouping
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
- ### 7. message_demo.rb - User-Facing Messages
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
- ### 8. progress_demo.rb - Progress Display Modes
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 # Tree mode
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
@@ -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
- # - Parallel clean execution when possible
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 "--- Running build process ---"
127
- CreateRelease.run
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
- puts "Build completed!"
131
- puts " Release: #{CreateRelease.release_path}"
132
- puts
104
+ CreateRelease.run_and_clean
133
105
 
134
- puts "--- Cleaning up (reverse dependency order) ---"
135
- puts "Note: CreateRelease cleans first, then CompileSource/GenerateDocs in parallel,"
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
- # Reset to allow clean execution
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 "The run_and_clean method executes both phases in a single operation."
157
- puts "Key benefits:"
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
- # Reset for new demonstration
164
- Taski::Task.reset!
165
-
166
- puts "--- Using run_and_clean ---"
167
- puts "This is equivalent to calling run followed by clean, but in a single operation."
168
- puts
169
-
170
- CreateRelease.run_and_clean
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 "Both run and clean phases completed in a single call!"
133
+ puts "Block executed between run and clean phases!"
174
134
  puts
175
135
 
176
136
  # Demonstrate error handling