makit 0.0.111 → 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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/lib/makit/cli/repository_commands.rb +1 -1
  3. data/lib/makit/commands/middleware/cache.rb +3 -3
  4. data/lib/makit/commands/middleware/command_logger.rb +33 -45
  5. data/lib/makit/commands/request.rb +63 -1
  6. data/lib/makit/commands/runner.rb +56 -5
  7. data/lib/makit/commands/strategies/base.rb +13 -2
  8. data/lib/makit/commands/strategies/synchronous.rb +11 -6
  9. data/lib/makit/commands.rb +8 -0
  10. data/lib/makit/configuration/gitlab_helper.rb +0 -2
  11. data/lib/makit/configuration/project.rb +48 -8
  12. data/lib/makit/configuration/step.rb +3 -3
  13. data/lib/makit/content/default_gitignore.txt +226 -0
  14. data/lib/makit/directories.rb +3 -4
  15. data/lib/makit/docs/files.rb +1 -1
  16. data/lib/makit/docs/rake.rb +1 -1
  17. data/lib/makit/dotnet/cli.rb +69 -65
  18. data/lib/makit/dotnet/project.rb +71 -7
  19. data/lib/makit/examples/runner.rb +2 -2
  20. data/lib/makit/logging/configuration.rb +9 -6
  21. data/lib/makit/logging/format_registry.rb +84 -84
  22. data/lib/makit/logging/formatters/console_formatter.rb +22 -9
  23. data/lib/makit/logging/log_request.rb +6 -2
  24. data/lib/makit/logging/logger.rb +45 -5
  25. data/lib/makit/logging/sinks/base.rb +91 -91
  26. data/lib/makit/logging/sinks/structured.rb +123 -129
  27. data/lib/makit/logging/sinks/unified_file_sink.rb +39 -46
  28. data/lib/makit/logging.rb +45 -1
  29. data/lib/makit/mp/project_mp.rb +6 -6
  30. data/lib/makit/mp/string_mp.rb +108 -265
  31. data/lib/makit/serializer.rb +14 -1
  32. data/lib/makit/services/builder.rb +5 -5
  33. data/lib/makit/services/repository_manager.rb +8 -6
  34. data/lib/makit/setup/classlib.rb +44 -7
  35. data/lib/makit/setup/gem.rb +268 -250
  36. data/lib/makit/setup/razorclasslib.rb +91 -0
  37. data/lib/makit/setup/runner.rb +36 -22
  38. data/lib/makit/setup.rb +5 -0
  39. data/lib/makit/symbols.rb +10 -1
  40. data/lib/makit/tasks/at_exit.rb +3 -1
  41. data/lib/makit/tasks/build.rb +16 -12
  42. data/lib/makit/tasks/clean.rb +2 -0
  43. data/lib/makit/tasks/configure.rb +10 -0
  44. data/lib/makit/tasks/format.rb +10 -0
  45. data/lib/makit/tasks/hook_manager.rb +160 -8
  46. data/lib/makit/tasks/init.rb +2 -0
  47. data/lib/makit/tasks/integrate.rb +17 -3
  48. data/lib/makit/tasks/pull_incoming.rb +6 -5
  49. data/lib/makit/tasks/setup.rb +10 -3
  50. data/lib/makit/tasks/sync.rb +13 -7
  51. data/lib/makit/tasks/tag.rb +16 -0
  52. data/lib/makit/tasks/task_monkey_patch.rb +58 -56
  53. data/lib/makit/tasks/test.rb +22 -0
  54. data/lib/makit/tasks/update.rb +18 -0
  55. data/lib/makit/tasks.rb +20 -5
  56. data/lib/makit/v1/makit.v1_pb.rb +1 -0
  57. data/lib/makit/version.rb +1 -1
  58. data/lib/makit/version_util.rb +21 -0
  59. data/lib/makit copy.rb +44 -0
  60. data/lib/makit.rb +31 -0
  61. metadata +118 -13
  62. data/lib/makit/command_runner.rb +0 -463
  63. data/lib/makit/commands/compatibility.rb +0 -365
  64. data/lib/makit/commands/middleware/unified_logger.rb +0 -243
  65. data/lib/makit/task_hooks.rb +0 -125
