makit 0.0.130 → 0.0.137

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: '0621283549942c0c4d2cad1479716f15baa95683610100d19ccdce504d59c7e6'
4
- data.tar.gz: a5d3a378e509f16717d52c00759213718d364f67114bd916aff530ff45dba927
3
+ metadata.gz: 9b1587ff7fc4ebf629318b13cc0b34f7e280067e1d47e72c39e9e4fe0eccdacd
4
+ data.tar.gz: 3791591e80c80cb78ad1ad4e3a2751116539fa014392ca0de9def3cd2abe3d16
5
5
  SHA512:
6
- metadata.gz: 46399a0009c96b0834222c940d25d0b9284e708240290efc317fe0840cc6d9a10ee6ace8bb1fb324f463f1de932e7b6f114ae4fd3ee8cbb8c358d476259002c4
7
- data.tar.gz: 1fc7149896202a6bbb7619d3b5354e460edcfc210bd972d22eb5b679eb998f48c459520974d64d3db9bcff189934700e321380a8ef0412270a36152b970c9d59
6
+ metadata.gz: 546e136499db7988f773144965e99334849472abdaa35cc48a43c3a6ead87b390f7a6934369ce7edd90f65c570dfca7cd2ac23220c0009ea783363676dc79a99
7
+ data.tar.gz: 5b24c2215de2aeeafb894453e3de1aef3ee4db9ef50dcf1880c5c4b489c93018bf56fd9f933d1dee26d31b3b18bd84177c03546c539a5deb40a5732eb29c0671
data/exe/makit CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "makit"
4
+ require "makit/auto"
5
5
  Makit::Cli::MainCommand.run(ARGV)
data/lib/makit/auto.rb ADDED
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load the core makit functionality first
4
+ begin
5
+ require_relative "../makit"
6
+ rescue LoadError => e
7
+ # If makit can't be loaded (e.g., missing dependencies),
8
+ # we'll still provide the auto module
9
+ puts "Warning: Could not load full makit library: #{e.message}"
10
+ end
11
+
12
+ # Load CLI functionality for command-line interface
13
+ begin
14
+ require_relative "cli/main"
15
+ require_relative "cli/repository_commands"
16
+ require_relative "cli/project_commands"
17
+ require_relative "cli/build_commands"
18
+ require_relative "cli/utility_commands"
19
+ require_relative "cli/strategy_commands"
20
+ rescue LoadError => e
21
+ puts "Warning: Could not load CLI modules: #{e.message}"
22
+ end
23
+
24
+ module Makit
25
+ # Auto module provides enhanced functionality when requiring "makit/auto"
26
+ # This includes CLI commands and other enhanced features
27
+ module Auto
28
+ # Version of the auto functionality
29
+ VERSION = "1.0.0"
30
+
31
+ # Check if auto functionality is loaded
32
+ def self.loaded?
33
+ true
34
+ end
35
+
36
+ # Log that auto mode is enabled
37
+ def self.enable_auto_mode
38
+ if defined?(Makit::Logging)
39
+ Makit::Logging.info("Makit auto mode enabled - enhanced functionality available")
40
+ else
41
+ puts "Makit auto mode enabled - enhanced functionality available"
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # Enable auto mode logging
48
+ Makit::Auto.enable_auto_mode
@@ -5,6 +5,7 @@ require_relative "repository_commands"
5
5
  require_relative "project_commands"
6
6
  require_relative "build_commands"
7
7
  require_relative "utility_commands"
8
+ require_relative "strategy_commands"
8
9
  require_relative "../rake/cli"
9
10
 
10
11
  module Makit
@@ -20,6 +21,8 @@ module Makit
20
21
  project - Manage project creation and setup (new, init, setup, work)
21
22
  build - Build operations and cleanup (make, clean)
22
23
  utility - System utilities and maintenance (nuget-cache, system-info)
24
+ strategy - Manage execution strategies (show, test)
25
+ trace - Manage trace functionality (show, enable, disable, test)
23
26
  rake - Manage rake tasks
24
27
 
25
28
  Common usage examples:
@@ -56,6 +59,8 @@ module Makit
56
59
  subcommand "project", "Manage project creation and setup", ProjectCommand
57
60
  subcommand "build", "Build operations and cleanup", BuildCommand
58
61
  subcommand "utility", "System utilities and maintenance", UtilityCommand
62
+ subcommand "strategy", "Manage execution strategies", StrategyCommands
63
+ subcommand "trace", "Manage trace functionality", TraceCommands
59
64
  subcommand "rake", "Manage rake tasks", Makit::Rake::CliCommand
60
65
  end
61
66
  end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Makit
