makit 0.0.99 → 0.0.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +41 -0
- data/exe/makit +5 -0
- data/lib/makit/apache.rb +7 -11
- data/lib/makit/cli/build_commands.rb +500 -0
- data/lib/makit/cli/generators/base_generator.rb +74 -0
- data/lib/makit/cli/generators/dotnet_generator.rb +50 -0
- data/lib/makit/cli/generators/generator_factory.rb +49 -0
- data/lib/makit/cli/generators/node_generator.rb +50 -0
- data/lib/makit/cli/generators/ruby_generator.rb +77 -0
- data/lib/makit/cli/generators/rust_generator.rb +50 -0
- data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -0
- data/lib/makit/cli/generators/templates/node_templates.rb +161 -0
- data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -0
- data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -0
- data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -0
- data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -0
- data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -0
- data/lib/makit/cli/generators/templates/ruby/test.rb +39 -0
- data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -0
- data/lib/makit/cli/generators/templates/ruby/version.rb +29 -0
- data/lib/makit/cli/generators/templates/rust_templates.rb +128 -0
- data/lib/makit/cli/main.rb +48 -19
- data/lib/makit/cli/project_commands.rb +868 -0
- data/lib/makit/cli/repository_commands.rb +661 -0
- data/lib/makit/cli/utility_commands.rb +521 -0
- data/lib/makit/command_runner.rb +187 -128
- data/lib/makit/commands/compatibility.rb +365 -0
- data/lib/makit/commands/factory.rb +359 -0
- data/lib/makit/commands/middleware/base.rb +73 -0
- data/lib/makit/commands/middleware/cache.rb +248 -0
- data/lib/makit/commands/middleware/command_logger.rb +323 -0
- data/lib/makit/commands/middleware/unified_logger.rb +243 -0
- data/lib/makit/commands/middleware/validator.rb +269 -0
- data/lib/makit/commands/request.rb +254 -0
- data/lib/makit/commands/result.rb +323 -0
- data/lib/makit/commands/runner.rb +317 -0
- data/lib/makit/commands/strategies/base.rb +160 -0
- data/lib/makit/commands/strategies/synchronous.rb +134 -0
- data/lib/makit/commands.rb +24 -3
- data/lib/makit/configuration/gitlab_helper.rb +60 -0
- data/lib/makit/configuration/project.rb +127 -0
- data/lib/makit/configuration/rakefile_helper.rb +43 -0
- data/lib/makit/configuration/step.rb +34 -0
- data/lib/makit/configuration.rb +14 -0
- data/lib/makit/content/default_gitignore.rb +4 -2
- data/lib/makit/content/default_rakefile.rb +4 -2
- data/lib/makit/content/gem_rakefile.rb +4 -2
- data/lib/makit/context.rb +1 -0
- data/lib/makit/data.rb +9 -10
- data/lib/makit/directories.rb +48 -52
- data/lib/makit/directory.rb +38 -52
- data/lib/makit/docs/files.rb +5 -10
- data/lib/makit/docs/rake.rb +16 -20
- data/lib/makit/dotnet/cli.rb +65 -0
- data/lib/makit/dotnet/project.rb +153 -0
- data/lib/makit/dotnet/solution.rb +38 -0
- data/lib/makit/dotnet/solution_classlib.rb +239 -0
- data/lib/makit/dotnet/solution_console.rb +264 -0
- data/lib/makit/dotnet/solution_maui.rb +354 -0
- data/lib/makit/dotnet/solution_wasm.rb +275 -0
- data/lib/makit/dotnet/solution_wpf.rb +304 -0
- data/lib/makit/dotnet.rb +54 -171
- data/lib/makit/email.rb +46 -17
- data/lib/makit/environment.rb +22 -19
- data/lib/makit/examples/runner.rb +370 -0
- data/lib/makit/exceptions.rb +45 -0
- data/lib/makit/fileinfo.rb +3 -5
- data/lib/makit/files.rb +12 -16
- data/lib/makit/gems.rb +40 -39
- data/lib/makit/git/cli.rb +54 -0
- data/lib/makit/git/repository.rb +90 -0
- data/lib/makit/git.rb +44 -91
- data/lib/makit/gitlab_runner.rb +0 -1
- data/lib/makit/humanize.rb +31 -23
- data/lib/makit/indexer.rb +15 -24
- data/lib/makit/logging/configuration.rb +305 -0
- data/lib/makit/logging/format_registry.rb +84 -0
- data/lib/makit/logging/formatters/base.rb +39 -0
- data/lib/makit/logging/formatters/console_formatter.rb +127 -0
- data/lib/makit/logging/formatters/json_formatter.rb +65 -0
- data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -0
- data/lib/makit/logging/formatters/text_formatter.rb +64 -0
- data/lib/makit/logging/log_request.rb +115 -0
- data/lib/makit/logging/logger.rb +159 -0
- data/lib/makit/logging/sinks/base.rb +91 -0
- data/lib/makit/logging/sinks/console.rb +72 -0
- data/lib/makit/logging/sinks/file_sink.rb +92 -0
- data/lib/makit/logging/sinks/structured.rb +129 -0
- data/lib/makit/logging/sinks/unified_file_sink.rb +303 -0
- data/lib/makit/logging.rb +452 -37
- data/lib/makit/markdown.rb +18 -18
- data/lib/makit/mp/basic_object_mp.rb +5 -4
- data/lib/makit/mp/command_mp.rb +5 -5
- data/lib/makit/mp/command_request.mp.rb +3 -2
- data/lib/makit/mp/project_mp.rb +85 -96
- data/lib/makit/mp/string_mp.rb +245 -73
- data/lib/makit/nuget.rb +27 -25
- data/lib/makit/port.rb +25 -27
- data/lib/makit/process.rb +127 -29
- data/lib/makit/protoc.rb +27 -24
- data/lib/makit/rake/cli.rb +196 -0
- data/lib/makit/rake.rb +6 -6
- data/lib/makit/ruby/cli.rb +185 -0
- data/lib/makit/ruby.rb +25 -0
- data/lib/makit/secrets.rb +18 -18
- data/lib/makit/serializer.rb +29 -27
- data/lib/makit/services/builder.rb +186 -0
- data/lib/makit/services/error_handler.rb +226 -0
- data/lib/makit/services/repository_manager.rb +229 -0
- data/lib/makit/services/validator.rb +112 -0
- data/lib/makit/setup/classlib.rb +53 -0
- data/lib/makit/setup/gem.rb +250 -0
- data/lib/makit/setup/runner.rb +40 -0
- data/lib/makit/show.rb +16 -16
- data/lib/makit/storage.rb +32 -37
- data/lib/makit/symbols.rb +12 -0
- data/lib/makit/task_hooks.rb +125 -0
- data/lib/makit/task_info.rb +63 -21
- data/lib/makit/tasks/at_exit.rb +13 -0
- data/lib/makit/tasks/build.rb +18 -0
- data/lib/makit/tasks/clean.rb +11 -0
- data/lib/makit/tasks/hook_manager.rb +239 -0
- data/lib/makit/tasks/init.rb +47 -0
- data/lib/makit/tasks/integrate.rb +15 -0
- data/lib/makit/tasks/pull_incoming.rb +12 -0
- data/lib/makit/tasks/setup.rb +6 -0
- data/lib/makit/tasks/sync.rb +11 -0
- data/lib/makit/tasks/task_monkey_patch.rb +79 -0
- data/lib/makit/tasks.rb +5 -150
- data/lib/makit/test_cache.rb +239 -0
- data/lib/makit/v1/makit.v1_pb.rb +34 -35
- data/lib/makit/v1/makit.v1_services_pb.rb +2 -0
- data/lib/makit/version.rb +1 -57
- data/lib/makit/wix.rb +23 -23
- data/lib/makit/yaml.rb +18 -6
- data/lib/makit.rb +2 -261
- metadata +109 -145
- data/lib/makit/cli/clean.rb +0 -14
- data/lib/makit/cli/clone.rb +0 -59
- data/lib/makit/cli/init.rb +0 -38
- data/lib/makit/cli/make.rb +0 -54
- data/lib/makit/cli/new.rb +0 -37
- data/lib/makit/cli/nuget_cache.rb +0 -38
- data/lib/makit/cli/pull.rb +0 -31
- data/lib/makit/cli/setup.rb +0 -71
- data/lib/makit/cli/work.rb +0 -21
- data/lib/makit/content/default_gitignore.txt +0 -222
@@ -0,0 +1,521 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
require "clamp"
|
5
|
+
require "fileutils"
|
6
|
+
|
7
|
+
module Makit
|
8
|
+
module Cli
|
9
|
+
# Consolidated utility commands
|
10
|
+
# Combines: nuget_cache and other utility functionality
|
11
|
+
class UtilityCommand < Clamp::Command
|
12
|
+
self.description = <<~DESC
|
13
|
+
Utility commands for system maintenance and development tools.
|
14
|
+
|
15
|
+
Available operations:
|
16
|
+
nuget-cache - Manage NuGet package cache
|
17
|
+
system-info - Display system and environment information
|
18
|
+
DESC
|
19
|
+
end
|
20
|
+
|
21
|
+
# Manage NuGet package cache
|
22
|
+
class NugetCacheCommand < Clamp::Command
|
23
|
+
self.description = <<~DESC
|
24
|
+
Manage NuGet package cache and troubleshoot package issues.
|
25
|
+
|
26
|
+
Examples:
|
27
|
+
makit utility nuget-cache --clear
|
28
|
+
makit utility nuget-cache --list
|
29
|
+
makit utility nuget-cache --verify
|
30
|
+
DESC
|
31
|
+
|
32
|
+
option ["--clear"], :flag, "Clear all NuGet caches"
|
33
|
+
option ["--list"], :flag, "List NuGet cache locations"
|
34
|
+
option ["--verify"], :flag, "Verify cache integrity"
|
35
|
+
option ["--cache-type"], "TYPE", "Specific cache to target (global-packages, http-cache, temp, plugins-cache)"
|
36
|
+
option ["--dry-run"], :flag, "Show what would be done without actually doing it"
|
37
|
+
option ["--verbose"], :flag, "Show verbose output"
|
38
|
+
|
39
|
+
def execute
|
40
|
+
unless nuget_available?
|
41
|
+
puts "Error: NuGet CLI is not available. Please install .NET SDK or NuGet CLI tools."
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
if list?
|
46
|
+
list_cache_locations
|
47
|
+
elsif verify?
|
48
|
+
verify_cache_integrity
|
49
|
+
elsif clear?
|
50
|
+
clear_nuget_caches
|
51
|
+
else
|
52
|
+
show_cache_status
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def nuget_available?
|
59
|
+
system("dotnet --version > /dev/null 2>&1") || system("nuget help > /dev/null 2>&1")
|
60
|
+
end
|
61
|
+
|
62
|
+
def show_cache_status
|
63
|
+
puts "NuGet Cache Status:"
|
64
|
+
puts "=" * 50
|
65
|
+
|
66
|
+
cache_locations = get_cache_locations
|
67
|
+
cache_locations.each do |name, path|
|
68
|
+
if Dir.exist?(path)
|
69
|
+
size = calculate_directory_size(path)
|
70
|
+
puts "✅ #{name.ljust(20)} #{path} (#{format_size(size)})"
|
71
|
+
else
|
72
|
+
puts "❌ #{name.ljust(20)} #{path} (not found)"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
puts "\nUse --clear to clear all caches, or --list for detailed information."
|
77
|
+
end
|
78
|
+
|
79
|
+
def list_cache_locations
|
80
|
+
puts "NuGet Cache Locations:"
|
81
|
+
puts "=" * 50
|
82
|
+
|
83
|
+
cache_locations = get_cache_locations
|
84
|
+
cache_locations.each do |name, path|
|
85
|
+
puts "\n#{name}:"
|
86
|
+
puts " Path: #{path}"
|
87
|
+
|
88
|
+
if Dir.exist?(path)
|
89
|
+
size = calculate_directory_size(path)
|
90
|
+
file_count = count_files_in_directory(path)
|
91
|
+
puts " Status: ✅ Exists"
|
92
|
+
puts " Size: #{format_size(size)}"
|
93
|
+
puts " Files: #{file_count}"
|
94
|
+
|
95
|
+
if verbose?
|
96
|
+
recent_files = find_recent_files(path, 5)
|
97
|
+
if recent_files.any?
|
98
|
+
puts " Recent files:"
|
99
|
+
recent_files.each { |file| puts " - #{File.basename(file)}" }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
else
|
103
|
+
puts " Status: ❌ Not found"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def verify_cache_integrity
|
109
|
+
puts "Verifying NuGet cache integrity..."
|
110
|
+
|
111
|
+
if system("dotnet --version > /dev/null 2>&1")
|
112
|
+
puts " Running: dotnet nuget verify"
|
113
|
+
success = system("dotnet nuget verify")
|
114
|
+
|
115
|
+
if success
|
116
|
+
puts "✅ Cache verification completed successfully"
|
117
|
+
else
|
118
|
+
puts "❌ Cache verification found issues"
|
119
|
+
puts "Consider clearing the cache with --clear"
|
120
|
+
end
|
121
|
+
else
|
122
|
+
puts "Manual verification of cache locations..."
|
123
|
+
cache_locations = get_cache_locations
|
124
|
+
|
125
|
+
cache_locations.each do |name, path|
|
126
|
+
next unless Dir.exist?(path)
|
127
|
+
|
128
|
+
puts " Checking #{name}..."
|
129
|
+
|
130
|
+
# Basic checks for common corruption indicators
|
131
|
+
corrupt_files = find_corrupt_files(path)
|
132
|
+
if corrupt_files.any?
|
133
|
+
puts " ⚠️ Found #{corrupt_files.length} potentially corrupt files"
|
134
|
+
corrupt_files.first(3).each { |file| puts " - #{file}" }
|
135
|
+
puts " ... and #{corrupt_files.length - 3} more" if corrupt_files.length > 3
|
136
|
+
else
|
137
|
+
puts " ✅ No obvious corruption detected"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def clear_nuget_caches
|
144
|
+
if dry_run?
|
145
|
+
puts "DRY RUN: Would clear the following NuGet caches:"
|
146
|
+
else
|
147
|
+
puts "Clearing NuGet caches..."
|
148
|
+
end
|
149
|
+
|
150
|
+
if cache_type
|
151
|
+
clear_specific_cache(cache_type)
|
152
|
+
else
|
153
|
+
clear_all_caches
|
154
|
+
end
|
155
|
+
|
156
|
+
if dry_run?
|
157
|
+
puts "✅ Dry run completed - no caches were actually cleared"
|
158
|
+
else
|
159
|
+
puts "✅ NuGet caches cleared successfully"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def clear_specific_cache(type)
|
164
|
+
cache_locations = get_cache_locations
|
165
|
+
path = cache_locations[type]
|
166
|
+
|
167
|
+
if path.nil?
|
168
|
+
puts "Error: Unknown cache type '#{type}'"
|
169
|
+
puts "Valid types: #{cache_locations.keys.join(", ")}"
|
170
|
+
exit 1
|
171
|
+
end
|
172
|
+
|
173
|
+
clear_cache_directory(type, path)
|
174
|
+
end
|
175
|
+
|
176
|
+
def clear_all_caches
|
177
|
+
# Try using dotnet CLI first
|
178
|
+
if system("dotnet --version > /dev/null 2>&1") && !cache_type
|
179
|
+
puts " Using dotnet nuget locals --clear all" if verbose?
|
180
|
+
|
181
|
+
if dry_run?
|
182
|
+
puts " Would run: dotnet nuget locals --clear all"
|
183
|
+
else
|
184
|
+
success = system("dotnet nuget locals --clear all")
|
185
|
+
if success
|
186
|
+
puts " ✅ Cleared all caches using dotnet CLI"
|
187
|
+
return
|
188
|
+
else
|
189
|
+
puts " ⚠️ dotnet command failed, falling back to manual cleanup"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Manual cleanup
|
195
|
+
cache_locations = get_cache_locations
|
196
|
+
cache_locations.each do |name, path|
|
197
|
+
clear_cache_directory(name, path)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def clear_cache_directory(name, path)
|
202
|
+
if Dir.exist?(path)
|
203
|
+
size_before = calculate_directory_size(path)
|
204
|
+
|
205
|
+
if dry_run?
|
206
|
+
puts " Would clear #{name}: #{path} (#{format_size(size_before)})"
|
207
|
+
else
|
208
|
+
puts " Clearing #{name}: #{path} (#{format_size(size_before)})" if verbose?
|
209
|
+
|
210
|
+
begin
|
211
|
+
FileUtils.rm_rf(path)
|
212
|
+
FileUtils.mkdir_p(path) # Recreate the directory
|
213
|
+
puts " ✅ Cleared #{name}" if verbose?
|
214
|
+
rescue StandardError => e
|
215
|
+
puts " ❌ Failed to clear #{name}: #{e.message}"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
elsif verbose?
|
219
|
+
puts " #{name} not found: #{path}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def get_cache_locations
|
224
|
+
# Standard NuGet cache locations
|
225
|
+
home = Dir.home
|
226
|
+
|
227
|
+
locations = {
|
228
|
+
"global-packages" => File.join(home, ".nuget", "packages"),
|
229
|
+
"http-cache" => File.join(home, ".nuget", "v3-cache"),
|
230
|
+
"temp" => File.join(home, ".nuget", "temp"),
|
231
|
+
"plugins-cache" => File.join(home, ".nuget", "plugins-cache"),
|
232
|
+
}
|
233
|
+
|
234
|
+
# Add Windows-specific locations if on Windows
|
235
|
+
if Gem.win_platform?
|
236
|
+
ENV["APPDATA"] || File.join(home, "AppData", "Roaming")
|
237
|
+
local_app_data = ENV["LOCALAPPDATA"] || File.join(home, "AppData", "Local")
|
238
|
+
|
239
|
+
locations["http-cache"] = File.join(local_app_data, "NuGet", "v3-cache")
|
240
|
+
locations["plugins-cache"] = File.join(local_app_data, "NuGet", "plugins-cache")
|
241
|
+
end
|
242
|
+
|
243
|
+
locations
|
244
|
+
end
|
245
|
+
|
246
|
+
def calculate_directory_size(path)
|
247
|
+
return 0 unless Dir.exist?(path)
|
248
|
+
|
249
|
+
total_size = 0
|
250
|
+
Dir.glob(File.join(path, "**", "*")).each do |file|
|
251
|
+
total_size += File.size(file) if File.file?(file)
|
252
|
+
end
|
253
|
+
total_size
|
254
|
+
end
|
255
|
+
|
256
|
+
def count_files_in_directory(path)
|
257
|
+
return 0 unless Dir.exist?(path)
|
258
|
+
|
259
|
+
Dir.glob(File.join(path, "**", "*")).count { |f| File.file?(f) }
|
260
|
+
end
|
261
|
+
|
262
|
+
def format_size(bytes)
|
263
|
+
units = %w[B KB MB GB TB]
|
264
|
+
size = bytes.to_f
|
265
|
+
unit_index = 0
|
266
|
+
|
267
|
+
while size >= 1024 && unit_index < units.length - 1
|
268
|
+
size /= 1024.0
|
269
|
+
unit_index += 1
|
270
|
+
end
|
271
|
+
|
272
|
+
format("%.1f %s", size, units[unit_index])
|
273
|
+
end
|
274
|
+
|
275
|
+
def find_recent_files(path, limit)
|
276
|
+
return [] unless Dir.exist?(path)
|
277
|
+
|
278
|
+
Dir.glob(File.join(path, "**", "*"))
|
279
|
+
.select { |f| File.file?(f) }
|
280
|
+
.sort_by { |f| File.mtime(f) }
|
281
|
+
.reverse
|
282
|
+
.first(limit)
|
283
|
+
end
|
284
|
+
|
285
|
+
def find_corrupt_files(path)
|
286
|
+
return [] unless Dir.exist?(path)
|
287
|
+
|
288
|
+
corrupt_files = []
|
289
|
+
|
290
|
+
Dir.glob(File.join(path, "**", "*")).each do |file|
|
291
|
+
next unless File.file?(file)
|
292
|
+
|
293
|
+
# Check for zero-byte files that shouldn't be empty
|
294
|
+
corrupt_files << file if File.empty?(file) && File.extname(file) =~ /\.(dll|exe|nupkg)$/
|
295
|
+
|
296
|
+
# Check for incomplete downloads (common with network issues)
|
297
|
+
corrupt_files << file if File.basename(file) =~ /\.tmp$/ || File.basename(file) =~ /\.partial$/
|
298
|
+
end
|
299
|
+
|
300
|
+
corrupt_files
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Display system and environment information
|
305
|
+
class SystemInfoCommand < Clamp::Command
|
306
|
+
self.description = <<~DESC
|
307
|
+
Display system information, environment details, and development tool versions.
|
308
|
+
|
309
|
+
Examples:
|
310
|
+
makit utility system-info
|
311
|
+
makit utility system-info --tools-only
|
312
|
+
makit utility system-info --export
|
313
|
+
DESC
|
314
|
+
|
315
|
+
option ["--tools-only"], :flag, "Show only development tool versions"
|
316
|
+
option ["--export"], :flag, "Export information to system-info.txt"
|
317
|
+
option ["--verbose"], :flag, "Show detailed information"
|
318
|
+
|
319
|
+
def execute
|
320
|
+
info = collect_system_info
|
321
|
+
|
322
|
+
if export?
|
323
|
+
export_system_info(info)
|
324
|
+
else
|
325
|
+
display_system_info(info)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
private
|
330
|
+
|
331
|
+
def collect_system_info
|
332
|
+
info = {}
|
333
|
+
|
334
|
+
unless tools_only?
|
335
|
+
info[:system] = collect_system_details
|
336
|
+
info[:ruby] = collect_ruby_info
|
337
|
+
end
|
338
|
+
|
339
|
+
info[:tools] = collect_development_tools
|
340
|
+
|
341
|
+
info
|
342
|
+
end
|
343
|
+
|
344
|
+
def collect_system_details
|
345
|
+
{
|
346
|
+
os: RbConfig::CONFIG["host_os"],
|
347
|
+
arch: RbConfig::CONFIG["host_cpu"],
|
348
|
+
user: ENV["USER"] || ENV.fetch("USERNAME", nil),
|
349
|
+
shell: ENV["SHELL"] || "Unknown",
|
350
|
+
pwd: Dir.pwd,
|
351
|
+
home: Dir.home,
|
352
|
+
}
|
353
|
+
end
|
354
|
+
|
355
|
+
def collect_ruby_info
|
356
|
+
{
|
357
|
+
version: RUBY_VERSION,
|
358
|
+
patchlevel: RUBY_PATCHLEVEL,
|
359
|
+
platform: RUBY_PLATFORM,
|
360
|
+
engine: RUBY_ENGINE,
|
361
|
+
gem_version: Gem::VERSION,
|
362
|
+
bundler_version: get_command_version("bundle --version"),
|
363
|
+
}
|
364
|
+
end
|
365
|
+
|
366
|
+
def collect_development_tools
|
367
|
+
tools = {}
|
368
|
+
|
369
|
+
# Version control
|
370
|
+
tools[:git] = get_command_version("git --version")
|
371
|
+
|
372
|
+
# Package managers
|
373
|
+
tools[:npm] = get_command_version("npm --version")
|
374
|
+
tools[:yarn] = get_command_version("yarn --version")
|
375
|
+
tools[:pip] = get_command_version("pip --version")
|
376
|
+
|
377
|
+
# Runtime environments
|
378
|
+
tools[:node] = get_command_version("node --version")
|
379
|
+
tools[:python] = get_command_version("python --version")
|
380
|
+
tools[:python3] = get_command_version("python3 --version")
|
381
|
+
|
382
|
+
# Build tools
|
383
|
+
tools[:make] = get_command_version("make --version")
|
384
|
+
tools[:cmake] = get_command_version("cmake --version")
|
385
|
+
|
386
|
+
# Language-specific tools
|
387
|
+
tools[:dotnet] = get_command_version("dotnet --version")
|
388
|
+
tools[:nuget] = get_command_version("nuget help") # Different format
|
389
|
+
tools[:cargo] = get_command_version("cargo --version")
|
390
|
+
tools[:rustc] = get_command_version("rustc --version")
|
391
|
+
tools[:go] = get_command_version("go version")
|
392
|
+
tools[:java] = get_command_version("java -version")
|
393
|
+
tools[:javac] = get_command_version("javac -version")
|
394
|
+
|
395
|
+
# Editors (just check availability)
|
396
|
+
tools[:code] = command_available?("code --version") ? "Available" : nil
|
397
|
+
tools[:subl] = command_available?("subl --version") ? "Available" : nil
|
398
|
+
tools[:vim] = get_command_version("vim --version")
|
399
|
+
tools[:emacs] = get_command_version("emacs --version")
|
400
|
+
|
401
|
+
# Container tools
|
402
|
+
tools[:docker] = get_command_version("docker --version")
|
403
|
+
tools[:podman] = get_command_version("podman --version")
|
404
|
+
|
405
|
+
tools.compact
|
406
|
+
end
|
407
|
+
|
408
|
+
def get_command_version(command)
|
409
|
+
output = `#{command} 2>&1`.strip
|
410
|
+
return nil if $CHILD_STATUS.exitstatus != 0
|
411
|
+
|
412
|
+
# Extract version number from output
|
413
|
+
version_match = output.match(/(?:v)?(\d+\.[\d.]+(?:-[\w.]+)?)/)
|
414
|
+
version_match ? version_match[1] : output.split("\n").first
|
415
|
+
rescue StandardError
|
416
|
+
nil
|
417
|
+
end
|
418
|
+
|
419
|
+
def command_available?(command)
|
420
|
+
system("#{command} > /dev/null 2>&1")
|
421
|
+
end
|
422
|
+
|
423
|
+
def display_system_info(info)
|
424
|
+
unless tools_only?
|
425
|
+
display_system_section(info[:system])
|
426
|
+
display_ruby_section(info[:ruby])
|
427
|
+
end
|
428
|
+
|
429
|
+
display_tools_section(info[:tools])
|
430
|
+
end
|
431
|
+
|
432
|
+
def display_system_section(system_info)
|
433
|
+
puts "System Information:"
|
434
|
+
puts "=" * 50
|
435
|
+
puts "OS: #{system_info[:os]}"
|
436
|
+
puts "Architecture: #{system_info[:arch]}"
|
437
|
+
puts "User: #{system_info[:user]}"
|
438
|
+
puts "Shell: #{system_info[:shell]}" if system_info[:shell] != "Unknown"
|
439
|
+
puts "Working Directory: #{system_info[:pwd]}"
|
440
|
+
puts "Home Directory: #{system_info[:home]}"
|
441
|
+
puts
|
442
|
+
end
|
443
|
+
|
444
|
+
def display_ruby_section(ruby_info)
|
445
|
+
puts "Ruby Environment:"
|
446
|
+
puts "=" * 50
|
447
|
+
puts "Ruby Version: #{ruby_info[:version]} (patchlevel #{ruby_info[:patchlevel]})"
|
448
|
+
puts "Platform: #{ruby_info[:platform]}"
|
449
|
+
puts "Engine: #{ruby_info[:engine]}"
|
450
|
+
puts "RubyGems Version: #{ruby_info[:gem_version]}"
|
451
|
+
puts "Bundler Version: #{ruby_info[:bundler_version]}" if ruby_info[:bundler_version]
|
452
|
+
puts
|
453
|
+
end
|
454
|
+
|
455
|
+
def display_tools_section(tools_info)
|
456
|
+
puts "Development Tools:"
|
457
|
+
puts "=" * 50
|
458
|
+
|
459
|
+
categories = {
|
460
|
+
"Version Control" => [:git],
|
461
|
+
"Package Managers" => %i[npm yarn pip],
|
462
|
+
"Runtime Environments" => %i[node python python3 dotnet java],
|
463
|
+
"Build Tools" => %i[make cmake cargo rustc go javac],
|
464
|
+
"Editors" => %i[code subl vim emacs],
|
465
|
+
"Container Tools" => %i[docker podman],
|
466
|
+
}
|
467
|
+
|
468
|
+
categories.each do |category, tool_keys|
|
469
|
+
category_tools = tool_keys.map { |key| [key, tools_info[key]] }.select { |_, version| version }
|
470
|
+
|
471
|
+
next if category_tools.empty?
|
472
|
+
|
473
|
+
puts "#{category}:"
|
474
|
+
category_tools.each do |tool, version|
|
475
|
+
puts " #{tool.to_s.ljust(15)} #{version}"
|
476
|
+
end
|
477
|
+
puts
|
478
|
+
end
|
479
|
+
|
480
|
+
# Show any remaining tools not categorized
|
481
|
+
remaining_tools = tools_info.except(*categories.values.flatten)
|
482
|
+
return unless remaining_tools.any?
|
483
|
+
|
484
|
+
puts "Other Tools:"
|
485
|
+
remaining_tools.each do |tool, version|
|
486
|
+
puts " #{tool.to_s.ljust(15)} #{version}"
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
def export_system_info(info)
|
491
|
+
filename = "system-info.txt"
|
492
|
+
|
493
|
+
File.open(filename, "w") do |file|
|
494
|
+
file.puts "System Information Export"
|
495
|
+
file.puts "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
|
496
|
+
file.puts "=" * 60
|
497
|
+
file.puts
|
498
|
+
|
499
|
+
unless tools_only?
|
500
|
+
file.puts "SYSTEM DETAILS:"
|
501
|
+
info[:system].each { |key, value| file.puts "#{key}: #{value}" }
|
502
|
+
file.puts
|
503
|
+
|
504
|
+
file.puts "RUBY ENVIRONMENT:"
|
505
|
+
info[:ruby].each { |key, value| file.puts "#{key}: #{value}" }
|
506
|
+
file.puts
|
507
|
+
end
|
508
|
+
|
509
|
+
file.puts "DEVELOPMENT TOOLS:"
|
510
|
+
info[:tools].each { |tool, version| file.puts "#{tool}: #{version}" }
|
511
|
+
end
|
512
|
+
|
513
|
+
puts "✅ System information exported to: #{filename}"
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
# Add subcommand declarations after all classes are defined
|
518
|
+
UtilityCommand.subcommand "nuget-cache", "Manage NuGet package cache", NugetCacheCommand
|
519
|
+
UtilityCommand.subcommand "system-info", "Display system information", SystemInfoCommand
|
520
|
+
end
|
521
|
+
end
|