@@ -1,129 +1,123 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base"
4
-
5
- module Makit
6
- module Logging
7
- module Sinks
8
- # Structured sink for adding metadata to log requests
9
- #
10
- # This sink enriches log requests with structured metadata like
11
- # process information, thread details, and other contextual data that
12
- # can be useful for debugging and monitoring. It follows the same
13
- # pattern as other sinks but focuses on data enrichment rather than output.
14
- #
15
- # @example Basic usage
16
- # structured_sink = Structured.new
17
- # logger = Logger.new(sinks: [structured_sink])
18
- # logger.info("Processing started")
19
- # # Adds metadata like process_id, thread_id, etc.
20
- #
21
- # @example With custom metadata
22
- # structured_sink = Structured.new(
23
- # custom_metadata: { environment: "production" }
24
- # )
25
- class Structured < Base
26
- # Initialize structured sink
27
- #
28
- # @param include_process_info [Boolean] whether to include process information
29
- # @param include_thread_info [Boolean] whether to include thread information
30
- # @param include_timing [Boolean] whether to include timing information
31
- # @param custom_metadata [Hash] custom metadata to add to all log requests
32
- def initialize(include_process_info: true, include_thread_info: true, include_timing: true, custom_metadata: {})
33
- @include_process_info = include_process_info
34
- @include_thread_info = include_thread_info
35
- @include_timing = include_timing
36
- @custom_metadata = custom_metadata.dup
37
- end
38
-
39
- # Execute sink logic to add structured metadata
40
- #
41
- # @param log_request [LogRequest] the log request to process
42
- # @yield [LogRequest] yields the processed log request to the next sink
43
- # @yieldreturn [LogRequest] the processed log request
44
- # @return [LogRequest] the final processed log request
45
- def call(log_request, &block)
46
- add_structured_metadata(log_request)
47
- block&.call(log_request) if block_given?
48
- log_request
49
- end
50
-
51
- # Get sink configuration
52
- #
53
- # @return [Hash] sink configuration
54
- def config
55
- {
56
- name: self.class.name.split("::").last,
57
- include_process_info: @include_process_info,
58
- include_thread_info: @include_thread_info,
59
- include_timing: @include_timing,
60
- custom_metadata: @custom_metadata,
61
- }
62
- end
63
-
64
- private
65
-
66
- # Add structured metadata to the log request
67
- #
68
- # @param log_request [LogRequest] the log request to enrich
69
- def add_structured_metadata(log_request)
70
- metadata = {}
71
-
72
- # Add process information
73
- if @include_process_info
74
- metadata.merge!(get_process_metadata)
75
- end
76
-
77
- # Add thread information
78
- if @include_thread_info
79
- metadata.merge!(get_thread_metadata)
80
- end
81
-
82
- # Add timing information
83
- if @include_timing
84
- metadata.merge!(get_timing_metadata)
85
- end
86
-
87
- # Add custom metadata
88
- metadata.merge!(@custom_metadata)
89
-
90
- # Add to log request
91
- log_request.add_metadata(metadata)
92
- end
93
-
94
- # Get process-related metadata
95
- #
96
- # @return [Hash] process metadata
97
- def get_process_metadata
98
- {
99
- process_id: ::Process.pid,
100
- process_title: $0,
101
- ruby_version: RUBY_VERSION,
102
- ruby_platform: RUBY_PLATFORM,
103
- }
104
- end
105
-
106
- # Get thread-related metadata
107
- #
108
- # @return [Hash] thread metadata
109
- def get_thread_metadata
110
- {
111
- thread_id: Thread.current.object_id,
112
- thread_name: Thread.current.name || "main",
113
- }
114
- end
115
-
116
- # Get timing-related metadata
117
- #
118
- # @return [Hash] timing metadata
119
- def get_timing_metadata
120
- {
121
- timestamp: Time.now.iso8601,
122
- unix_timestamp: Time.now.to_i,
123
- timezone: Time.now.zone,
124
- }
125
- end
126
- end
127
- end
128
- end
129
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Makit
6
+ module Logging
7
+ module Sinks
8
+ # Structured sink for adding metadata to log requests
9
+ #
10
+ # This sink enriches log requests with structured metadata like
11
+ # process information, thread details, and other contextual data that
12
+ # can be useful for debugging and monitoring. It follows the same
13
+ # pattern as other sinks but focuses on data enrichment rather than output.
14
+ #
15
+ # @example Basic usage
16
+ # structured_sink = Structured.new
17
+ # logger = Logger.new(sinks: [structured_sink])
18
+ # logger.info("Processing started")
19
+ # # Adds metadata like process_id, thread_id, etc.
20
+ #
21
+ # @example With custom metadata
22
+ # structured_sink = Structured.new(
23
+ # custom_metadata: { environment: "production" }
24
+ # )
25
+ class Structured < Base
26
+ # Initialize structured sink
27
+ #
28
+ # @param include_process_info [Boolean] whether to include process information
29
+ # @param include_thread_info [Boolean] whether to include thread information
30
+ # @param include_timing [Boolean] whether to include timing information
31
+ # @param custom_metadata [Hash] custom metadata to add to all log requests
32
+ def initialize(include_process_info: true, include_thread_info: true, include_timing: true, custom_metadata: {})
33
+ @include_process_info = include_process_info
34
+ @include_thread_info = include_thread_info
35
+ @include_timing = include_timing
36
+ @custom_metadata = custom_metadata.dup
37
+ end
38
+
39
+ # Execute sink logic to add structured metadata
40
+ #
41
+ # @param log_request [LogRequest] the log request to process
42
+ # @yield [LogRequest] yields the processed log request to the next sink
43
+ # @yieldreturn [LogRequest] the processed log request
44
+ # @return [LogRequest] the final processed log request
45
+ def call(log_request, &block)
46
+ add_structured_metadata(log_request)
47
+ block&.call(log_request) if block_given?
48
+ log_request
49
+ end
50
+
51
+ # Get sink configuration
52
+ #
53
+ # @return [Hash] sink configuration
54
+ def config
55
+ {
56
+ name: self.class.name.split("::").last,
57
+ include_process_info: @include_process_info,
58
+ include_thread_info: @include_thread_info,
59
+ include_timing: @include_timing,
60
+ custom_metadata: @custom_metadata,
61
+ }
62
+ end
63
+
64
+ private
65
+
66
+ # Add structured metadata to the log request
67
+ #
68
+ # @param log_request [LogRequest] the log request to enrich
69
+ def add_structured_metadata(log_request)
70
+ metadata = {}
71
+
72
+ # Add process information
73
+ metadata.merge!(get_process_metadata) if @include_process_info
74
+
75
+ # Add thread information
76
+ metadata.merge!(get_thread_metadata) if @include_thread_info
77
+
78
+ # Add timing information
79
+ metadata.merge!(get_timing_metadata) if @include_timing
80
+
81
+ # Add custom metadata
82
+ metadata.merge!(@custom_metadata)
83
+
84
+ # Add to log request
85
+ log_request.add_metadata(metadata)
86
+ end
87
+
88
+ # Get process-related metadata
89
+ #
90
+ # @return [Hash] process metadata
91
+ def get_process_metadata
92
+ {
93
+ process_id: ::Process.pid,
94
+ process_title: $PROGRAM_NAME,
95
+ ruby_version: RUBY_VERSION,
96
+ ruby_platform: RUBY_PLATFORM,
97
+ }
98
+ end
99
+
100
+ # Get thread-related metadata
101
+ #
102
+ # @return [Hash] thread metadata
103
+ def get_thread_metadata
104
+ {
105
+ thread_id: Thread.current.object_id,
106
+ thread_name: Thread.current.name || "main",
107
+ }
108
+ end
109
+
110
+ # Get timing-related metadata
111
+ #
112
+ # @return [Hash] timing metadata
113
+ def get_timing_metadata
114
+ {
115
+ timestamp: Time.now.iso8601,
116
+ unix_timestamp: Time.now.to_i,
117
+ timezone: Time.now.zone,
118
+ }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -111,9 +111,12 @@ module Makit
111
111
  def validate_single_configuration(config, index)