6
+ module Cli
7
+ # Commands for managing execution strategies
8
+ class StrategyCommands < Base
9
+ desc "strategy", "Show current execution strategy information"
10
+ option ["--verbose", "-v"], :flag, "Show detailed strategy information"
11
+ def strategy
12
+ runner = Makit::Commands::Runner.default
13
+ info = runner.strategy_info
14
+
15
+ puts "Current Execution Strategy:"
16
+ puts " Type: #{info[:type]}"
17
+ puts " Class: #{info[:class]}"
18
+
19
+ if options[:verbose]
20
+ puts "\nFactory Information:"
21
+ factory_info = info[:factory_info]
22
+ puts " Current: #{factory_info[:current]}"
23
+ puts " Available: #{factory_info[:available].join(', ')}"
24
+ puts " ChildProcess Available: #{factory_info[:childprocess_available]}"
25
+ puts " Open3 Available: #{factory_info[:open3_available]}"
26
+ end
27
+
28
+ puts "\nEnvironment Variables:"
29
+ puts " MAKIT_STRATEGY: #{ENV['MAKIT_STRATEGY'] || 'not set (using auto-detect)'}"
30
+ end
31
+
32
+ desc "strategy test", "Test both strategies and show performance comparison"
33
+ option ["--timeout", "-t"], "TIMEOUT", "Timeout for test commands", default: "5"
34
+ def test
35
+ timeout = options[:timeout].to_i
36
+
37
+ puts "Testing execution strategies..."
38
+ puts "=" * 50
39
+
40
+ # Test ChildProcess strategy
41
+ puts "\n1. Testing ChildProcess Strategy:"
42
+ childprocess_result = test_strategy('childprocess', timeout)
43
+
44
+ # Test Open3 strategy
45
+ puts "\n2. Testing Open3 Strategy:"
46
+ open3_result = test_strategy('open3', timeout)
47
+
48
+ # Show comparison
49
+ puts "\n" + "=" * 50
50
+ puts "Performance Comparison:"
51
+ puts " ChildProcess: #{childprocess_result[:duration]}s (#{childprocess_result[:status]})"
52
+ puts " Open3: #{open3_result[:duration]}s (#{open3_result[:status]})"
53
+ end
54
+
55
+ private
56
+
57
+ # Test a specific strategy
58
+ #
59
+ # @param strategy_type [String] strategy type to test
60
+ # @param timeout [Integer] timeout for test commands
61
+ # @return [Hash] test results
62
+ def test_strategy(strategy_type, timeout)
63
+ start_time = Time.now
64
+
65
+ begin
66
+ # Create runner with specific strategy
67
+ strategy = Makit::Commands::Strategies::Factory.create(strategy: strategy_type)
68
+ runner = Makit::Commands::Runner.new(strategy: strategy)
69
+
70
+ # Test with a simple command
71
+ request = Makit::Commands::Request.new(
72
+ command: "echo",
73
+ arguments: ["Hello from #{strategy_type}!"],
74
+ timeout: timeout
75
+ )
76
+
77
+ result = runner.execute(request)
78
+ duration = Time.now - start_time
79
+
80
+ status = result.success? ? "SUCCESS" : "FAILED"
81
+ puts " Status: #{status}"
82
+ puts " Duration: #{duration.round(3)}s"
83
+ puts " Output: #{result.stdout.strip}"
84
+
85
+ if result.failure?
86
+ puts " Error: #{result.stderr}"
87
+ end
88
+
89
+ { duration: duration.round(3), status: status, success: result.success? }
90
+
91
+ rescue => e
92
+ duration = Time.now - start_time
93
+ puts " Status: ERROR"
94
+ puts " Duration: #{duration.round(3)}s"
95
+ puts " Error: #{e.message}"
96
+
97
+ { duration: duration.round(3), status: "ERROR", success: false }
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ # Add trace commands to the main CLI
104
+ module Makit
105
+ module Cli
106
+ # Commands for managing trace functionality
107
+ class TraceCommands < Base
108
+ desc "trace", "Show current trace status and configuration"
109
+ option ["--verbose", "-v"], :flag, "Show detailed trace information"
110
+ def trace
111
+ puts "Makit Trace Status:"
112
+ puts "=" * 30
113
+
114
+ status = Makit::Rake.status
115
+
116
+ puts "Enhanced Tracing: #{Makit::Rake.tracing_enabled? ? 'Enabled' : 'Disabled'}"
117
+ puts "Rake Trace: #{status[:trace_controller][:rake_trace] || 'Not set'}"
118
+ puts "Trace Flag: #{status[:trace_controller][:trace_flag] ? 'Present' : 'Not present'}"
119
+ puts "Makit Trace: #{status[:trace_controller][:makit_trace] || 'Not set'}"
120
+ puts "Verbose Mode: #{status[:verbose] ? 'Enabled' : 'Disabled'}"
121
+
122
+ if options[:verbose]
123
+ puts "\nDetailed Information:"
124
+ puts " Strategy: #{status[:strategy][:type] || 'Unknown'}"
125
+ puts " Class: #{status[:strategy][:class] || 'Unknown'}"
126
+ puts " Factory Info: #{status[:strategy][:factory_info] || 'Not available'}"
127
+ end
128
+ end
129
+
130
+ desc "trace enable", "Enable enhanced tracing"
131
+ def enable
132
+ ENV['MAKIT_TRACE'] = 'true'
133
+ puts "Enhanced tracing enabled"
134
+ puts "Run 'rake --trace' to see enhanced output"
135
+ end
136
+
137
+ desc "trace disable", "Disable enhanced tracing"
138
+ def disable
139
+ ENV.delete('MAKIT_TRACE')
140
+ puts "Enhanced tracing disabled"
141
+ end
142
+
143
+ desc "trace test", "Test trace functionality with a simple rake task"
144
+ def test
145
+ puts "Testing trace functionality..."
146
+ puts "Run: rake --trace"
147
+ puts "You should see [MAKIT] prefixed trace output for makit-related tasks"
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -230,8 +230,9 @@ module Makit
230
230
  # @param duration [Float] execution duration
231
231
  # @param command_id [String] unique command identifier
232
232
  def log_performance_warnings(request, result, duration, command_id)
233
+ duration_threshold_seconds = 60.0
233
234
  # Log slow commands
