taski 0.8.1 → 0.8.2
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 +9 -0
- data/README.md +42 -1
- data/docs/GUIDE.md +18 -4
- data/examples/README.md +33 -45
- data/examples/progress_demo.rb +154 -0
- data/lib/taski/execution/base_progress_display.rb +16 -0
- data/lib/taski/execution/execution_context.rb +2 -21
- data/lib/taski/execution/executor.rb +0 -8
- data/lib/taski/execution/simple_progress_display.rb +8 -2
- data/lib/taski/execution/task_output_router.rb +2 -1
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +3 -3
- metadata +2 -8
- data/examples/data_pipeline_demo.rb +0 -231
- data/examples/large_tree_demo.rb +0 -519
- data/examples/nested_section_demo.rb +0 -161
- data/examples/parallel_progress_demo.rb +0 -72
- data/examples/simple_progress_demo.rb +0 -80
- data/examples/system_call_demo.rb +0 -56
- data/examples/tree_progress_demo.rb +0 -164
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# Taski Data Pipeline Example
|
|
5
|
-
#
|
|
6
|
-
# This example demonstrates a realistic data processing pipeline:
|
|
7
|
-
# - Section API for switching data sources (production vs test)
|
|
8
|
-
# - Multiple data sources fetched in parallel
|
|
9
|
-
# - Data transformation and aggregation
|
|
10
|
-
#
|
|
11
|
-
# Run: ruby examples/data_pipeline_demo.rb
|
|
12
|
-
# Disable progress: TASKI_PROGRESS_DISABLE=1 ruby examples/data_pipeline_demo.rb
|
|
13
|
-
|
|
14
|
-
require_relative "../lib/taski"
|
|
15
|
-
|
|
16
|
-
# Section: Data source abstraction
|
|
17
|
-
# Switch between production API and test fixtures
|
|
18
|
-
class DataSourceSection < Taski::Section
|
|
19
|
-
interfaces :users, :sales, :activities
|
|
20
|
-
|
|
21
|
-
def impl
|
|
22
|
-
(ENV["USE_TEST_DATA"] == "true") ? TestData : ProductionData
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Production: Fetch from APIs (simulated with delays)
|
|
26
|
-
class ProductionData < Taski::Task
|
|
27
|
-
def run
|
|
28
|
-
puts " [ProductionData] Fetching from APIs..."
|
|
29
|
-
sleep(0.3)
|
|
30
|
-
|
|
31
|
-
@users = [
|
|
32
|
-
{id: 1, name: "Alice", department: "Engineering"},
|
|
33
|
-
{id: 2, name: "Bob", department: "Sales"},
|
|
34
|
-
{id: 3, name: "Charlie", department: "Engineering"},
|
|
35
|
-
{id: 4, name: "Diana", department: "Marketing"}
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
@sales = [
|
|
39
|
-
{user_id: 2, amount: 1000, date: "2024-01"},
|
|
40
|
-
{user_id: 2, amount: 1500, date: "2024-02"},
|
|
41
|
-
{user_id: 4, amount: 800, date: "2024-01"}
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
@activities = [
|
|
45
|
-
{user_id: 1, action: :commit, count: 45},
|
|
46
|
-
{user_id: 3, action: :commit, count: 32},
|
|
47
|
-
{user_id: 1, action: :review, count: 12},
|
|
48
|
-
{user_id: 3, action: :review, count: 8}
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
puts " [ProductionData] Loaded #{@users.size} users, #{@sales.size} sales, #{@activities.size} activities"
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Test: Minimal fixture data (no delays)
|
|
56
|
-
class TestData < Taski::Task
|
|
57
|
-
def run
|
|
58
|
-
puts " [TestData] Loading test fixtures..."
|
|
59
|
-
|
|
60
|
-
@users = [
|
|
61
|
-
{id: 1, name: "Test User", department: "Test Dept"}
|
|
62
|
-
]
|
|
63
|
-
|
|
64
|
-
@sales = [
|
|
65
|
-
{user_id: 1, amount: 100, date: "2024-01"}
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
@activities = [
|
|
69
|
-
{user_id: 1, action: :commit, count: 10}
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
puts " [TestData] Loaded minimal test data"
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Section: Report format selection
|
|
78
|
-
class ReportFormatSection < Taski::Section
|
|
79
|
-
interfaces :format_report
|
|
80
|
-
|
|
81
|
-
def impl
|
|
82
|
-
(ENV["REPORT_FORMAT"] == "json") ? JsonFormat : TextFormat
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
class TextFormat < Taski::Task
|
|
86
|
-
def run
|
|
87
|
-
@format_report = ->(report) {
|
|
88
|
-
report.map do |dept, stats|
|
|
89
|
-
"#{dept}: #{stats[:user_count]} users, $#{stats[:total_sales]} sales"
|
|
90
|
-
end.join("\n")
|
|
91
|
-
}
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
class JsonFormat < Taski::Task
|
|
96
|
-
def run
|
|
97
|
-
require "json"
|
|
98
|
-
@format_report = ->(report) { JSON.pretty_generate(report) }
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Transform: Enrich users with sales data
|
|
104
|
-
class EnrichWithSales < Taski::Task
|
|
105
|
-
exports :users_with_sales
|
|
106
|
-
|
|
107
|
-
def run
|
|
108
|
-
users = DataSourceSection.users
|
|
109
|
-
sales = DataSourceSection.sales
|
|
110
|
-
|
|
111
|
-
sales_by_user = sales.group_by { |s| s[:user_id] }
|
|
112
|
-
.transform_values { |records| records.sum { |r| r[:amount] } }
|
|
113
|
-
|
|
114
|
-
@users_with_sales = users.map do |user|
|
|
115
|
-
user.merge(total_sales: sales_by_user[user[:id]] || 0)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
puts " [EnrichWithSales] Enriched #{@users_with_sales.size} users"
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
# Transform: Enrich users with activity data
|
|
123
|
-
class EnrichWithActivities < Taski::Task
|
|
124
|
-
exports :users_with_activities
|
|
125
|
-
|
|
126
|
-
def run
|
|
127
|
-
users = DataSourceSection.users
|
|
128
|
-
activities = DataSourceSection.activities
|
|
129
|
-
|
|
130
|
-
activities_by_user = activities.group_by { |a| a[:user_id] }
|
|
131
|
-
.transform_values do |records|
|
|
132
|
-
records.to_h { |r| [r[:action], r[:count]] }
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
@users_with_activities = users.map do |user|
|
|
136
|
-
user.merge(activities: activities_by_user[user[:id]] || {})
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
puts " [EnrichWithActivities] Enriched #{@users_with_activities.size} users"
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Aggregate: Combine enrichments into profiles
|
|
144
|
-
class BuildProfiles < Taski::Task
|
|
145
|
-
exports :profiles
|
|
146
|
-
|
|
147
|
-
def run
|
|
148
|
-
users_sales = EnrichWithSales.users_with_sales
|
|
149
|
-
users_activities = EnrichWithActivities.users_with_activities
|
|
150
|
-
|
|
151
|
-
activities_map = users_activities.to_h { |u| [u[:id], u[:activities]] }
|
|
152
|
-
|
|
153
|
-
@profiles = users_sales.map do |user|
|
|
154
|
-
user.merge(activities: activities_map[user[:id]] || {})
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
puts " [BuildProfiles] Built #{@profiles.size} profiles"
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Output: Generate department report
|
|
162
|
-
class GenerateReport < Taski::Task
|
|
163
|
-
exports :report, :formatted_output
|
|
164
|
-
|
|
165
|
-
def run
|
|
166
|
-
profiles = BuildProfiles.profiles
|
|
167
|
-
formatter = ReportFormatSection.format_report
|
|
168
|
-
|
|
169
|
-
by_department = profiles.group_by { |p| p[:department] }
|
|
170
|
-
|
|
171
|
-
@report = by_department.transform_values do |dept_users|
|
|
172
|
-
{
|
|
173
|
-
user_count: dept_users.size,
|
|
174
|
-
total_sales: dept_users.sum { |u| u[:total_sales] },
|
|
175
|
-
total_commits: dept_users.sum { |u| u[:activities][:commit] || 0 },
|
|
176
|
-
total_reviews: dept_users.sum { |u| u[:activities][:review] || 0 }
|
|
177
|
-
}
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
@formatted_output = formatter.call(@report)
|
|
181
|
-
puts " [GenerateReport] Generated report for #{@report.size} departments"
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Demo execution
|
|
186
|
-
puts "Taski Data Pipeline Demo"
|
|
187
|
-
puts "=" * 50
|
|
188
|
-
|
|
189
|
-
puts "\n1. Dependency Tree"
|
|
190
|
-
puts "-" * 50
|
|
191
|
-
puts GenerateReport.tree
|
|
192
|
-
|
|
193
|
-
puts "\n2. Production Data (default)"
|
|
194
|
-
puts "-" * 50
|
|
195
|
-
ENV["USE_TEST_DATA"] = "false"
|
|
196
|
-
ENV["REPORT_FORMAT"] = "text"
|
|
197
|
-
|
|
198
|
-
start_time = Time.now
|
|
199
|
-
GenerateReport.run
|
|
200
|
-
elapsed = Time.now - start_time
|
|
201
|
-
|
|
202
|
-
puts "\nReport (text format):"
|
|
203
|
-
puts GenerateReport.formatted_output
|
|
204
|
-
puts "\nCompleted in #{elapsed.round(3)}s"
|
|
205
|
-
|
|
206
|
-
puts "\n" + "=" * 50
|
|
207
|
-
puts "\n3. Test Data with JSON Format"
|
|
208
|
-
puts "-" * 50
|
|
209
|
-
ENV["USE_TEST_DATA"] = "true"
|
|
210
|
-
ENV["REPORT_FORMAT"] = "json"
|
|
211
|
-
|
|
212
|
-
# Reset all tasks for fresh execution
|
|
213
|
-
[DataSourceSection, ReportFormatSection, EnrichWithSales,
|
|
214
|
-
EnrichWithActivities, BuildProfiles, GenerateReport].each(&:reset!)
|
|
215
|
-
|
|
216
|
-
start_time = Time.now
|
|
217
|
-
GenerateReport.run
|
|
218
|
-
elapsed = Time.now - start_time
|
|
219
|
-
|
|
220
|
-
puts "\nReport (JSON format):"
|
|
221
|
-
puts GenerateReport.formatted_output
|
|
222
|
-
puts "\nCompleted in #{elapsed.round(3)}s"
|
|
223
|
-
|
|
224
|
-
puts "\n" + "=" * 50
|
|
225
|
-
puts "Pipeline demonstration complete!"
|
|
226
|
-
puts "\nKey concepts demonstrated:"
|
|
227
|
-
puts " - DataSourceSection: Switch between production/test data"
|
|
228
|
-
puts " - ReportFormatSection: Switch output format (text/JSON)"
|
|
229
|
-
puts " - Parallel execution of independent transforms"
|
|
230
|
-
puts "\nTo disable progress display:"
|
|
231
|
-
puts " TASKI_PROGRESS_DISABLE=1 ruby examples/data_pipeline_demo.rb"
|