makit 0.0.129 → 0.0.135
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/exe/makit +1 -1
- data/lib/makit/auto.rb +47 -0
- data/lib/makit/cli/main.rb +3 -0
- data/lib/makit/cli/strategy_commands.rb +102 -0
- data/lib/makit/commands/middleware/command_logger.rb +2 -1
- data/lib/makit/commands/runner.rb +13 -1
- data/lib/makit/commands/strategies/child_process.rb +165 -0
- data/lib/makit/commands/strategies/factory.rb +135 -0
- data/lib/makit/configuration/dotnet_project.rb +12 -0
- data/lib/makit/configuration/project.rb +1 -0
- data/lib/makit/mp/string_mp.rb +3 -3
- data/lib/makit/setup/classlib.rb +7 -0
- data/lib/makit/setup/gem.rb +9 -9
- data/lib/makit/setup/razorclasslib.rb +36 -26
- data/lib/makit/task_info.rb +4 -2
- data/lib/makit/version.rb +93 -2
- data/lib/makit.rb +1 -0
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04fddef2bfe206d137c1f4181f5ebaad085ecb2e449817c66fb839174d91779b
|
4
|
+
data.tar.gz: e40f4f909e1b073da28702e2ef78d32270ab8e3e8a59b012181d981c2f972b5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16324ca4ea5dffd8083f960783298e9ccb0ba238e919a1ea683f4232d84fdf9d3a01938b4f13ecc992c811c42cad6dfc0d3569d7fbc21aadad7f785c6b9afc36
|
7
|
+
data.tar.gz: 6a52c596632122e783d4df5d4bb2c1ad9e78cd3810c43b90d6d2c3f6569c7e8f36e3105f07cb059ff01ea72be1fc6773da761d5eb2686a3f58a56307db1cfdd9
|
data/exe/makit
CHANGED
data/lib/makit/auto.rb
ADDED
@@ -0,0 +1,47 @@
|
|
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
|
+
rescue LoadError => e
|
20
|
+
puts "Warning: Could not load CLI modules: #{e.message}"
|
21
|
+
end
|
22
|
+
|
23
|
+
module Makit
|
24
|
+
# Auto module provides enhanced functionality when requiring "makit/auto"
|
25
|
+
# This includes CLI commands and other enhanced features
|
26
|
+
module Auto
|
27
|
+
# Version of the auto functionality
|
28
|
+
VERSION = "1.0.0"
|
29
|
+
|
30
|
+
# Check if auto functionality is loaded
|
31
|
+
def self.loaded?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Log that auto mode is enabled
|
36
|
+
def self.enable_auto_mode
|
37
|
+
if defined?(Makit::Logging)
|
38
|
+
Makit::Logging.info("Makit auto mode enabled - enhanced functionality available")
|
39
|
+
else
|
40
|
+
puts "Makit auto mode enabled - enhanced functionality available"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Enable auto mode logging
|
47
|
+
Makit::Auto.enable_auto_mode
|
data/lib/makit/cli/main.rb
CHANGED
@@ -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,7 @@ 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)
|
23
25
|
rake - Manage rake tasks
|
24
26
|
|
25
27
|
Common usage examples:
|
@@ -56,6 +58,7 @@ module Makit
|
|
56
58
|
subcommand "project", "Manage project creation and setup", ProjectCommand
|
57
59
|
subcommand "build", "Build operations and cleanup", BuildCommand
|
58
60
|
subcommand "utility", "System utilities and maintenance", UtilityCommand
|
61
|
+
subcommand "strategy", "Manage execution strategies", StrategyCommands
|
59
62
|
subcommand "rake", "Manage rake tasks", Makit::Rake::CliCommand
|
60
63
|
end
|
61
64
|
end
|
@@ -0,0 +1,102 @@
|
|
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
|
+
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 >
|
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
|
|
@@ -64,7 +65,7 @@ module Makit
|
|
64
65
|
# @param options [Hash] additional configuration
|
65
66
|
def initialize(middleware: nil, strategy: nil, **options)
|
66
67
|
@middleware = Array(middleware || default_middleware)
|
67
|
-
@strategy = strategy || Strategies::
|
68
|
+
@strategy = strategy || Strategies::Factory.create(options)
|
68
69
|
@options = options
|
69
70
|
|
70
71
|
validate_middleware
|
@@ -314,6 +315,17 @@ module Makit
|
|
314
315
|
raise ArgumentError, "Strategy must respond to #supports?: #{@strategy.class}"
|
315
316
|
end
|
316
317
|
|
318
|
+
# Get information about the current strategy
|
319
|
+
#
|
320
|
+
# @return [Hash] strategy information
|
321
|
+
def strategy_info
|
322
|
+
{
|
323
|
+
class: @strategy.class.name,
|
324
|
+
type: @strategy.class.name.split('::').last.downcase,
|
325
|
+
factory_info: Strategies::Factory.strategy_info
|
326
|
+
}
|
327
|
+
end
|
328
|
+
|
317
329
|
# Log command execution result using the default logger.
|
318
330
|
#
|
319
331
|
# @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,135 @@
|
|
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
|
+
case strategy_type
|
40
|
+
when 'childprocess'
|
41
|
+
create_childprocess_strategy(options)
|
42
|
+
when 'open3'
|
43
|
+
create_open3_strategy(options)
|
44
|
+
when 'auto'
|
45
|
+
create_auto_detect_strategy(options)
|
46
|
+
else
|
47
|
+
Makit::Logging.warn("Unknown strategy '#{strategy_type}', falling back to Open3")
|
48
|
+
create_open3_strategy(options)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get the current strategy type from environment or default
|
53
|
+
#
|
54
|
+
# @return [String] strategy type
|
55
|
+
def self.determine_strategy_type
|
56
|
+
env_strategy = ENV['MAKIT_STRATEGY']&.downcase
|
57
|
+
|
58
|
+
if env_strategy && STRATEGIES.key?(env_strategy)
|
59
|
+
env_strategy
|
60
|
+
else
|
61
|
+
'auto' # Default to auto-detect
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Create ChildProcess strategy with fallback
|
66
|
+
#
|
67
|
+
# @param options [Hash] strategy options
|
68
|
+
# @return [Strategies::Base] strategy instance
|
69
|
+
def self.create_childprocess_strategy(options)
|
70
|
+
begin
|
71
|
+
require_relative 'child_process'
|
72
|
+
ChildProcess.new(**options)
|
73
|
+
rescue LoadError, StandardError => e
|
74
|
+
Makit::Logging.warn("Failed to load ChildProcess strategy: #{e.message}")
|
75
|
+
Makit::Logging.info("Falling back to Open3 strategy")
|
76
|
+
create_open3_strategy(options)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Create Open3 strategy
|
81
|
+
#
|
82
|
+
# @param options [Hash] strategy options
|
83
|
+
# @return [Strategies::Base] strategy instance
|
84
|
+
def self.create_open3_strategy(options)
|
85
|
+
Synchronous.new(**options)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Create auto-detect strategy that tries ChildProcess first
|
89
|
+
#
|
90
|
+
# @param options [Hash] strategy options
|
91
|
+
# @return [Strategies::Base] strategy instance
|
92
|
+
def self.create_auto_detect_strategy(options)
|
93
|
+
# For now, always use Open3 until ChildProcess gem is installed
|
94
|
+
Makit::Logging.debug("Using Open3 strategy (ChildProcess not yet installed)")
|
95
|
+
Synchronous.new(**options)
|
96
|
+
|
97
|
+
# TODO: Uncomment this when ChildProcess gem is installed
|
98
|
+
# begin
|
99
|
+
# require_relative 'child_process'
|
100
|
+
# Makit::Logging.debug("Using ChildProcess strategy")
|
101
|
+
# ChildProcess.new(**options)
|
102
|
+
# rescue LoadError, StandardError => e
|
103
|
+
# Makit::Logging.debug("ChildProcess not available: #{e.message}")
|
104
|
+
# Makit::Logging.debug("Using Open3 strategy")
|
105
|
+
# Synchronous.new(**options)
|
106
|
+
# end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get information about available strategies
|
110
|
+
#
|
111
|
+
# @return [Hash] strategy information
|
112
|
+
def self.strategy_info
|
113
|
+
{
|
114
|
+
current: determine_strategy_type,
|
115
|
+
available: STRATEGIES.keys,
|
116
|
+
childprocess_available: childprocess_available?,
|
117
|
+
open3_available: true # Always available
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
# Check if ChildProcess strategy is available
|
122
|
+
#
|
123
|
+
# @return [Boolean] true if ChildProcess can be loaded
|
124
|
+
def self.childprocess_available?
|
125
|
+
begin
|
126
|
+
require 'childprocess'
|
127
|
+
true
|
128
|
+
rescue LoadError
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -7,6 +7,7 @@ module Makit
|
|
7
7
|
# Project configuration management
|
8
8
|
class Project
|
9
9
|
attr_accessor :git_remote_url, :name, :version, :project_type, :steps, :authors, :description, :license_expression
|
10
|
+
attr_accessor :dotnet_projects
|
10
11
|
|
11
12
|
def initialize(name, version = nil, project_type = nil)
|
12
13
|
# Support both keyword arguments and positional arguments for compatibility
|
data/lib/makit/mp/string_mp.rb
CHANGED
@@ -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
|
data/lib/makit/setup/classlib.rb
CHANGED
@@ -9,6 +9,13 @@ module Makit
|
|
9
9
|
# puts "Setting up Nuget project..."
|
10
10
|
project = Makit::Configuration::Project.default
|
11
11
|
|
12
|
+
dotnet_project_directory = "source/#{project.name}"
|
13
|
+
dotnet_project = Makit::Configuration::DotNetProject.new
|
14
|
+
dotnet_project.name = project.name
|
15
|
+
dotnet_project.template = "classlib"
|
16
|
+
dotnet_project.output_dir = dotnet_project_directory
|
17
|
+
dotnet_project.frameworks = ["net8.0", "net8.0-browser"]
|
18
|
+
|
12
19
|
project_filename = "source/#{project.name}/#{project.name}.csproj"
|
13
20
|
if (!File.exist?(project_filename))
|
14
21
|
Makit::DotNet::Project.new_project("classlib", project.name, "source/#{project.name}", "--framework net8.0")
|
data/lib/makit/setup/gem.rb
CHANGED
@@ -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
|
-
|
111
|
+
#version_content = <<~VERSION
|
112
|
+
# # frozen_string_literal: true
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
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)
|
@@ -8,38 +8,48 @@ module Makit
|
|
8
8
|
def self.run
|
9
9
|
# puts "Setting up Nuget project..."
|
10
10
|
project = Makit::Configuration::Project.default
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
11
|
+
|
12
|
+
project_filename = "source/#{project.name}/#{project.name}.csproj"
|
13
|
+
if (!File.exist?(project_filename))
|
14
|
+
Makit::DotNet::Project.new_project("razorclasslib", project.name, "source/#{project.name}",
|
15
|
+
"--framework net8.0")
|
16
|
+
dotnet_project = Makit::DotNet::Project.new("source/#{project.name}/#{project.name}.csproj")
|
17
|
+
# set the version to project.version
|
18
|
+
dotnet_project.set_version(project.version)
|
19
|
+
# set the frameworks = ["net8.0","net8.0-browser"]
|
20
|
+
dotnet_project.set_target_frameworks(["net8.0", "net8.0-browser"])
|
21
|
+
# set the nuget metadata
|
22
|
+
dotnet_project.set_nuget_metadata(project.name, project.authors, project.description,
|
23
|
+
project.license_expression)
|
24
|
+
end
|
25
|
+
|
26
|
+
test_project_filename = "tests/#{project.name}.Tests/#{project.name}.Tests.csproj"
|
27
|
+
if (File.exist?(test_project_filename))
|
28
|
+
Makit::DotNet::Project.new_project("TUnit", "#{project.name}.Tests", "tests/#{project.name}")
|
29
|
+
dotnet_project = Makit::DotNet::Project.new("tests/#{project.name}/#{project.name}.Tests.csproj")
|
30
|
+
# set the version to project.version
|
31
|
+
dotnet_project.set_version(project.version)
|
32
|
+
# set the frameworks = ["net8.0","net8.0-browser"]
|
33
|
+
dotnet_project.set_target_frameworks(["net8.0", "net8.0-browser"])
|
34
|
+
# set the nuget metadata
|
35
|
+
dotnet_project.set_nuget_metadata("#{project.name}.Tests", project.authors, project.description,
|
36
|
+
project.license_expression)
|
37
|
+
Makit::DotNet::Project.add_reference("tests/#{project.name}/#{project.name}.Tests.csproj",
|
38
|
+
"source/#{project.name}/#{project.name}.csproj")
|
39
|
+
end
|
32
40
|
update_build_step(project)
|
33
41
|
update_test_step(project)
|
34
42
|
|
35
43
|
project.save
|
36
44
|
|
37
45
|
# Setup the sln, then slnx
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
if (!File.exist?("#{project.name}.slnx"))
|
47
|
+
Makit::DotNet.new_solution(project.name)
|
48
|
+
Makit::DotNet.sln_add_projects(project.name)
|
49
|
+
# migrate the sln to slnx
|
50
|
+
"dotnet sln migrate #{project.name}.sln".run
|
51
|
+
FileUtils.rm_f("#{project.name}.sln") if File.exist?("#{project.name}.slnx")
|
52
|
+
end
|
43
53
|
Makit::Logging.default_logger.debug("Project setup completed")
|
44
54
|
end
|
45
55
|
|
data/lib/makit/task_info.rb
CHANGED
@@ -50,7 +50,8 @@ module Makit
|
|
50
50
|
# end
|
51
51
|
def self.track(task_name)
|
52
52
|
task = new(task_name)
|
53
|
-
Makit::
|
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::
|
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
|
|
data/lib/makit/version.rb
CHANGED
@@ -1,5 +1,96 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Makit
|
4
|
-
|
5
|
-
|
4
|
+
# Static version for now to avoid circular dependency issues
|
5
|
+
VERSION = "0.0.135"
|
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
@@ -17,6 +17,7 @@ require_relative "makit/serializer"
|
|
17
17
|
require_relative "makit/humanize"
|
18
18
|
require_relative "makit/directories"
|
19
19
|
require_relative "makit/files"
|
20
|
+
require_relative "makit/task_info"
|
20
21
|
require_relative "makit/tasks"
|
21
22
|
require_relative "makit/environment"
|
22
23
|
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.
|
4
|
+
version: 0.0.135
|
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.
|
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.
|
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,8 +210,11 @@ 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
|
217
|
+
- lib/makit/configuration/dotnet_project.rb
|
198
218
|
- lib/makit/configuration/gitlab_helper.rb
|
199
219
|
- lib/makit/configuration/project.rb
|
200
220
|
- lib/makit/configuration/rakefile_helper.rb
|
@@ -319,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
339
|
- !ruby/object:Gem::Version
|
320
340
|
version: '0'
|
321
341
|
requirements: []
|
322
|
-
rubygems_version: 3.
|
342
|
+
rubygems_version: 3.6.9
|
323
343
|
specification_version: 4
|
324
344
|
summary: A Ruby gem
|
325
345
|
test_files: []
|