234
- if duration > 5.0
235
+ if duration > duration_threshold_seconds
235
236
  @logger.warn("Slow command detected",
236
237
  command_id: command_id,
237
238
  command: request.command,
@@ -3,6 +3,7 @@
3
3
  require_relative "request"
4
4
  require_relative "result"
5
5
  require_relative "strategies/synchronous"
6
+ require_relative "strategies/factory"
6
7
  require_relative "middleware/base"
7
8
  require_relative "middleware/command_logger"
8
9
 
@@ -40,19 +41,24 @@ module Makit
40
41
  # @return [Runner] default runner with standard middleware
41
42
  def self.default
42
43
  # Recreate the runner if the log level has changed
43
- current_log_level = Makit::Logging.current_log_level
44
+ current_log_level = defined?(Makit::Logging) ? Makit::Logging.current_log_level : :info
44
45
  if @default.nil? || @last_log_level != current_log_level
45
46
  @last_log_level = current_log_level
46
- @default = new(
47
- middleware: [
48
- Middleware::CommandLogger.new(
49
- log_stdout: true,
50
- log_stderr: true,
51
- log_performance: true,
52
- max_output_lines: 50,
53
- ),
54
- ],
55
- )
47
+ begin
48
+ @default = new(
49
+ middleware: [
50
+ Middleware::CommandLogger.new(
51
+ log_stdout: true,
52
+ log_stderr: true,
53
+ log_performance: true,
54
+ max_output_lines: 50,
55
+ ),
56
+ ],
57
+ )
58
+ rescue => e
59
+ # Fallback to basic runner if there are issues
60
+ @default = new
61
+ end
56
62
  end
57
63
  @default
58
64
  end
@@ -64,7 +70,7 @@ module Makit
64
70
  # @param options [Hash] additional configuration
65
71
  def initialize(middleware: nil, strategy: nil, **options)
66
72
  @middleware = Array(middleware || default_middleware)
67
- @strategy = strategy || Strategies::Synchronous.new
73
+ @strategy = strategy || Strategies::Factory.create(options)
68
74
  @options = options
69
75
 
70
76
  validate_middleware
@@ -314,6 +320,17 @@ module Makit
314
320
  raise ArgumentError, "Strategy must respond to #supports?: #{@strategy.class}"
315
321
  end
316
322
 
323
+ # Get information about the current strategy
324
+ #
325
+ # @return [Hash] strategy information
326
+ def strategy_info
327
+ {
328
+ class: @strategy.class.name,
329
+ type: @strategy.class.name.split('::').last.downcase,
330
+ factory_info: Strategies::Factory.strategy_info
331
+ }
332
+ end
333
+
317
334
  # Log command execution result using the default logger.
318
335
  #
319
336
  # @param request [Request] the executed request
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'childprocess'
4
+ require 'tempfile'
5
+ require_relative "base"
6
+
7
+ module Makit
8
+ module Commands
9
+ module Strategies
10
+ # ChildProcess-based command execution strategy
11
+ #
12
+ # This strategy uses the ChildProcess gem for robust cross-platform
13
+ # process management. It provides better handling of timeouts, I/O,
14
+ # and process lifecycle management compared to Open3.
15
+ #
16
+ # @example Basic usage
17
+ # strategy = ChildProcess.new
18
+ # result = strategy.execute(request)
19
+ #
20
+ # @example With custom options
21
+ # strategy = ChildProcess.new(
22
+ # timeout: 60,
23
+ # max_output_size: 1_000_000
24
+ # )
25
+ class ChildProcess < Base
26
+ # @!attribute [r] timeout
27
+ # @return [Integer] default timeout in seconds
28
+ attr_reader :timeout
29
+
30
+ # @!attribute [r] max_output_size
31
+ # @return [Integer] maximum output size in bytes
32
+ attr_reader :max_output_size
33
+
34
+ # Initialize ChildProcess strategy
35
+ #
36
+ # @param timeout [Integer] default timeout in seconds (default: 30)
37
+ # @param max_output_size [Integer] maximum output size in bytes (default: 1MB)
38
+ def initialize(timeout: 30, max_output_size: 1_000_000, **options)
39
+ @timeout = timeout
40
+ @max_output_size = max_output_size
41
+ super(**options)
42
+ end
43
+
44
+ # Execute a command request using ChildProcess
45
+ #
46
+ # @param request [Request] the command request to execute
47
+ # @return [Result] execution result
48
+ def execute(request)
49
+ result = Result.new(
50
+ command: request.to_shell_command,
51
+ started_at: Time.now,
52
+ )
53
+
54
+ stdout_file = nil
55
+ stderr_file = nil
56
+ process = nil
57
+
58
+ begin
59
+ # Create temporary files for output
60
+ stdout_file = Tempfile.new('makit_stdout')
61
+ stderr_file = Tempfile.new('makit_stderr')
62
+
63
+ # Build the process
64
+ process = ChildProcess.build(request.command, *request.arguments)
65
+
66
+ # Set working directory
67
+ process.cwd = request.directory if request.directory
68
+
69
+ # Set environment variables
70
+ (request.environment || {}).each do |key, value|
71
+ process.environment[key] = value.to_s
72
+ end
73
+
74
+ # Set up I/O
75
+ process.io.stdout = stdout_file
76
+ process.io.stderr = stderr_file
77
+
78
+ # Start the process
79
+ process.start
80
+
81
+ # Wait for completion with timeout
82
+ timeout_seconds = request.timeout || @timeout
83
+ process.poll_for_exit(timeout_seconds)
84
+
85
+ # Read output
86
+ stdout_file.rewind
87
+ stderr_file.rewind
88
+ stdout = stdout_file.read
89
+ stderr = stderr_file.read
90
+
91
+ # Truncate output if too large
92
+ stdout = truncate_output(stdout, "stdout")
93
+ stderr = truncate_output(stderr, "stderr")
94
+
95
+ result.finish!(
96
+ exit_code: process.exit_code,
97
+ stdout: stdout,
98
+ stderr: stderr,
99
+ )
100
+
101
+ rescue ChildProcess::TimeoutError
102
+ # Handle timeout
103
+ process&.stop
104
+ result.finish!(
105
+ exit_code: 124,
106
+ stderr: "Command timed out after #{timeout_seconds} seconds",
107
+ ).add_metadata(:timeout, true)
108
+ .add_metadata(:strategy, 'childprocess')
109
+
110
+ rescue => e
111
+ # Handle other errors
112
+ process&.stop rescue nil
113
+ result.finish!(
114
+ exit_code: 1,
115
+ stderr: e.message,
116
+ ).add_metadata(:error_class, e.class.name)
117
+ .add_metadata(:strategy, 'childprocess')
118
+
119
+ ensure
120
+ # Clean up resources
121
+ [stdout_file, stderr_file].each do |file|
122
+ file&.close
123
+ file&.unlink rescue nil
124
+ end
125
+ end
126
+
127
+ result
128
+ end
129
+
130
+ # Execute multiple requests using ChildProcess
131
+ #
132
+ # @param requests [Array<Request>] requests to execute
133
+ # @return [Array<Result>] execution results
134
+ def execute_batch(requests)
135
+ # For now, execute sequentially to avoid complexity
136
+ # Could be enhanced to use process pools in the future
137
+ requests.map { |request| execute(request) }
138
+ end
139
+
140
+ private
141
+
142
+ # Truncate output if it exceeds maximum size
143
+ #
144
+ # @param output [String] output to potentially truncate
145
+ # @param type [String] output type for logging
146
+ # @return [String] truncated output
147
+ def truncate_output(output, type)
148
+ return output if output.bytesize <= @max_output_size
149
+
150
+ original_size = output.bytesize
151
+ truncated = output.byteslice(0, @max_output_size)
152
+
153
+ Makit::Logging.warn(
154
+ "#{type.capitalize} truncated",
155
+ original_size: original_size,
156
+ max_size: @max_output_size,
157
+ strategy: 'childprocess'
158
+ )
159
+
160
+ "#{truncated}\n[#{type.upcase} TRUNCATED - Original size: #{original_size} bytes]"
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "synchronous"
5
+
6
+ module Makit
7
+ module Commands
8
+ module Strategies
9
+ # Factory for creating command execution strategies with fallback support
10
+ #
11
+ # This factory allows easy switching between different execution strategies
12
+ # (ChildProcess, Open3, etc.) with automatic fallback to Open3 if the
13
+ # preferred strategy fails to load or execute.
14
+ #
15
+ # @example Using environment variable to control strategy
16
+ # # Use ChildProcess (default)
17
+ # MAKIT_STRATEGY=childprocess rake
18
+ #
19
+ # # Force Open3 usage
20
+ # MAKIT_STRATEGY=open3 rake
21
+ #
22
+ # # Auto-detect (try ChildProcess, fallback to Open3)
23
+ # MAKIT_STRATEGY=auto rake
24
+ class Factory
25
+ # Available strategy types
26
+ STRATEGIES = {
27
+ 'childprocess' => 'ChildProcess',
28
+ 'open3' => 'Synchronous',
29
+ 'auto' => 'AutoDetect'
30
+ }.freeze
31
+
32
+ # Get the configured strategy instance
33
+ #
34
+ # @param options [Hash] strategy options
35
+ # @return [Strategies::Base] configured strategy instance
36
+ def self.create(options = {})
37
+ strategy_type = determine_strategy_type
38
+
39
+ begin
40
+ case strategy_type
41
+ when 'childprocess'
42
+ create_childprocess_strategy(options)
43
+ when 'open3'
44
+ create_open3_strategy(options)
45
+ when 'auto'
46
+ create_auto_detect_strategy(options)
47
+ else
48
+ Makit::Logging.warn("Unknown strategy '#{strategy_type}', falling back to Open3") if defined?(Makit::Logging)
49
+ create_open3_strategy(options)
50
+ end
51
+ rescue => e
52
+ # Ultimate fallback - create basic synchronous strategy
53
+ Makit::Logging.warn("Failed to create strategy: #{e.message}") if defined?(Makit::Logging)
54
+ Synchronous.new
55
+ end
56
+ end
57
+
58
+ # Get the current strategy type from environment or default
59
+ #
60
+ # @return [String] strategy type
61
+ def self.determine_strategy_type
62
+ env_strategy = ENV['MAKIT_STRATEGY']&.downcase
63
+
64
+ if env_strategy && STRATEGIES.key?(env_strategy)
65
+ env_strategy
66
+ else
67
+ 'auto' # Default to auto-detect
68
+ end
69
+ end
70
+
71
+ # Create ChildProcess strategy with fallback
72
+ #
73
+ # @param options [Hash] strategy options
74
+ # @return [Strategies::Base] strategy instance
75
+ def self.create_childprocess_strategy(options)
76
+ begin
77
+ require_relative 'child_process'
78
+ ChildProcess.new(**options)
79
+ rescue LoadError, StandardError => e
80
+ Makit::Logging.warn("Failed to load ChildProcess strategy: #{e.message}")
81
+ Makit::Logging.info("Falling back to Open3 strategy")
82
+ create_open3_strategy(options)
83
+ end
84
+ end
85
+
86
+ # Create Open3 strategy
87
+ #
88
+ # @param options [Hash] strategy options
89
+ # @return [Strategies::Base] strategy instance
90
+ def self.create_open3_strategy(options)
91
+ Synchronous.new(**options)
92
+ end
93
+
94
+ # Create auto-detect strategy that tries ChildProcess first
95
+ #
96
+ # @param options [Hash] strategy options
97
+ # @return [Strategies::Base] strategy instance
98
+ def self.create_auto_detect_strategy(options)
99
+ # Always use Open3 for now to avoid circular dependency issues
100
+ begin
101
+ Makit::Logging.debug("Using Open3 strategy") if defined?(Makit::Logging)
102
+ Synchronous.new(**options)
103
+ rescue => e
104
+ # Fallback to basic strategy if there are any issues
105
+ Makit::Logging.warn("Failed to create Open3 strategy: #{e.message}") if defined?(Makit::Logging)
106
+ Synchronous.new
107
+ end
108
+ end
109
+
110
+ # Get information about available strategies
111
+ #
112
+ # @return [Hash] strategy information
113
+ def self.strategy_info
114
+ {
115
+ current: determine_strategy_type,
116
+ available: STRATEGIES.keys,
117
+ childprocess_available: childprocess_available?,
118
+ open3_available: true # Always available
119
+ }
120
+ end
121
+
122
+ # Check if ChildProcess strategy is available
123
+ #
124
+ # @return [Boolean] true if ChildProcess can be loaded
125
+ def self.childprocess_available?
126
+ begin
127
+ require 'childprocess'
128
+ true
129
+ rescue LoadError
130
+ false
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -62,7 +62,7 @@ class String
62
62
  end
63
63
 
64
64
  def cache_run(timestamp = nil)
65
- puts "cache_run: #{self}"
65
+ #puts "cache_run: #{self}"
66
66
  command = self
67
67
  request = Makit::Commands::Request.from_string(command)
68
68
  if timestamp
@@ -75,9 +75,9 @@ class String
75
75
  environment: request.environment || {},
76
76
  metadata: (request.metadata || {}).merge(timestamp: timestamp),
77
77
  )