112
112
  raise ArgumentError, "configuration #{index} must be a hash" unless config.is_a?(Hash)
113
113
 
114
- required_keys = [:file, :format]
114
+ required_keys = %i[file format]
115
115
  missing_keys = required_keys - config.keys
116
- raise ArgumentError, "configuration #{index} missing required keys: #{missing_keys.join(", ")}" unless missing_keys.empty?
116
+ unless missing_keys.empty?
117
+ raise ArgumentError,
118
+ "configuration #{index} missing required keys: #{missing_keys.join(", ")}"
119
+ end
117
120
 
118
121
  # Validate file
119
122
  file = config[:file]
@@ -132,9 +135,9 @@ module Makit
132
135
  raise ArgumentError, "configuration #{index} min_level must be a valid log level"
133
136
  end
134
137
 
135
- if config[:max_level] && !valid_log_level?(config[:max_level])
136
- raise ArgumentError, "configuration #{index} max_level must be a valid log level"
137
- end
138
+ return unless config[:max_level] && !valid_log_level?(config[:max_level])
139
+
140
+ raise ArgumentError, "configuration #{index} max_level must be a valid log level"
138
141
  end
139
142
 
140
143
  # Check if log level is valid
@@ -163,36 +166,34 @@ module Makit
163
166
  formatter_class = FormatRegistry.get(format)
164
167
 
165
168
  # Handle different formatter initialization patterns
