makit 0.0.112 → 0.0.126
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 +41 -41
- data/exe/makit +5 -5
- data/lib/makit/apache.rb +28 -28
- data/lib/makit/cli/build_commands.rb +500 -500
- data/lib/makit/cli/generators/base_generator.rb +74 -74
- data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
- data/lib/makit/cli/generators/generator_factory.rb +49 -49
- data/lib/makit/cli/generators/node_generator.rb +50 -50
- data/lib/makit/cli/generators/ruby_generator.rb +77 -77
- data/lib/makit/cli/generators/rust_generator.rb +50 -50
- data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
- data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
- data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
- data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -40
- data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
- data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
- data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
- data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
- data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
- data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
- data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
- data/lib/makit/cli/main.rb +62 -62
- data/lib/makit/cli/project_commands.rb +868 -868
- data/lib/makit/cli/repository_commands.rb +661 -661
- data/lib/makit/cli/utility_commands.rb +521 -521
- data/lib/makit/commands/factory.rb +359 -359
- data/lib/makit/commands/middleware/base.rb +73 -73
- data/lib/makit/commands/middleware/cache.rb +248 -248
- data/lib/makit/commands/middleware/command_logger.rb +311 -320
- data/lib/makit/commands/middleware/validator.rb +269 -269
- data/lib/makit/commands/request.rb +316 -254
- data/lib/makit/commands/result.rb +323 -323
- data/lib/makit/commands/runner.rb +368 -337
- data/lib/makit/commands/strategies/base.rb +171 -160
- data/lib/makit/commands/strategies/synchronous.rb +139 -134
- data/lib/makit/commands.rb +50 -51
- data/lib/makit/configuration/gitlab_helper.rb +58 -60
- data/lib/makit/configuration/project.rb +167 -127
- data/lib/makit/configuration/rakefile_helper.rb +43 -43
- data/lib/makit/configuration/step.rb +34 -34
- data/lib/makit/configuration.rb +14 -14
- data/lib/makit/content/default_gitignore.rb +7 -7
- data/lib/makit/content/default_gitignore.txt +226 -0
- data/lib/makit/content/default_rakefile.rb +13 -13
- data/lib/makit/content/gem_rakefile.rb +16 -16
- data/lib/makit/context.rb +1 -1
- data/lib/makit/data.rb +49 -49
- data/lib/makit/directories.rb +140 -141
- data/lib/makit/directory.rb +262 -262
- data/lib/makit/docs/files.rb +89 -89
- data/lib/makit/docs/rake.rb +102 -102
- data/lib/makit/dotnet/cli.rb +69 -65
- data/lib/makit/dotnet/project.rb +217 -153
- data/lib/makit/dotnet/solution.rb +38 -38
- data/lib/makit/dotnet/solution_classlib.rb +239 -239
- data/lib/makit/dotnet/solution_console.rb +264 -264
- data/lib/makit/dotnet/solution_maui.rb +354 -354
- data/lib/makit/dotnet/solution_wasm.rb +275 -275
- data/lib/makit/dotnet/solution_wpf.rb +304 -304
- data/lib/makit/dotnet.rb +102 -102
- data/lib/makit/email.rb +90 -90
- data/lib/makit/environment.rb +142 -142
- data/lib/makit/examples/runner.rb +370 -370
- data/lib/makit/exceptions.rb +45 -45
- data/lib/makit/fileinfo.rb +24 -24
- data/lib/makit/files.rb +43 -43
- data/lib/makit/gems.rb +40 -40
- data/lib/makit/git/cli.rb +54 -54
- data/lib/makit/git/repository.rb +90 -90
- data/lib/makit/git.rb +98 -98
- data/lib/makit/gitlab_runner.rb +59 -59
- data/lib/makit/humanize.rb +137 -137
- data/lib/makit/indexer.rb +47 -47
- data/lib/makit/logging/configuration.rb +308 -305
- data/lib/makit/logging/format_registry.rb +84 -84
- data/lib/makit/logging/formatters/base.rb +39 -39
- data/lib/makit/logging/formatters/console_formatter.rb +140 -140
- data/lib/makit/logging/formatters/json_formatter.rb +65 -65
- data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
- data/lib/makit/logging/formatters/text_formatter.rb +64 -64
- data/lib/makit/logging/log_request.rb +119 -115
- data/lib/makit/logging/logger.rb +199 -163
- data/lib/makit/logging/sinks/base.rb +91 -91
- data/lib/makit/logging/sinks/console.rb +72 -72
- data/lib/makit/logging/sinks/file_sink.rb +92 -92
- data/lib/makit/logging/sinks/structured.rb +123 -129
- data/lib/makit/logging/sinks/unified_file_sink.rb +296 -303
- data/lib/makit/logging.rb +565 -530
- data/lib/makit/markdown.rb +75 -75
- data/lib/makit/mp/basic_object_mp.rb +17 -17
- data/lib/makit/mp/command_mp.rb +13 -13
- data/lib/makit/mp/command_request.mp.rb +17 -17
- data/lib/makit/mp/project_mp.rb +199 -199
- data/lib/makit/mp/string_mp.rb +191 -193
- data/lib/makit/nuget.rb +74 -74
- data/lib/makit/port.rb +32 -32
- data/lib/makit/process.rb +163 -163
- data/lib/makit/protoc.rb +107 -107
- data/lib/makit/rake/cli.rb +196 -196
- data/lib/makit/rake.rb +25 -25
- data/lib/makit/ruby/cli.rb +185 -185
- data/lib/makit/ruby.rb +25 -25
- data/lib/makit/secrets.rb +51 -51
- data/lib/makit/serializer.rb +130 -130
- data/lib/makit/services/builder.rb +186 -186
- data/lib/makit/services/error_handler.rb +226 -226
- data/lib/makit/services/repository_manager.rb +231 -229
- data/lib/makit/services/validator.rb +112 -112
- data/lib/makit/setup/classlib.rb +90 -53
- data/lib/makit/setup/gem.rb +268 -263
- data/lib/makit/setup/razorclasslib.rb +91 -0
- data/lib/makit/setup/runner.rb +54 -45
- data/lib/makit/setup.rb +5 -5
- data/lib/makit/show.rb +110 -110
- data/lib/makit/storage.rb +126 -126
- data/lib/makit/symbols.rb +170 -170
- data/lib/makit/task_info.rb +128 -128
- data/lib/makit/tasks/at_exit.rb +15 -13
- data/lib/makit/tasks/build.rb +22 -19
- data/lib/makit/tasks/clean.rb +13 -11
- data/lib/makit/tasks/configure.rb +10 -0
- data/lib/makit/tasks/format.rb +10 -0
- data/lib/makit/tasks/hook_manager.rb +391 -393
- data/lib/makit/tasks/init.rb +49 -47
- data/lib/makit/tasks/integrate.rb +29 -17
- data/lib/makit/tasks/pull_incoming.rb +13 -11
- data/lib/makit/tasks/setup.rb +13 -6
- data/lib/makit/tasks/sync.rb +17 -12
- data/lib/makit/tasks/tag.rb +16 -15
- data/lib/makit/tasks/task_monkey_patch.rb +81 -79
- data/lib/makit/tasks/test.rb +22 -0
- data/lib/makit/tasks/update.rb +18 -0
- data/lib/makit/tasks.rb +20 -15
- data/lib/makit/test_cache.rb +239 -239
- data/lib/makit/tree.rb +37 -37
- data/lib/makit/v1/makit.v1_pb.rb +35 -34
- data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
- data/lib/makit/version.rb +5 -5
- data/lib/makit/version_util.rb +21 -21
- data/lib/makit/wix.rb +95 -95
- data/lib/makit/yaml.rb +29 -29
- data/lib/makit/zip.rb +17 -17
- data/lib/makit copy.rb +44 -44
- data/lib/makit.rb +39 -40
- metadata +69 -7
- data/lib/makit/commands/middleware/unified_logger.rb +0 -243
@@ -1,393 +1,391 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "set"
|
4
|
-
require "colorize"
|
5
|
-
require "fileutils"
|
6
|
-
|
7
|
-
# Task hooks system for Makit
|
8
|
-
#
|
9
|
-
# This module provides a comprehensive hook system for Rake tasks, allowing
|
10
|
-
# developers to add pre and post execution hooks globally or for specific tasks.
|
11
|
-
# It uses monkey patching to intercept all task invocations and execute hooks
|
12
|
-
# at the appropriate times.
|
13
|
-
#
|
14
|
-
# @example Global hooks
|
15
|
-
# Makit::Tasks::HookManager.add_pre_hook do |task_name|
|
16
|
-
# Makit::Logging.info("Starting task: #{task_name}")
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# Makit::Tasks::HookManager.add_post_hook do |task_name, duration, result, error|
|
20
|
-
# if error
|
21
|
-
# Makit::Logging.error("Task failed: #{task_name}")
|
22
|
-
# else
|
23
|
-
# Makit::Logging.success("Task completed: #{task_name}")
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# @example Task-specific hooks
|
28
|
-
# Makit::Tasks::HookManager.add_pre_hook_for(:build) do |task_name|
|
29
|
-
# Makit::Logging.info("Building project...")
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# Makit::Tasks::HookManager.add_post_hook_for(:test) do |task_name, duration, result, error|
|
33
|
-
# Makit::Logging.info("Test execution took #{duration.round(2)}s")
|
34
|
-
# end
|
35
|
-
module Makit
|
36
|
-
module Tasks
|
37
|
-
class HookManager
|
38
|
-
@pre_hooks = []
|
39
|
-
@post_hooks = []
|
40
|
-
@task_specific_pre_hooks = {}
|
41
|
-
@task_specific_post_hooks = {}
|
42
|
-
@excluded_tasks = Set.new
|
43
|
-
@logged_tasks = Set.new
|
44
|
-
|
45
|
-
# Timing functionality
|
46
|
-
@timing_enabled = false
|
47
|
-
@task_stack = []
|
48
|
-
@performance_log = "artifacts/task_performance.log"
|
49
|
-
@hooks_installed = false
|
50
|
-
|
51
|
-
class << self
|
52
|
-
# @return [Array<Proc>] Global pre-task hooks
|
53
|
-
attr_reader :pre_hooks
|
54
|
-
|
55
|
-
# @return [Array<Proc>] Global post-task hooks
|
56
|
-
attr_reader :post_hooks
|
57
|
-
|
58
|
-
# @return [Hash<String, Array<Proc>>] Task-specific pre-task hooks
|
59
|
-
attr_reader :task_specific_pre_hooks
|
60
|
-
|
61
|
-
# @return [Hash<String, Array<Proc>>] Task-specific post-task hooks
|
62
|
-
attr_reader :task_specific_post_hooks
|
63
|
-
|
64
|
-
# @return [Set<String>] Tasks excluded from hook execution
|
65
|
-
attr_reader :excluded_tasks
|
66
|
-
|
67
|
-
# @return [Boolean] Whether timing is enabled
|
68
|
-
attr_reader :timing_enabled
|
69
|
-
|
70
|
-
# @return [Array<Hash>] Stack of currently executing tasks
|
71
|
-
attr_reader :task_stack
|
72
|
-
|
73
|
-
# @return [String] Path to performance log file
|
74
|
-
attr_reader :performance_log
|
75
|
-
|
76
|
-
# Add a global pre-task hook
|
77
|
-
#
|
78
|
-
# The hook will be executed before every task runs.
|
79
|
-
#
|
80
|
-
# @yield [task_name] the name of the task being executed
|
81
|
-
# @yieldparam task_name [String] the name of the task
|
82
|
-
# @return [void]
|
83
|
-
def add_pre_hook(&block)
|
84
|
-
@pre_hooks << block
|
85
|
-
end
|
86
|
-
|
87
|
-
# Add a global post-task hook
|
88
|
-
#
|
89
|
-
# The hook will be executed after every task completes (success or failure).
|
90
|
-
#
|
91
|
-
# @yield [task_name, duration, result, error] hook parameters
|
92
|
-
# @yieldparam task_name [String] the name of the task
|
93
|
-
# @yieldparam duration [Float] execution duration in seconds
|
94
|
-
# @yieldparam result [Object, nil] the result of the task execution
|
95
|
-
# @yieldparam error [Exception, nil] any error that occurred during execution
|
96
|
-
# @return [void]
|
97
|
-
def add_post_hook(&block)
|
98
|
-
@post_hooks << block
|
99
|
-
end
|
100
|
-
|
101
|
-
# Add a pre-task hook for a specific task
|
102
|
-
#
|
103
|
-
# The hook will only be executed before the specified task runs.
|
104
|
-
#
|
105
|
-
# @param task_name [String, Symbol] the name of the task
|
106
|
-
# @yield [task_name] the name of the task being executed
|
107
|
-
# @yieldparam task_name [String] the name of the task
|
108
|
-
# @return [void]
|
109
|
-
def add_pre_hook_for(task_name, &block)
|
110
|
-
@task_specific_pre_hooks[task_name.to_s] ||= []
|
111
|
-
@task_specific_pre_hooks[task_name.to_s] << block
|
112
|
-
end
|
113
|
-
|
114
|
-
# Add a post-task hook for a specific task
|
115
|
-
#
|
116
|
-
# The hook will only be executed after the specified task completes.
|
117
|
-
#
|
118
|
-
# @param task_name [String, Symbol] the name of the task
|
119
|
-
# @yield [task_name, duration, result, error] hook parameters
|
120
|
-
# @yieldparam task_name [String] the name of the task
|
121
|
-
# @yieldparam duration [Float] execution duration in seconds
|
122
|
-
# @yieldparam result [Object, nil] the result of the task execution
|
123
|
-
# @yieldparam error [Exception, nil] any error that occurred during execution
|
124
|
-
# @return [void]
|
125
|
-
def add_post_hook_for(task_name, &block)
|
126
|
-
@task_specific_post_hooks[task_name.to_s] ||= []
|
127
|
-
@task_specific_post_hooks[task_name.to_s] << block
|
128
|
-
end
|
129
|
-
|
130
|
-
# Execute all pre-task hooks for a given task
|
131
|
-
#
|
132
|
-
# @param task_name [String] the name of the task
|
133
|
-
# @return [void]
|
134
|
-
def execute_pre_hooks(task_name)
|
135
|
-
return if excluded?(task_name)
|
136
|
-
|
137
|
-
# Track timing if enabled
|
138
|
-
if timing_enabled?
|
139
|
-
@task_stack.push({
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
# Execute global pre-hooks
|
147
|
-
@pre_hooks.each { |hook| hook.call(task_name) }
|
148
|
-
|
149
|
-
# Execute task-specific pre-hooks
|
150
|
-
task_hooks = @task_specific_pre_hooks[task_name.to_s] || []
|
151
|
-
task_hooks.each { |hook| hook.call(task_name) }
|
152
|
-
end
|
153
|
-
|
154
|
-
# Execute all post-task hooks for a given task
|
155
|
-
#
|
156
|
-
# @param task_name [String] the name of the task
|
157
|
-
# @param duration [Float] execution duration in seconds
|
158
|
-
# @param result [Object, nil] the result of the task execution
|
159
|
-
# @param error [Exception, nil] any error that occurred during execution
|
160
|
-
# @return [void]
|
161
|
-
def execute_post_hooks(task_name, duration, result, error)
|
162
|
-
return if excluded?(task_name)
|
163
|
-
|
164
|
-
# Handle timing if enabled
|
165
|
-
if timing_enabled?
|
166
|
-
task_info = @task_stack.pop
|
167
|
-
if task_info && task_info[:name] == task_name
|
168
|
-
# Log performance for tasks that took longer than 0.1 seconds
|
169
|
-
log_task_performance(task_name, duration, task_info[:level])
|
170
|
-
end
|
171
|
-
|
172
|
-
# Log task failure if there was an error
|
173
|
-
if error
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
#
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
@
|
191
|
-
@
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
#
|
197
|
-
#
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
#
|
205
|
-
#
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
#
|
213
|
-
#
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
#
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
#
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
#
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
#
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
#
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
#
|
267
|
-
#
|
268
|
-
#
|
269
|
-
#
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
setup
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
#
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
#Makit::Logging.info("#{
|
343
|
-
#Makit::Logging.info("
|
344
|
-
#Makit::Logging.info("
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
#
|
352
|
-
#
|
353
|
-
# @param
|
354
|
-
# @
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
#
|
369
|
-
#
|
370
|
-
# @param
|
371
|
-
# @param
|
372
|
-
# @
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
timestamp
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
# Setup default hooks when the module is loaded
|
393
|
-
Makit::Tasks::HookManager.setup_default_hooks
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "colorize"
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
# Task hooks system for Makit
|
8
|
+
#
|
9
|
+
# This module provides a comprehensive hook system for Rake tasks, allowing
|
10
|
+
# developers to add pre and post execution hooks globally or for specific tasks.
|
11
|
+
# It uses monkey patching to intercept all task invocations and execute hooks
|
12
|
+
# at the appropriate times.
|
13
|
+
#
|
14
|
+
# @example Global hooks
|
15
|
+
# Makit::Tasks::HookManager.add_pre_hook do |task_name|
|
16
|
+
# Makit::Logging.info("Starting task: #{task_name}")
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Makit::Tasks::HookManager.add_post_hook do |task_name, duration, result, error|
|
20
|
+
# if error
|
21
|
+
# Makit::Logging.error("Task failed: #{task_name}")
|
22
|
+
# else
|
23
|
+
# Makit::Logging.success("Task completed: #{task_name}")
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# @example Task-specific hooks
|
28
|
+
# Makit::Tasks::HookManager.add_pre_hook_for(:build) do |task_name|
|
29
|
+
# Makit::Logging.info("Building project...")
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Makit::Tasks::HookManager.add_post_hook_for(:test) do |task_name, duration, result, error|
|
33
|
+
# Makit::Logging.info("Test execution took #{duration.round(2)}s")
|
34
|
+
# end
|
35
|
+
module Makit
|
36
|
+
module Tasks
|
37
|
+
class HookManager
|
38
|
+
@pre_hooks = []
|
39
|
+
@post_hooks = []
|
40
|
+
@task_specific_pre_hooks = {}
|
41
|
+
@task_specific_post_hooks = {}
|
42
|
+
@excluded_tasks = Set.new
|
43
|
+
@logged_tasks = Set.new
|
44
|
+
|
45
|
+
# Timing functionality
|
46
|
+
@timing_enabled = false
|
47
|
+
@task_stack = []
|
48
|
+
@performance_log = "artifacts/task_performance.log"
|
49
|
+
@hooks_installed = false
|
50
|
+
|
51
|
+
class << self
|
52
|
+
# @return [Array<Proc>] Global pre-task hooks
|
53
|
+
attr_reader :pre_hooks
|
54
|
+
|
55
|
+
# @return [Array<Proc>] Global post-task hooks
|
56
|
+
attr_reader :post_hooks
|
57
|
+
|
58
|
+
# @return [Hash<String, Array<Proc>>] Task-specific pre-task hooks
|
59
|
+
attr_reader :task_specific_pre_hooks
|
60
|
+
|
61
|
+
# @return [Hash<String, Array<Proc>>] Task-specific post-task hooks
|
62
|
+
attr_reader :task_specific_post_hooks
|
63
|
+
|
64
|
+
# @return [Set<String>] Tasks excluded from hook execution
|
65
|
+
attr_reader :excluded_tasks
|
66
|
+
|
67
|
+
# @return [Boolean] Whether timing is enabled
|
68
|
+
attr_reader :timing_enabled
|
69
|
+
|
70
|
+
# @return [Array<Hash>] Stack of currently executing tasks
|
71
|
+
attr_reader :task_stack
|
72
|
+
|
73
|
+
# @return [String] Path to performance log file
|
74
|
+
attr_reader :performance_log
|
75
|
+
|
76
|
+
# Add a global pre-task hook
|
77
|
+
#
|
78
|
+
# The hook will be executed before every task runs.
|
79
|
+
#
|
80
|
+
# @yield [task_name] the name of the task being executed
|
81
|
+
# @yieldparam task_name [String] the name of the task
|
82
|
+
# @return [void]
|
83
|
+
def add_pre_hook(&block)
|
84
|
+
@pre_hooks << block
|
85
|
+
end
|
86
|
+
|
87
|
+
# Add a global post-task hook
|
88
|
+
#
|
89
|
+
# The hook will be executed after every task completes (success or failure).
|
90
|
+
#
|
91
|
+
# @yield [task_name, duration, result, error] hook parameters
|
92
|
+
# @yieldparam task_name [String] the name of the task
|
93
|
+
# @yieldparam duration [Float] execution duration in seconds
|
94
|
+
# @yieldparam result [Object, nil] the result of the task execution
|
95
|
+
# @yieldparam error [Exception, nil] any error that occurred during execution
|
96
|
+
# @return [void]
|
97
|
+
def add_post_hook(&block)
|
98
|
+
@post_hooks << block
|
99
|
+
end
|
100
|
+
|
101
|
+
# Add a pre-task hook for a specific task
|
102
|
+
#
|
103
|
+
# The hook will only be executed before the specified task runs.
|
104
|
+
#
|
105
|
+
# @param task_name [String, Symbol] the name of the task
|
106
|
+
# @yield [task_name] the name of the task being executed
|
107
|
+
# @yieldparam task_name [String] the name of the task
|
108
|
+
# @return [void]
|
109
|
+
def add_pre_hook_for(task_name, &block)
|
110
|
+
@task_specific_pre_hooks[task_name.to_s] ||= []
|
111
|
+
@task_specific_pre_hooks[task_name.to_s] << block
|
112
|
+
end
|
113
|
+
|
114
|
+
# Add a post-task hook for a specific task
|
115
|
+
#
|
116
|
+
# The hook will only be executed after the specified task completes.
|
117
|
+
#
|
118
|
+
# @param task_name [String, Symbol] the name of the task
|
119
|
+
# @yield [task_name, duration, result, error] hook parameters
|
120
|
+
# @yieldparam task_name [String] the name of the task
|
121
|
+
# @yieldparam duration [Float] execution duration in seconds
|
122
|
+
# @yieldparam result [Object, nil] the result of the task execution
|
123
|
+
# @yieldparam error [Exception, nil] any error that occurred during execution
|
124
|
+
# @return [void]
|
125
|
+
def add_post_hook_for(task_name, &block)
|
126
|
+
@task_specific_post_hooks[task_name.to_s] ||= []
|
127
|
+
@task_specific_post_hooks[task_name.to_s] << block
|
128
|
+
end
|
129
|
+
|
130
|
+
# Execute all pre-task hooks for a given task
|
131
|
+
#
|
132
|
+
# @param task_name [String] the name of the task
|
133
|
+
# @return [void]
|
134
|
+
def execute_pre_hooks(task_name)
|
135
|
+
return if excluded?(task_name)
|
136
|
+
|
137
|
+
# Track timing if enabled
|
138
|
+
if timing_enabled?
|
139
|
+
@task_stack.push({
|
140
|
+
name: task_name,
|
141
|
+
start_time: Time.now,
|
142
|
+
level: @task_stack.length,
|
143
|
+
})
|
144
|
+
end
|
145
|
+
|
146
|
+
# Execute global pre-hooks
|
147
|
+
@pre_hooks.each { |hook| hook.call(task_name) }
|
148
|
+
|
149
|
+
# Execute task-specific pre-hooks
|
150
|
+
task_hooks = @task_specific_pre_hooks[task_name.to_s] || []
|
151
|
+
task_hooks.each { |hook| hook.call(task_name) }
|
152
|
+
end
|
153
|
+
|
154
|
+
# Execute all post-task hooks for a given task
|
155
|
+
#
|
156
|
+
# @param task_name [String] the name of the task
|
157
|
+
# @param duration [Float] execution duration in seconds
|
158
|
+
# @param result [Object, nil] the result of the task execution
|
159
|
+
# @param error [Exception, nil] any error that occurred during execution
|
160
|
+
# @return [void]
|
161
|
+
def execute_post_hooks(task_name, duration, result, error)
|
162
|
+
return if excluded?(task_name)
|
163
|
+
|
164
|
+
# Handle timing if enabled
|
165
|
+
if timing_enabled?
|
166
|
+
task_info = @task_stack.pop
|
167
|
+
if task_info && task_info[:name] == task_name && (duration > 0.1)
|
168
|
+
# Log performance for tasks that took longer than 0.1 seconds
|
169
|
+
log_task_performance(task_name, duration, task_info[:level])
|
170
|
+
end
|
171
|
+
|
172
|
+
# Log task failure if there was an error
|
173
|
+
log_task_failure(task_name, duration, error, task_info&.dig(:level) || 0) if error
|
174
|
+
end
|
175
|
+
|
176
|
+
# Execute global post-hooks
|
177
|
+
@post_hooks.each { |hook| hook.call(task_name, duration, result, error) }
|
178
|
+
|
179
|
+
# Execute task-specific post-hooks
|
180
|
+
task_hooks = @task_specific_post_hooks[task_name.to_s] || []
|
181
|
+
task_hooks.each { |hook| hook.call(task_name, duration, result, error) }
|
182
|
+
end
|
183
|
+
|
184
|
+
# Clear all hooks
|
185
|
+
#
|
186
|
+
# @return [void]
|
187
|
+
def clear_all_hooks
|
188
|
+
@pre_hooks.clear
|
189
|
+
@post_hooks.clear
|
190
|
+
@task_specific_pre_hooks.clear
|
191
|
+
@task_specific_post_hooks.clear
|
192
|
+
end
|
193
|
+
|
194
|
+
# Exclude a task from hook execution
|
195
|
+
#
|
196
|
+
# @param task_name [String, Symbol] the name of the task to exclude
|
197
|
+
# @return [void]
|
198
|
+
def exclude_task(task_name)
|
199
|
+
@excluded_tasks.add(task_name.to_s)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Include a task in hook execution (remove from exclusions)
|
203
|
+
#
|
204
|
+
# @param task_name [String, Symbol] the name of the task to include
|
205
|
+
# @return [void]
|
206
|
+
def include_task(task_name)
|
207
|
+
@excluded_tasks.delete(task_name.to_s)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Check if a task is excluded from hook execution
|
211
|
+
#
|
212
|
+
# @param task_name [String, Symbol] the name of the task to check
|
213
|
+
# @return [Boolean] true if the task is excluded
|
214
|
+
def excluded?(task_name)
|
215
|
+
@excluded_tasks.include?(task_name.to_s)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Get statistics about registered hooks
|
219
|
+
#
|
220
|
+
# @return [Hash] hook statistics
|
221
|
+
def stats
|
222
|
+
{
|
223
|
+
global_pre_hooks: @pre_hooks.size,
|
224
|
+
global_post_hooks: @post_hooks.size,
|
225
|
+
task_specific_pre_hooks: @task_specific_pre_hooks.values.flatten.size,
|
226
|
+
task_specific_post_hooks: @task_specific_post_hooks.values.flatten.size,
|
227
|
+
tasks_with_pre_hooks: @task_specific_pre_hooks.keys,
|
228
|
+
tasks_with_post_hooks: @task_specific_post_hooks.keys,
|
229
|
+
timing_enabled: @timing_enabled,
|
230
|
+
task_stack_depth: @task_stack.size,
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
# Enable task timing and performance logging
|
235
|
+
#
|
236
|
+
# @return [void]
|
237
|
+
def enable_timing!
|
238
|
+
@timing_enabled = true
|
239
|
+
puts "🔧 Task timing enabled".colorize(:grey) if defined?(String.instance_method(:colorize))
|
240
|
+
end
|
241
|
+
|
242
|
+
# Disable task timing and performance logging
|
243
|
+
#
|
244
|
+
# @return [void]
|
245
|
+
def disable_timing!
|
246
|
+
@timing_enabled = false
|
247
|
+
end
|
248
|
+
|
249
|
+
# Check if timing is enabled
|
250
|
+
#
|
251
|
+
# @return [Boolean] true if timing is enabled
|
252
|
+
def timing_enabled?
|
253
|
+
@timing_enabled == true
|
254
|
+
end
|
255
|
+
|
256
|
+
# Clear performance logs
|
257
|
+
#
|
258
|
+
# @return [void]
|
259
|
+
def clear_performance_logs
|
260
|
+
FileUtils.rm_f(@performance_log)
|
261
|
+
FileUtils.rm_f("artifacts/task_failures.log")
|
262
|
+
end
|
263
|
+
|
264
|
+
# Setup task hooks by monkey patching Rake::Task
|
265
|
+
#
|
266
|
+
# This method patches the Rake::Task#execute method to automatically
|
267
|
+
# call pre and post hooks for all task executions.
|
268
|
+
#
|
269
|
+
# @return [void]
|
270
|
+
def setup!
|
271
|
+
return if @hooks_installed
|
272
|
+
|
273
|
+
Rake::Task.class_eval do
|
274
|
+
alias_method :makit_original_execute, :execute
|
275
|
+
|
276
|
+
def execute(args = nil)
|
277
|
+
start_time = Time.now
|
278
|
+
error = nil
|
279
|
+
result = nil
|
280
|
+
|
281
|
+
begin
|
282
|
+
# Execute pre-hooks
|
283
|
+
Makit::Tasks::HookManager.execute_pre_hooks(name)
|
284
|
+
|
285
|
+
# Execute the original task
|
286
|
+
result = makit_original_execute(args)
|
287
|
+
rescue StandardError => e
|
288
|
+
error = e
|
289
|
+
raise
|
290
|
+
ensure
|
291
|
+
# Calculate duration
|
292
|
+
duration = Time.now - start_time
|
293
|
+
|
294
|
+
# Execute post-hooks
|
295
|
+
Makit::Tasks::HookManager.execute_post_hooks(name, duration, result, error)
|
296
|
+
end
|
297
|
+
|
298
|
+
result
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
@hooks_installed = true
|
303
|
+
end
|
304
|
+
|
305
|
+
# Setup default task hooks
|
306
|
+
#
|
307
|
+
# This method sets up the default task hooks that provide basic
|
308
|
+
# task execution feedback. It should be called during initialization.
|
309
|
+
#
|
310
|
+
# @return [void]
|
311
|
+
def setup_default_hooks
|
312
|
+
# Setup the monkey patching first
|
313
|
+
setup!
|
314
|
+
|
315
|
+
# Only setup default hooks if no hooks are already registered
|
316
|
+
return unless @pre_hooks.empty? && @post_hooks.empty?
|
317
|
+
|
318
|
+
# Exclude the init task from hooks to prevent duplication
|
319
|
+
exclude_task(:init)
|
320
|
+
exclude_task(:default)
|
321
|
+
|
322
|
+
# Default pre-task hook: log task start to default logger
|
323
|
+
add_pre_hook do |task_name|
|
324
|
+
log_task_start(task_name)
|
325
|
+
end
|
326
|
+
|
327
|
+
# Default post-task hook: log task completion
|
328
|
+
add_post_hook do |task_name, duration, result, error|
|
329
|
+
log_task_completion(task_name, duration, result, error)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def log_task_start(task_name)
|
334
|
+
# return if @logged_tasks.include?(task_name)
|
335
|
+
# @logged_tasks.add(task_name)
|
336
|
+
# Makit::Logging.info("#{task_name}".colorize(:white).bold)
|
337
|
+
end
|
338
|
+
|
339
|
+
def log_task_completion(task_name, duration, result, error)
|
340
|
+
# Makit::Logging.info("#{task_name}".colorize(:white).bold)
|
341
|
+
# Makit::Logging.info("Task completed".colorize(:green).bold)
|
342
|
+
# Makit::Logging.info("Duration: #{duration.round(2)}s".colorize(:green).bold)
|
343
|
+
# Makit::Logging.info("Result: #{result}".colorize(:green).bold)
|
344
|
+
# Makit::Logging.info("Error: #{error}".colorize(:red).bold)
|
345
|
+
end
|
346
|
+
|
347
|
+
private
|
348
|
+
|
349
|
+
# Log task performance to file
|
350
|
+
#
|
351
|
+
# @param name [String] task name
|
352
|
+
# @param duration [Float] execution duration
|
353
|
+
# @param level [Integer] nesting level
|
354
|
+
# @return [void]
|
355
|
+
def log_task_performance(name, duration, level)
|
356
|
+
return if ENV["CI"] == "true" && duration < 1.0
|
357
|
+
|
358
|
+
FileUtils.mkdir_p("artifacts")
|
359
|
+
File.open(@performance_log, "a") do |f|
|
360
|
+
f.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")},#{name},#{duration.round(4)},#{level}"
|
361
|
+
end
|
362
|
+
rescue StandardError
|
363
|
+
# Silently fail performance logging to not interrupt tasks
|
364
|
+
end
|
365
|
+
|
366
|
+
# Log task failure to file
|
367
|
+
#
|
368
|
+
# @param name [String] task name
|
369
|
+
# @param duration [Float] execution duration
|
370
|
+
# @param error [Exception] the error that occurred
|
371
|
+
# @param level [Integer] nesting level
|
372
|
+
# @return [void]
|
373
|
+
def log_task_failure(name, duration, error, _level)
|
374
|
+
failure_log = "artifacts/task_failures.log"
|
375
|
+
FileUtils.mkdir_p("artifacts")
|
376
|
+
|
377
|
+
File.open(failure_log, "a") do |f|
|
378
|
+
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
379
|
+
message = error.message.gsub(",", ";")
|
380
|
+
f.puts "#{timestamp},#{name},#{duration.round(4)},#{error.class.name},#{message}"
|
381
|
+
end
|
382
|
+
rescue StandardError
|
383
|
+
# Silently fail error logging
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
# Setup default hooks when the module is loaded
|
391
|
+
Makit::Tasks::HookManager.setup_default_hooks
|