78
- puts "timestamp: #{timestamp}"
78
+ #puts "timestamp: #{timestamp}"
79
79
  else
80
- puts "no timestamp"
80
+ #puts "no timestamp"
81
81
  end
82
82
  Makit::Commands::Runner.default.execute(request)
83
83
  end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Makit
4
+ module Rake
5
+ # Enhanced trace controller for Rake with Makit-specific debugging information
6
+ #
7
+ # This class provides enhanced tracing capabilities when --trace is passed to rake,
8
+ # adding makit-specific debugging information to help with troubleshooting and
9
+ # understanding command execution flow.
10
+ #
11
+ # @example Basic usage
12
+ # # In Rakefile
13
+ # require "makit"
14
+ # Makit::Rake::TraceController.setup
15
+ #
16
+ # @example With environment variable
17
+ # MAKIT_TRACE=true rake --trace
18
+ class TraceController
19
+ # Set up enhanced tracing for Rake tasks
20
+ #
21
+ # This method should be called early in the Rakefile to enable enhanced
22
+ # tracing when --trace is passed to rake.
23
+ #
24
+ # @return [void]
25
+ def self.setup
26
+ return unless should_enhance_trace?
27
+
28
+ # Set up enhanced tracing
29
+ setup_enhanced_tracing
30
+ Makit::Logging.debug("Enhanced trace controller activated") if defined?(Makit::Logging)
31
+ end
32
+
33
+ # Check if trace enhancement should be enabled
34
+ #
35
+ # @return [Boolean] true if trace enhancement should be enabled
36
+ def self.should_enhance_trace?
37
+ ENV['RAKE_TRACE'] ||
38
+ ARGV.include?('--trace') ||
39
+ ENV['MAKIT_TRACE'] == 'true'
40
+ end
41
+
42
+ # Get current trace status
43
+ #
44
+ # @return [Hash] trace status information
45
+ def self.trace_status
46
+ {
47
+ rake_trace: ENV['RAKE_TRACE'],
48
+ trace_flag: ARGV.include?('--trace'),
49
+ makit_trace: ENV['MAKIT_TRACE'],
50
+ enhanced: should_enhance_trace?
51
+ }
52
+ end
53
+
54
+ private
55
+
56
+ # Set up enhanced tracing by monkey patching Rake's trace methods
57
+ #
58
+ # @return [void]
59
+ def self.setup_enhanced_tracing
60
+ # Store the original trace method if not already stored
61
+ unless ::Rake::Task.method_defined?(:makit_original_trace)
62
+ ::Rake::Task.class_eval do
63
+ alias_method :makit_original_trace, :trace
64
+
65
+ def trace(mode, message)
66
+ # Call original trace
67
+ makit_original_trace(mode, message)
68
+
69
+ # Add makit-specific trace info
70
+ add_makit_trace_info(mode, message)
71
+ end
72
+
73
+ private
74
+
75
+ # Add makit-specific trace information
76
+ #
77
+ # @param mode [Symbol] trace mode (:execute, :invoke, :prereq, etc.)
78
+ # @param message [String] trace message
79
+ # @return [void]
80
+ def add_makit_trace_info(mode, message)
81
+ case mode
82
+ when :execute
83
+ trace_makit_execution(message)
84
+ when :invoke
85
+ trace_makit_invocation(message)
86
+ when :prereq
87
+ trace_makit_prerequisite(message)
88
+ when :syntax
89
+ trace_makit_syntax(message)
90
+ end
91
+ end
92
+
93
+ # Trace makit execution with detailed information
94
+ #
95
+ # @param message [String] execution message
96
+ # @return [void]
97
+ def trace_makit_execution(message)
98
+ if makit_related?(message)
99
+ puts " [MAKIT] Executing: #{message}"
100
+ puts " [MAKIT] Strategy: #{get_makit_strategy_info}"
101
+ puts " [MAKIT] Environment: #{ENV['MAKIT_STRATEGY'] || 'auto'}"
102
+ puts " [MAKIT] Working Directory: #{Dir.pwd}"
103
+ puts " [MAKIT] Timestamp: #{Time.now.iso8601}"
104
+ puts " [MAKIT] Task: #{name}"
105
+ end
106
+ end
107
+
108
+ # Trace makit invocation
109
+ #
110
+ # @param message [String] invocation message
111
+ # @return [void]
112
+ def trace_makit_invocation(message)
113
+ if makit_related?(message)
114
+ puts " [MAKIT] Invoking: #{message}"
115
+ puts " [MAKIT] Task: #{name}"
116
+ end
117
+ end
118
+
119
+ # Trace makit prerequisite
120
+ #
121
+ # @param message [String] prerequisite message
122
+ # @return [void]
123
+ def trace_makit_prerequisite(message)
124
+ if makit_related?(message)
125
+ puts " [MAKIT] Prerequisite: #{message}"
126
+ puts " [MAKIT] Task: #{name}"
127
+ end
128
+ end
129
+
130
+ # Trace makit syntax
131
+ #
132
+ # @param message [String] syntax message
133
+ # @return [void]
134
+ def trace_makit_syntax(message)
135
+ if makit_related?(message)
136
+ puts " [MAKIT] Syntax: #{message}"
137
+ end
138
+ end
139
+
140
+ # Check if message is makit-related
141
+ #
142
+ # @param message [String] message to check
143
+ # @return [Boolean] true if message is makit-related
144
+ def makit_related?(message)
145
+ message.downcase.include?('makit') ||
146
+ message.include?('bundle') ||
147
+ message.include?('gem') ||
148
+ message.include?('dotnet') ||
149
+ message.include?('protoc') ||
150
+ message.include?('git')
151
+ end
152
+
153
+ # Get makit strategy information safely
154
+ #
155
+ # @return [String] strategy information
156
+ def get_makit_strategy_info
157
+ begin
158
+ if defined?(Makit::Commands::Runner)
159
+ runner = Makit::Commands::Runner.default
160
+ info = runner.strategy_info
161
+ "#{info[:type]} (#{info[:class]})"
162
+ else
163
+ "not available"
164
+ end
165
+ rescue => e
166
+ "error: #{e.message}"
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
data/lib/makit/rake.rb CHANGED
@@ -1,25 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This module provides classes for the Makit gem.
3
+ require_relative "rake/trace_controller"
4
+
4
5
  module Makit