166
- if formatter_class == Formatters::ConsoleFormatter
167
- # ConsoleFormatter expects keyword arguments
168
- @formatters[index] = formatter_class.new(
169
- show_timestamp: formatter_options[:show_timestamp] || false,
170
- show_level: formatter_options[:show_level] || false,
171
- )
172
- elsif formatter_class == Formatters::TextFormatter
173
- # TextFormatter expects keyword arguments
174
- @formatters[index] = formatter_class.new(
175
- timestamp_format: formatter_options[:timestamp_format] || "%Y-%m-%d %H:%M:%S",
176
- include_context: formatter_options[:include_context] || false,
177
- )
178
- elsif formatter_class == Formatters::JsonFormatter
179
- # JsonFormatter expects keyword arguments
180
- @formatters[index] = formatter_class.new(
181
- options: formatter_options,
182
- )
183
- elsif formatter_class == Formatters::PlainTextFormatter
184
- # PlainTextFormatter expects keyword arguments
185
- @formatters[index] = formatter_class.new(
186
- include_context: formatter_options[:include_context] || false,
187
- )
188
- else
189
- # Other formatters expect hash or no arguments
190
- if formatter_options.empty?
191
- @formatters[index] = formatter_class.new
169
+ @formatters[index] = if formatter_class == Formatters::ConsoleFormatter
170
+ # ConsoleFormatter expects keyword arguments
171
+ formatter_class.new(
172
+ show_timestamp: formatter_options[:show_timestamp] || false,
173
+ show_level: formatter_options[:show_level] || false,
174
+ )
175
+ elsif formatter_class == Formatters::TextFormatter
176
+ # TextFormatter expects keyword arguments
177
+ formatter_class.new(
178
+ timestamp_format: formatter_options[:timestamp_format] || "%Y-%m-%d %H:%M:%S",
179
+ include_context: formatter_options[:include_context] || false,
180
+ )
181
+ elsif formatter_class == Formatters::JsonFormatter
182
+ # JsonFormatter expects keyword arguments
183
+ formatter_class.new(
184
+ options: formatter_options,
185
+ )
186
+ elsif formatter_class == Formatters::PlainTextFormatter
187
+ # PlainTextFormatter expects keyword arguments
188
+ formatter_class.new(
189
+ include_context: formatter_options[:include_context] || false,
190
+ )
191
+ elsif formatter_options.empty?
192
+ # Other formatters expect hash or no arguments
193
+ formatter_class.new
192
194
  else
193
- @formatters[index] = formatter_class.new(formatter_options)
195
+ formatter_class.new(formatter_options)
194
196
  end
195
- end
196
197
  rescue ArgumentError => e
197
198
  raise ArgumentError, "configuration #{index} has invalid format '#{format}': #{e.message}"
198
199
  end
@@ -211,7 +212,7 @@ module Makit
211
212
  FileUtils.mkdir_p(File.dirname(file)) unless File.dirname(file) == "."
212
213
 
213
214
  # Open file with appropriate mode
214
- mode = config[:append] != false ? "a" : "w"
215
+ mode = config[:append] == false ? "w" : "a"
215
216
  @files[index] = File.open(file, mode)
216
217
  else
217
218
  # Use IO object directly
@@ -244,18 +245,12 @@ module Makit
244
245
  # @return [Boolean] true if should output
245
246
  def should_output?(log_request, config)
246
247
  # Check level filtering
247
- if config[:min_level] && !level_greater_or_equal?(log_request.level, config[:min_level])
248
- return false
249
- end
248
+ return false if config[:min_level] && !level_greater_or_equal?(log_request.level, config[:min_level])
250
249
 
251
- if config[:max_level] && !level_less_or_equal?(log_request.level, config[:max_level])
252
- return false
253
- end
250
+ return false if config[:max_level] && !level_less_or_equal?(log_request.level, config[:max_level])
254
251
 
255
252
  # Check custom condition
256
- if config[:condition] && !config[:condition].call(log_request)
257
- return false
258
- end
253
+ return false if config[:condition] && !config[:condition].call(log_request)
259
254
 
260
255
  true
261
256
  end
@@ -291,9 +286,7 @@ module Makit
291
286
  sanitized.delete(:condition)
292
287
 
293
288
  # Convert IO objects to string representation
294
- if sanitized[:file].is_a?(IO)
295
- sanitized[:file] = "<#{sanitized[:file].class.name}>"
296
- end
289
+ sanitized[:file] = "<#{sanitized[:file].class.name}>" if sanitized[:file].is_a?(IO)
297
290
 
298
291
  sanitized
