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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e593418f036752e5adf6bb989cfc800ee249be3b3a7ace71df377a5aa1b73bf
4
- data.tar.gz: 4e69af8247ade3e1e585475dcab88ae73fa42a71a60d4bbcc420456b1b2d9de5
3
+ metadata.gz: 0ca85800083318a5bc4d40151f14e5c55d6474a81a89a095de6d2433a8609043
4
+ data.tar.gz: d68b0a3f9bf5bab689882df7cdf22fe02a169008a3d4bd64a24eaea2699dce33
5
5
  SHA512:
6
- metadata.gz: 339d64fa997095a68adffa2d7227c5e648dc147edf576824283328a1e655706d6e72666fd56a8d8f934283ddd399eb691467121381f995b8540c798bb7f28c87
7
- data.tar.gz: 3d5d41b708ab1d9f715bc0848d22b7b4233b50b6f922440ec304fb3c32a2b86bddf936839387462370a8b2df0e9de9d8200b9733aa8fdafdf3fa2536e21835ab
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
- records.to_h { |r| [r[:action], r[:count]] }
132
+ records.to_h { |r| [r[:action], r[:count]] }
133
133
  end
134
134
 
135
135
  @users_with_activities = users.map do |user|