5
- # This class provide methods for working with the system Environment.
6
- #
7
- class RakeHelper
8
- def self.rake_repository(url, task_name)
9
- local_path = File.join(Makit::Directories::HOME, "code", "work", Makit::Directories.get_relative_directory(url))
10
- if Dir.exist?(local_path)
11
- Dir.chdir(local_path) do
12
- puts " #{local_path.to_s.colorize(:grey)}"
13
- "git pull".run
6
+ module Rake
7
+ # Enhanced Rake integration for Makit
8
+ #
9
+ # This module provides enhanced Rake integration capabilities including
10
+ # trace enhancement, task monitoring, and debugging utilities.
11
+ #
12
+ # @example Basic usage
13
+ # require "makit"
14
+ # Makit::Rake.setup
15
+ #
16
+ # @example With custom options
17
+ # Makit::Rake.setup(trace: true, verbose: true)
18
+ class << self
19
+ # Set up enhanced Rake integration
20
+ #
21
+ # @param trace [Boolean] enable trace enhancement (default: auto-detect)
22
+ # @param verbose [Boolean] enable verbose output (default: false)
23
+ # @return [void]
24
+ def setup(trace: nil, verbose: false)
25
+ # Set up trace enhancement
26
+ if trace.nil?
27
+ TraceController.setup
28
+ elsif trace
29
+ ENV['MAKIT_TRACE'] = 'true'
30
+ TraceController.setup
31
+ end
32
+
33
+ # Set up verbose output if requested
34
+ if verbose
35
+ ENV['MAKIT_VERBOSE'] = 'true'
14
36
  end