299
292
  end
data/lib/makit/logging.rb CHANGED
@@ -1,7 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "logger"
4
- require "colorize"
4
+ begin
5
+ require "colorize"
6
+ rescue LoadError
7
+ # colorize gem not available, define a no-op colorize method
8
+ class String
9
+ def colorize(*_args)
10
+ self
11
+ end
12
+ end
13
+ end
5
14
  require_relative "symbols"
6
15
  require_relative "logging/logger"
7
16
  require_relative "logging/log_request"
@@ -66,9 +75,25 @@ module Makit
66
75
  def self.current_log_level
67
76
  env_level = ENV["LOG_LEVEL"]&.downcase&.to_sym
68
77
  return env_level if env_level && LOG_LEVELS.key?(env_level)
78
+
69
79
  DEFAULT_LOG_LEVEL
70
80
  end
71
81
 
82
+ # Get the current verbosity level from environment or use default
83
+ def self.current_verbosity
84
+ env_verbosity = ENV["VERBOSITY"]&.downcase&.to_sym
85
+ return env_verbosity if env_verbosity && %i[quiet normal verbose debug].include?(env_verbosity)
86
+
87
+ :normal
88
+ end
89
+
90
+ # Get the current verbosity level from the default logger
91
+ #
92
+ # @return [Symbol] current verbosity level (:quiet, :normal, :verbose, :debug)
93
+ def self.verbosity
94
+ DEFAULT_LOGGER.verbosity
95
+ end
96
+
72
97
  # Logs the duration of a rake task to a file
73
98
  #
74
99
  # This method calculates the elapsed time since the STARTTIME constant was set
@@ -377,6 +402,7 @@ module Makit
377
402
  # This replaces the previous multi-sink approach with a single, configurable sink
378
403
  DEFAULT_LOGGER = Logger.new(
379
404
  level: current_log_level,
405
+ verbosity: current_verbosity,
380
406
  sinks: [
381
407
  Sinks::UnifiedFileSink.new(
382
408
  configurations: [
@@ -464,6 +490,24 @@ module Makit
464
490
  DEFAULT_LOGGER.fatal(message, context)
465
491
  end
466
492
 
493
+ # Log a verbose message (only shown in verbose or debug mode)
494
+ #
495
+ # @param message [String] the log message
496
+ # @param context [Hash] additional context information
497
+ # @return [void]
498
+ def self.verbose(message, context = {})
499
+ DEFAULT_LOGGER.verbose(message, context)
500
+ end
501
+
502
+ # Log a quiet message (shown even in quiet mode)
503
+ #
504
+ # @param message [String] the log message
505
+ # @param context [Hash] additional context information
506
+ # @return [void]
507
+ def self.quiet(message, context = {})
508
+ DEFAULT_LOGGER.quiet(message, context)
509
+ end
510
+
467
511
  # Create a logger with environment-specific configuration
468
512
  #
469
513
  # @param environment [Symbol] environment name (:development, :production, :test, :ci)
@@ -154,10 +154,10 @@ module Makit
154
154
  next if project.os == "windows" && !Makit::Environment.is_windows?
155
155
 
156
156
  project.commands.each do |command|
157
- newest_file_timestamp = Makit::Directory.get_newest_file_timestamp(project.output)
157
+ Makit::Directory.get_newest_file_timestamp(project.output)
158
158
  # newest_file = Makit::Directory::get_newest_file_or_now(project.output)
159
- command_request = Makit::RUNNER.parse_command_request(command)
160
- RUNNER.cache_run(command_request, newest_file_timestamp)
159
+ command_request = Makit::Commands::Request.from_string(command)
160
+ Makit::Commands::Runner.default.execute(command_request)
161
161
  end
162
162
  end
163
163
  end
@@ -167,10 +167,10 @@ module Makit
167
167
  next if project.os == "windows" && !Makit::Environment.is_windows?
168
168
 
169
169
  project.commands.each do |command|
170
- newest_file_timestamp = Makit::Directory.get_newest_file_timestamp(project.output)
170
+ Makit::Directory.get_newest_file_timestamp(project.output)
171
171
  # newest_file = Makit::Directory::get_newest_file_or_now(project.output)
172
- command_request = Makit::RUNNER.parse_command_request(command)
173
- RUNNER.cache_run(command_request, newest_file_timestamp)
172
+ command_request = Makit::Commands::Request.from_string(command)
173
+ Makit::Commands::Runner.default.execute(command_request)
174
174
  end
175
175
  project.build_args.each do |build_arg|
176
176
  project_path = File.join(project.output, "#{project.name}.csproj")