taski 0.7.0 → 0.7.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 +128 -0
- data/docs/GUIDE.md +54 -0
- data/examples/data_pipeline_demo.rb +1 -1
- data/examples/large_tree_demo.rb +519 -0
- data/examples/simple_progress_demo.rb +80 -0
- data/lib/taski/execution/base_progress_display.rb +348 -0
- data/lib/taski/execution/execution_context.rb +4 -0
- data/lib/taski/execution/executor.rb +111 -131
- data/lib/taski/execution/plain_progress_display.rb +76 -0
- data/lib/taski/execution/simple_progress_display.rb +173 -0
- data/lib/taski/execution/task_output_router.rb +91 -20
- data/lib/taski/execution/task_wrapper.rb +23 -30
- data/lib/taski/execution/tree_progress_display.rb +121 -271
- data/lib/taski/static_analysis/visitor.rb +3 -0
- data/lib/taski/task.rb +19 -24
- data/lib/taski/test_helper/errors.rb +13 -0
- data/lib/taski/test_helper/minitest.rb +38 -0
- data/lib/taski/test_helper/mock_registry.rb +51 -0
- data/lib/taski/test_helper/mock_wrapper.rb +46 -0
- data/lib/taski/test_helper/rspec.rb +38 -0
- data/lib/taski/test_helper.rb +214 -0
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +79 -6
- metadata +13 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ca85800083318a5bc4d40151f14e5c55d6474a81a89a095de6d2433a8609043
|
|
4
|
+
data.tar.gz: d68b0a3f9bf5bab689882df7cdf22fe02a169008a3d4bd64a24eaea2699dce33
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3705a29cdf6e5fbe4a244b9431c35bc326e2c383f71e00fe7223a1e87f98728e565e1faebbd081111ab8127197e39294c89d05c6e35511b8405425f21b6a8af3
|
|
7
|
+
data.tar.gz: 87d334c0e053bbd164c260e304f642a26305f14021de17bf10bb8d50180fd0160338efbca0821a3fc3af996b8212e3a10c52d5e533c54b6141b069e17f21af7a
|
data/README.md
CHANGED
|
@@ -113,6 +113,87 @@ end
|
|
|
113
113
|
|
|
114
114
|
> **Note**: Nested implementation classes automatically inherit Section's `interfaces` as `exports`.
|
|
115
115
|
|
|
116
|
+
## Best Practices
|
|
117
|
+
|
|
118
|
+
### Keep Tasks Small and Focused
|
|
119
|
+
|
|
120
|
+
Each task should do **one thing only**. While Taski allows you to write complex logic within a single task, keeping tasks small and focused provides significant benefits:
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
# ✅ Good: Small, focused tasks
|
|
124
|
+
class FetchData < Taski::Task
|
|
125
|
+
exports :data
|
|
126
|
+
def run
|
|
127
|
+
@data = API.fetch
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
class TransformData < Taski::Task
|
|
132
|
+
exports :result
|
|
133
|
+
def run
|
|
134
|
+
@result = FetchData.data.transform
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class SaveData < Taski::Task
|
|
139
|
+
def run
|
|
140
|
+
Database.save(TransformData.result)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# ❌ Avoid: Monolithic task doing everything
|
|
145
|
+
class DoEverything < Taski::Task
|
|
146
|
+
def run
|
|
147
|
+
data = API.fetch
|
|
148
|
+
result = data.transform
|
|
149
|
+
Database.save(result)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Why small tasks matter:**
|
|
155
|
+
|
|
156
|
+
- **Parallel Execution**: Independent tasks run concurrently. Large monolithic tasks can't be parallelized
|
|
157
|
+
- **Easier Cleanup**: `Task.clean` works per-task. Smaller tasks mean more granular cleanup control
|
|
158
|
+
- **Better Reusability**: Small tasks can be composed into different workflows
|
|
159
|
+
- **Clearer Dependencies**: The dependency graph becomes explicit and visible with `Task.tree`
|
|
160
|
+
|
|
161
|
+
**Note:** Complex internal logic is perfectly fine. "One thing" means one responsibility, not one line of code. Other tasks only care about the exported results, not how they were computed.
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
class RawData < Taski::Task
|
|
165
|
+
exports :data
|
|
166
|
+
def run
|
|
167
|
+
@data = API.fetch
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
class ProcessedData < Taski::Task
|
|
172
|
+
exports :result
|
|
173
|
+
|
|
174
|
+
def run
|
|
175
|
+
# Complex internal logic is OK - this task has one responsibility:
|
|
176
|
+
# producing the processed result
|
|
177
|
+
validated = validate_and_clean(RawData.data)
|
|
178
|
+
enriched = enrich_with_metadata(validated)
|
|
179
|
+
normalized = normalize_format(enriched)
|
|
180
|
+
@result = apply_business_rules(normalized)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
def validate_and_clean(data)
|
|
186
|
+
# Complex validation logic...
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def enrich_with_metadata(data)
|
|
190
|
+
# Complex enrichment logic...
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# ... other private methods
|
|
194
|
+
end
|
|
195
|
+
```
|
|
196
|
+
|
|
116
197
|
## Advanced Usage
|
|
117
198
|
|
|
118
199
|
### Args - Runtime Information and Options
|
|
@@ -191,6 +272,23 @@ WebServer (Task)
|
|
|
191
272
|
└── ◻ Server (Task)
|
|
192
273
|
```
|
|
193
274
|
|
|
275
|
+
**Simple mode** provides a compact single-line display:
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
⠹ [3/5] DeployTask | Uploading files...
|
|
279
|
+
✓ [5/5] All tasks completed (1234ms)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Configuration:**
|
|
283
|
+
|
|
284
|
+
```ruby
|
|
285
|
+
# Via API
|
|
286
|
+
Taski.progress_mode = :simple # or :tree (default)
|
|
287
|
+
|
|
288
|
+
# Via environment variable
|
|
289
|
+
TASKI_PROGRESS_MODE=simple ruby your_script.rb
|
|
290
|
+
```
|
|
291
|
+
|
|
194
292
|
To disable: `TASKI_PROGRESS_DISABLE=1 ruby your_script.rb`
|
|
195
293
|
|
|
196
294
|
### Tree Visualization
|
|
@@ -203,6 +301,36 @@ puts WebServer.tree
|
|
|
203
301
|
# └── Cache (Task)
|
|
204
302
|
```
|
|
205
303
|
|
|
304
|
+
## Testing
|
|
305
|
+
|
|
306
|
+
### Test Helper for Mocking Dependencies
|
|
307
|
+
|
|
308
|
+
Taski provides a test helper to mock task dependencies in your unit tests:
|
|
309
|
+
|
|
310
|
+
```ruby
|
|
311
|
+
require 'taski/test_helper/minitest'
|
|
312
|
+
|
|
313
|
+
class BuildReportTest < Minitest::Test
|
|
314
|
+
include Taski::TestHelper::Minitest
|
|
315
|
+
|
|
316
|
+
def test_builds_report
|
|
317
|
+
# Mock direct dependencies - their run methods won't execute
|
|
318
|
+
mock_task(FetchData, users: [1, 2, 3])
|
|
319
|
+
|
|
320
|
+
# Task under test uses mocked values
|
|
321
|
+
assert_equal 3, BuildReport.user_count
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Key features:**
|
|
327
|
+
- Mock only direct dependencies; indirect dependencies are automatically isolated
|
|
328
|
+
- Verify which dependencies were accessed with `assert_task_accessed` / `refute_task_accessed`
|
|
329
|
+
- Automatic cleanup after each test
|
|
330
|
+
- Supports both Minitest and RSpec
|
|
331
|
+
|
|
332
|
+
For RSpec, use `include Taski::TestHelper::RSpec` instead.
|
|
333
|
+
|
|
206
334
|
## Development
|
|
207
335
|
|
|
208
336
|
```bash
|
data/docs/GUIDE.md
CHANGED
|
@@ -287,6 +287,59 @@ After completion:
|
|
|
287
287
|
└── Server (Task) 70.2ms
|
|
288
288
|
```
|
|
289
289
|
|
|
290
|
+
### Display Modes
|
|
291
|
+
|
|
292
|
+
Taski supports two progress display modes:
|
|
293
|
+
|
|
294
|
+
#### Tree Mode (Default)
|
|
295
|
+
|
|
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
|
|
307
|
+
|
|
308
|
+
Compact single-line display showing current progress:
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
⠹ [3/5] DeployTask | Uploading files...
|
|
312
|
+
✓ [5/5] All tasks completed (1234ms)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Format: `[spinner] [completed/total] TaskName | last output...`
|
|
316
|
+
|
|
317
|
+
When multiple tasks run in parallel:
|
|
318
|
+
```
|
|
319
|
+
⠹ [2/5] DownloadLayer1, DownloadLayer2 | Downloading...
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
On failure:
|
|
323
|
+
```
|
|
324
|
+
✗ [3/5] DeployTask failed: Connection refused
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Configuring Progress Mode
|
|
328
|
+
|
|
329
|
+
**Via API:**
|
|
330
|
+
|
|
331
|
+
```ruby
|
|
332
|
+
Taski.progress_mode = :simple # Use simple mode
|
|
333
|
+
Taski.progress_mode = :tree # Use tree mode (default)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Via environment variable:**
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
TASKI_PROGRESS_MODE=simple ruby your_script.rb
|
|
340
|
+
TASKI_PROGRESS_MODE=tree ruby your_script.rb
|
|
341
|
+
```
|
|
342
|
+
|
|
290
343
|
### Disabling Progress Display
|
|
291
344
|
|
|
292
345
|
```bash
|
|
@@ -310,6 +363,7 @@ ruby build.rb > build.log 2>&1
|
|
|
310
363
|
| Variable | Purpose |
|
|
311
364
|
|----------|---------|
|
|
312
365
|
| `TASKI_PROGRESS_DISABLE=1` | Disable progress display |
|
|
366
|
+
| `TASKI_PROGRESS_MODE=simple\|tree` | Set progress display mode (default: tree) |
|
|
313
367
|
| `TASKI_DEBUG=1` | Enable debug output |
|
|
314
368
|
|
|
315
369
|
### Dependency Tree Visualization
|
|
@@ -129,7 +129,7 @@ class EnrichWithActivities < Taski::Task
|
|
|
129
129
|
|
|
130
130
|
activities_by_user = activities.group_by { |a| a[:user_id] }
|
|
131
131
|
.transform_values do |records|
|
|
132
|
-
|
|
132
|
+
records.to_h { |r| [r[:action], r[:count]] }
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
@users_with_activities = users.map do |user|
|