15
- else
16
- puts "> ".colorize(:grey) + "git clone #{url} #{local_path}".colorize(:green)
17
- `git clone #{url} #{local_path}`
37
+
38
+ # Log setup completion
39
+ if defined?(Makit::Logging)
40
+ Makit::Logging.debug("Makit Rake integration setup completed")
41
+ Makit::Logging.debug("Trace status: #{TraceController.trace_status}")
42
+ end
43
+ end
44
+
45
+ # Get current Rake integration status
46
+ #
47
+ # @return [Hash] integration status
48
+ def status
49
+ {
50
+ trace_controller: TraceController.trace_status,
51
+ verbose: ENV['MAKIT_VERBOSE'] == 'true',
52
+ strategy: get_strategy_info
53
+ }
54
+ end
55
+
56
+ # Check if enhanced tracing is active
57
+ #
58
+ # @return [Boolean] true if enhanced tracing is active
59
+ def tracing_enabled?
60
+ TraceController.should_enhance_trace?
18
61
  end
19
- Dir.chdir(local_path) do
20
- puts " #{local_path.to_s.colorize(:grey)}"
21
- "rake #{task_name}".run
62
+
63
+ private
64
+
65
+ # Get strategy information safely
66
+ #
67
+ # @return [Hash] strategy information
68
+ def get_strategy_info
69
+ begin
70
+ if defined?(Makit::Commands::Runner)
71
+ Makit::Commands::Runner.default.strategy_info
72
+ else
73
+ { error: "Commands::Runner not available" }
74
+ end
75
+ rescue => e
76
+ { error: e.message }
77
+ end
22
78
  end
23
79
  end
24
80
  end
25
- end
81
+ end
@@ -105,18 +105,18 @@ module Makit
105
105
  end
106
106
 
107
107
  def self.create_version_file(project)
108
- version_path = "lib/#{project.name}/version.rb"
109
- return if File.exist?(version_path)
108
+ #version_path = "lib/#{project.name}/version.rb"
109
+ #return if File.exist?(version_path)
110
110
 
111
- version_content = <<~VERSION
112
- # frozen_string_literal: true
111
+ #version_content = <<~VERSION
112
+ # # frozen_string_literal: true
113
113
 
114
- module #{project.name.capitalize}
115
- VERSION = "#{project.version}"
116
- end
117
- VERSION
114
+ # module #{project.name.capitalize}
115
+ # VERSION = "#{project.version}"
116
+ # end
117
+ #VERSION
118
118
 
119
- File.write(version_path, version_content)
119
+ #File.write(version_path, version_content)
120
120
  end
121
121
 
122
122
  def self.create_rakefile(_project)
@@ -50,7 +50,8 @@ module Makit
50
50
  # end
51
51
  def self.track(task_name)
52
52
  task = new(task_name)
53
- Makit::SHOW.task(task_name)
53
+ Makit::Logging.default_logger.task_start(task_name)
54
+ #Makit::SHOW.task(task_name)
54
55
  yield(task)
55
56
  ensure
56
57
  task&.report_and_store_time_taken
@@ -65,7 +66,8 @@ module Makit
65
66
  # @return [Object] Result of the yielded block
66
67
  def self.track_inferred(&block)
67
68
  task_name = infer_task_name
68
- Makit::SHOW.task(task_name)
69
+ Makit::Logging.default_logger.task_start(task_name)
70
+ #Makit::SHOW.task(task_name)
69
71
  track(task_name, &block)
70
72
  end
71
73
 
@@ -270,13 +270,65 @@ module Makit
270
270
  def setup!
271
271
  return if @hooks_installed
272
272
 
273
- Rake::Task.class_eval do
273
+ ::Rake::Task.class_eval do
274
274
  alias_method :makit_original_execute, :execute
275
275
 
276
+ # Check if this task should have enhanced makit tracing
277
+ #
278
+ # @return [Boolean] true if task should be traced
279
+ def should_trace_makit_task?
280
+ # Check if trace is enabled
281
+ return false unless ENV['RAKE_TRACE'] || ARGV.include?('--trace') || ENV['MAKIT_TRACE'] == 'true'
282
+
283
+ # Check if task is makit-related
284
+ makit_related_task?
285
+ end
286
+
287
+ # Check if task is makit-related
288
+ #
289
+ # @return [Boolean] true if task is makit-related
290
+ def makit_related_task?
291
+ name.downcase.include?('makit') ||
292
+ name.include?('bundle') ||
293
+ name.include?('gem') ||
294
+ name.include?('dotnet') ||
295
+ name.include?('protoc') ||
296
+ name.include?('git') ||
297
+ name.include?('setup') ||
298
+ name.include?('build') ||
299
+ name.include?('test')
300
+ end
301
+
302
+ # Get makit strategy information safely
303
+ #
304
+ # @return [String] strategy information
305
+ def get_makit_strategy_info
306
+ begin
307
+ if defined?(Makit::Commands::Runner)
308
+ runner = Makit::Commands::Runner.default
309
+ info = runner.strategy_info
310
+ "#{info[:type]} (#{info[:class]})"
311
+ else
312
+ "not available"
313
+ end
314
+ rescue => e
315
+ "error: #{e.message}"
316
+ end
317
+ end
318
+
276
319
  def execute(args = nil)
277
320
  start_time = Time.now
278
321
  error = nil
279
322
  result = nil
323
+
324
+ # Add enhanced trace output for makit-related tasks
325
+ if should_trace_makit_task?
326
+ puts " [MAKIT] Executing task: #{name}"
327
+ puts " [MAKIT] Strategy: #{get_makit_strategy_info}"
328
+ puts " [MAKIT] Environment: #{ENV['MAKIT_STRATEGY'] || 'auto'}"
329
+ puts " [MAKIT] Working Directory: #{Dir.pwd}"
330
+ puts " [MAKIT] Timestamp: #{Time.now.iso8601}"
331
+ end
280
332
 
281
333
  begin
282
334
  # Execute pre-hooks
data/lib/makit/version.rb CHANGED
@@ -1,5 +1,96 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Makit
4
- VERSION = "0.0.130"
5
- end
4
+ # Static version for now to avoid circular dependency issues
5
+ VERSION = "0.0.137"
6
+
7
+ # Version management utilities for various file formats
8
+ #
9
+ # This class provides methods for detecting, extracting, and updating version
10
+ # numbers in various file formats including .csproj, .wxs, .yml, .gemspec,
11
+ # .nuspec, and .toml files.
12
+ class Version
13
+ # Find the highest version from an array of version strings
14
+ #
15
+ # @param versions [Array<String>] Array of version strings to compare
16
+ # @return [String] The highest version string using semantic versioning comparison
17
+ def self.get_highest_version(versions)
18
+ versions.max { |a, b| Gem::Version.new(a) <=> Gem::Version.new(b) }
19
+ end
20
+
21
+ # Extract version number from a file based on its extension
22
+ #
23
+ # Supports multiple file formats:
24
+ # - .csproj files: `<Version>x.y.z</Version>`
25
+ # - .wxs files: `Version="x.y.z"`
26
+ # - .yml files: `VERSION: "x.y.z"`
27
+ #
28
+ # @param path [String] Path to the file containing version information
29
+ # @return [String] The extracted version string
30
+ # @raise [RuntimeError] If file doesn't exist or has unrecognized extension
31
+ def self.get_version_from_file(path)
32
+ raise "file #{path}does not exist" unless File.exist?(path)
33
+
34
+ extension = File.extname(path)
35
+ case extension
36
+ when ".csproj"
37
+ Makit::Version.detect_from_file(path, /<Version>([-\w\d.]+)</)
38
+ when ".wxs"
39
+ Makit::Version.detect_from_file(path, / Version="([\d.]+)"/)
40
+ when ".yml"
41
+ Makit::Version.detect_from_file(path, /VERSION:\s*["']?([\d.]+)["']?/)
42
+ else
43
+ raise "unrecognized file type"
44
+ end
45
+ end
46
+
47
+ # Detect version using a regex pattern in a specific file
48
+ #
49
+ # @param filename [String] Path to the file to search
50
+ # @param regex [Regexp] Regular expression pattern to match version
51
+ # @return [String, nil] The extracted version or nil if no match found
52
+ # @raise [RuntimeError] If file doesn't exist
53
+ def self.detect_from_file(filename, regex)
54
+ raise "unable to find version in #{filename}" unless File.exist?(filename)
55
+
56
+ match = File.read(filename).match(regex)
57
+ match.captures[0] if !match.nil? && match.captures.length.positive?
58
+ end
59
+
60
+ # Update version number in a file based on its extension
61
+ #
62
+ # Supports updating versions in multiple file formats:
63
+ # - .yml files
64
+ # - .gemspec files
65
+ # - .csproj files
66
+ # - .nuspec files
67
+ # - .wxs files
68
+ # - .toml files
69
+ #
70
+ # @param filename [String] Path to the file to update
71
+ # @param version [String] New version string to set
72
+ # @return [nil]
73
+ def self.set_version_in_file(filename, version)
74
+ text = File.read(filename)
75
+ new_text = text
76
+ new_text = text.gsub(/VERSION:\s?['|"]([.\d]+)['|"]/, "VERSION: \"#{version}\"") if filename.include?(".yml")
77
+ new_text = text.gsub(/version\s?=\s?['|"]([.\d]+)['|"]/, "version='#{version}'") if filename.include?(".gemspec")
78
+ new_text = text.gsub(/<Version>([-\w\d.]+)</, "<Version>#{version}<") if filename.include?(".csproj")
79
+ new_text = text.gsub(/<version>([-\w\d.]+)</, "<version>#{version}<") if filename.include?(".nuspec")
80
+ new_text = text.gsub(/ Version="([\d.]+)"/, " Version=\"#{version}\"") if filename.include?(".wxs")
81
+ new_text = text.gsub(/version\s+=\s+['"]([\w.]+)['"]/, "version=\"#{version}\"") if filename.include?(".toml")
82
+ File.write(filename, new_text) if new_text != text
83
+ end
84
+
85
+ # Update version number in multiple files matching a glob pattern
86
+ #
87
+ # @param glob_pattern [String] Glob pattern to match files (e.g., '**/*.csproj')
88
+ # @param version [String] New version string to set in all matching files
89
+ # @return [nil]
90
+ def self.set_version_in_files(glob_pattern, version)
91
+ Dir.glob(glob_pattern).each do |filename|
92
+ set_version_in_file(filename, version)
93
+ end
94
+ end
95
+ end
96
+ end
data/lib/makit.rb CHANGED
@@ -7,6 +7,7 @@ ENV["LOG_LEVEL"] ||= "info"
7
7
 
8
8
  require_relative "makit/version"
9
9
  require_relative "makit/dotnet"
10
+ require_relative "makit/rake"
10
11
 
11
12
  # Load essential modules for Rakefile
12
13
  require_relative "makit/version_util"
@@ -17,6 +18,7 @@ require_relative "makit/serializer"
17
18
  require_relative "makit/humanize"
18
19
  require_relative "makit/directories"
19
20
  require_relative "makit/files"
21
+ require_relative "makit/task_info"
20
22
  require_relative "makit/tasks"
21
23
  require_relative "makit/environment"
22
24
  require_relative "makit/process"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: makit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.130
4
+ version: 0.0.137
5
5
  platform: ruby
6
6
  authors:
7
7
  - Your Name
@@ -9,6 +9,20 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: childprocess
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '4.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '4.0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: colorize
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -57,14 +71,14 @@ dependencies:
57
71
  requirements:
58
72
  - - "~>"
59
73
  - !ruby/object:Gem::Version
60
- version: '2.6'
74
+ version: '2.4'
61
75
  type: :development
62
76
  prerelease: false
63
77
  version_requirements: !ruby/object:Gem::Requirement
64
78
  requirements:
65
79
  - - "~>"
66
80
  - !ruby/object:Gem::Version
67
- version: '2.6'
81
+ version: '2.4'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: fiddle
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -152,7 +166,8 @@ dependencies:
152
166
  description: A Ruby gem description
153
167
  email:
154
168
  - your.email@example.com
155
- executables: []
169
+ executables:
170
+ - makit
156
171
  extensions: []
157
172
  extra_rdoc_files: []
158
173
  files:
@@ -161,6 +176,7 @@ files:
161
176
  - lib/makit copy.rb
162
177
  - lib/makit.rb
163
178
  - lib/makit/apache.rb
179
+ - lib/makit/auto.rb
164
180
  - lib/makit/cli/build_commands.rb
165
181
  - lib/makit/cli/generators/base_generator.rb
166
182
  - lib/makit/cli/generators/dotnet_generator.rb
@@ -182,6 +198,7 @@ files:
182
198
  - lib/makit/cli/main.rb
183
199
  - lib/makit/cli/project_commands.rb
184
200
  - lib/makit/cli/repository_commands.rb
201
+ - lib/makit/cli/strategy_commands.rb
185
202
  - lib/makit/cli/utility_commands.rb
186
203
  - lib/makit/commands.rb
187
204
  - lib/makit/commands/factory.rb
@@ -193,6 +210,8 @@ files:
193
210
  - lib/makit/commands/result.rb
194
211
  - lib/makit/commands/runner.rb
195
212
  - lib/makit/commands/strategies/base.rb
213
+ - lib/makit/commands/strategies/child_process.rb
214
+ - lib/makit/commands/strategies/factory.rb
196
215
  - lib/makit/commands/strategies/synchronous.rb
197
216
  - lib/makit/configuration.rb
198
217
  - lib/makit/configuration/dotnet_project.rb
@@ -259,6 +278,7 @@ files:
259
278
  - lib/makit/protoc.rb
260
279
  - lib/makit/rake.rb
261
280
  - lib/makit/rake/cli.rb
281
+ - lib/makit/rake/trace_controller.rb
262
282
  - lib/makit/ruby.rb
263
283
  - lib/makit/ruby/cli.rb
264
284
  - lib/makit/secrets.rb
@@ -320,7 +340,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
340
  - !ruby/object:Gem::Version
321
341
  version: '0'
322
342
  requirements: []
323
- rubygems_version: 3.7.0
343
+ rubygems_version: 3.6.9
324
344
  specification_version: 4
325
345
  summary: A Ruby gem
326
346
  test_files: []