makit 0.0.140 → 0.0.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +41 -41
- data/exe/makit +5 -5
- data/lib/makit/apache.rb +28 -28
- data/lib/makit/auto.rb +48 -48
- data/lib/makit/cli/build_commands.rb +500 -500
- data/lib/makit/cli/generators/base_generator.rb +74 -74
- data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
- data/lib/makit/cli/generators/generator_factory.rb +49 -49
- data/lib/makit/cli/generators/node_generator.rb +50 -50
- data/lib/makit/cli/generators/ruby_generator.rb +77 -77
- data/lib/makit/cli/generators/rust_generator.rb +50 -50
- data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
- data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
- data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
- data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -40
- data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
- data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
- data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
- data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
- data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
- data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
- data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
- data/lib/makit/cli/main.rb +69 -69
- data/lib/makit/cli/project_commands.rb +868 -868
- data/lib/makit/cli/repository_commands.rb +661 -661
- data/lib/makit/cli/strategy_commands.rb +203 -203
- data/lib/makit/cli/utility_commands.rb +521 -521
- data/lib/makit/commands/factory.rb +359 -359
- data/lib/makit/commands/middleware/base.rb +73 -73
- data/lib/makit/commands/middleware/cache.rb +248 -248
- data/lib/makit/commands/middleware/command_logger.rb +312 -312
- data/lib/makit/commands/middleware/validator.rb +269 -269
- data/lib/makit/commands/request.rb +316 -316
- data/lib/makit/commands/result.rb +323 -323
- data/lib/makit/commands/runner.rb +388 -385
- data/lib/makit/commands/strategies/base.rb +171 -171
- data/lib/makit/commands/strategies/child_process.rb +165 -165
- data/lib/makit/commands/strategies/factory.rb +136 -136
- data/lib/makit/commands/strategies/synchronous.rb +139 -139
- data/lib/makit/commands.rb +50 -50
- data/lib/makit/configuration/dotnet_project.rb +12 -12
- data/lib/makit/configuration/gitlab_helper.rb +58 -58
- data/lib/makit/configuration/project.rb +168 -168
- data/lib/makit/configuration/rakefile_helper.rb +43 -43
- data/lib/makit/configuration/step.rb +34 -34
- data/lib/makit/configuration/timeout.rb +74 -74
- data/lib/makit/configuration.rb +15 -15
- data/lib/makit/content/default_gitignore.rb +7 -7
- data/lib/makit/content/default_gitignore.txt +225 -225
- data/lib/makit/content/default_rakefile.rb +13 -13
- data/lib/makit/content/gem_rakefile.rb +16 -16
- data/lib/makit/context.rb +1 -1
- data/lib/makit/data.rb +49 -49
- data/lib/makit/directories.rb +140 -140
- data/lib/makit/directory.rb +262 -262
- data/lib/makit/docs/files.rb +89 -89
- data/lib/makit/docs/rake.rb +102 -102
- data/lib/makit/dotnet/cli.rb +69 -69
- data/lib/makit/dotnet/project.rb +217 -217
- data/lib/makit/dotnet/solution.rb +38 -38
- data/lib/makit/dotnet/solution_classlib.rb +239 -239
- data/lib/makit/dotnet/solution_console.rb +264 -264
- data/lib/makit/dotnet/solution_maui.rb +354 -354
- data/lib/makit/dotnet/solution_wasm.rb +275 -275
- data/lib/makit/dotnet/solution_wpf.rb +304 -304
- data/lib/makit/dotnet.rb +102 -102
- data/lib/makit/email.rb +90 -90
- data/lib/makit/environment.rb +142 -142
- data/lib/makit/examples/runner.rb +370 -370
- data/lib/makit/exceptions.rb +45 -45
- data/lib/makit/fileinfo.rb +24 -24
- data/lib/makit/files.rb +43 -43
- data/lib/makit/gems.rb +40 -40
- data/lib/makit/git/cli.rb +54 -54
- data/lib/makit/git/repository.rb +90 -90
- data/lib/makit/git.rb +98 -98
- data/lib/makit/gitlab_runner.rb +59 -59
- data/lib/makit/humanize.rb +137 -137
- data/lib/makit/indexer.rb +47 -47
- data/lib/makit/logging/configuration.rb +308 -308
- data/lib/makit/logging/format_registry.rb +84 -84
- data/lib/makit/logging/formatters/base.rb +39 -39
- data/lib/makit/logging/formatters/console_formatter.rb +140 -140
- data/lib/makit/logging/formatters/json_formatter.rb +65 -65
- data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
- data/lib/makit/logging/formatters/text_formatter.rb +64 -64
- data/lib/makit/logging/log_request.rb +119 -119
- data/lib/makit/logging/logger.rb +199 -199
- data/lib/makit/logging/sinks/base.rb +91 -91
- data/lib/makit/logging/sinks/console.rb +72 -72
- data/lib/makit/logging/sinks/file_sink.rb +92 -92
- data/lib/makit/logging/sinks/structured.rb +123 -123
- data/lib/makit/logging/sinks/unified_file_sink.rb +296 -296
- data/lib/makit/logging.rb +565 -565
- data/lib/makit/markdown.rb +75 -75
- data/lib/makit/mp/basic_object_mp.rb +17 -17
- data/lib/makit/mp/command_mp.rb +13 -13
- data/lib/makit/mp/command_request.mp.rb +17 -17
- data/lib/makit/mp/project_mp.rb +199 -199
- data/lib/makit/mp/string_mp.rb +199 -191
- data/lib/makit/nuget.rb +74 -74
- data/lib/makit/port.rb +32 -32
- data/lib/makit/process.rb +163 -163
- data/lib/makit/protoc.rb +107 -107
- data/lib/makit/rake/cli.rb +196 -196
- data/lib/makit/rake/trace_controller.rb +173 -173
- data/lib/makit/rake.rb +80 -80
- data/lib/makit/ruby/cli.rb +185 -185
- data/lib/makit/ruby.rb +25 -25
- data/lib/makit/secrets.rb +51 -51
- data/lib/makit/serializer.rb +130 -130
- data/lib/makit/services/builder.rb +186 -186
- data/lib/makit/services/error_handler.rb +226 -226
- data/lib/makit/services/repository_manager.rb +231 -231
- data/lib/makit/services/validator.rb +112 -112
- data/lib/makit/setup/classlib.rb +101 -101
- data/lib/makit/setup/gem.rb +268 -268
- data/lib/makit/setup/razorclasslib.rb +101 -101
- data/lib/makit/setup/runner.rb +54 -54
- data/lib/makit/setup.rb +5 -5
- data/lib/makit/show.rb +110 -110
- data/lib/makit/storage.rb +126 -126
- data/lib/makit/symbols.rb +170 -170
- data/lib/makit/task_info.rb +130 -130
- data/lib/makit/tasks/at_exit.rb +15 -15
- data/lib/makit/tasks/build.rb +22 -22
- data/lib/makit/tasks/clean.rb +13 -13
- data/lib/makit/tasks/configure.rb +10 -10
- data/lib/makit/tasks/format.rb +10 -10
- data/lib/makit/tasks/hook_manager.rb +443 -443
- data/lib/makit/tasks/init.rb +49 -49
- data/lib/makit/tasks/integrate.rb +29 -29
- data/lib/makit/tasks/pull_incoming.rb +13 -13
- data/lib/makit/tasks/setup.rb +13 -13
- data/lib/makit/tasks/sync.rb +17 -17
- data/lib/makit/tasks/tag.rb +16 -16
- data/lib/makit/tasks/task_monkey_patch.rb +81 -81
- data/lib/makit/tasks/test.rb +22 -22
- data/lib/makit/tasks/update.rb +18 -18
- data/lib/makit/tasks.rb +20 -20
- data/lib/makit/test_cache.rb +239 -239
- data/lib/makit/tree.rb +37 -37
- data/lib/makit/v1/makit.v1_pb.rb +35 -35
- data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
- data/lib/makit/version.rb +99 -99
- data/lib/makit/version_util.rb +21 -21
- data/lib/makit/wix.rb +95 -95
- data/lib/makit/yaml.rb +29 -29
- data/lib/makit/zip.rb +17 -17
- data/lib/makit copy.rb +44 -44
- data/lib/makit.rb +42 -42
- metadata +2 -2
@@ -1,500 +1,500 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "clamp"
|
4
|
-
require "fileutils"
|
5
|
-
require "json"
|
6
|
-
|
7
|
-
module Makit
|
8
|
-
module Cli
|
9
|
-
# Consolidated build operations commands
|
10
|
-
# Combines: make, clean functionality
|
11
|
-
class BuildCommand < Clamp::Command
|
12
|
-
self.description = <<~DESC
|
13
|
-
Manage project build operations and artifact cleanup.
|
14
|
-
|
15
|
-
Available operations:
|
16
|
-
make - Build project and generate artifacts
|
17
|
-
clean - Clean build artifacts and temporary files
|
18
|
-
DESC
|
19
|
-
end
|
20
|
-
|
21
|
-
# Build project artifacts
|
22
|
-
class MakeBuildCommand < Clamp::Command
|
23
|
-
self.description = <<~DESC
|
24
|
-
Build project artifacts and execute build tasks.
|
25
|
-
|
26
|
-
When called without arguments, enumerates all tracked repositories
|
27
|
-
and displays their latest commit IDs.
|
28
|
-
|
29
|
-
Examples:
|
30
|
-
makit build make # Show all repositories and latest commits
|
31
|
-
makit build make https://github.com/user/repo # Build specific repository
|
32
|
-
makit build make --target release # Build current project with release target
|
33
|
-
makit build make --parallel # Build with parallel execution
|
34
|
-
DESC
|
35
|
-
|
36
|
-
parameter "[REPOSITORY_URL]", "Git repository URL to build (optional)", attribute_name: :repository_url,
|
37
|
-
required: false
|
38
|
-
option ["--commit"], "COMMIT", "Specific commit to build (default: latest)", default: "latest"
|
39
|
-
option ["--target"], "TARGET", "Build target (debug, release)", default: "debug"
|
40
|
-
option ["--parallel", "-j"], :flag, "Enable parallel build"
|
41
|
-
option ["--verbose", "-v"], :flag, "Show verbose build output"
|
42
|
-
option ["--clean"], :flag, "Clean before building"
|
43
|
-
option ["--force"], :flag, "Force rebuild even if cached result exists"
|
44
|
-
|
45
|
-
def execute
|
46
|
-
if repository_url
|
47
|
-
# Build specific repository
|
48
|
-
build_repository(repository_url)
|
49
|
-
else
|
50
|
-
# No arguments - enumerate all tracked repositories and show latest commits
|
51
|
-
enumerate_repositories
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def enumerate_repositories
|
58
|
-
puts "Enumerating all tracked repositories and their latest commit IDs..."
|
59
|
-
puts "=" * 80
|
60
|
-
|
61
|
-
repositories = load_tracked_repositories
|
62
|
-
|
63
|
-
if repositories.empty?
|
64
|
-
puts "No tracked repositories found."
|
65
|
-
puts "Use 'makit repository add <url>' to add repositories to track."
|
66
|
-
return
|
67
|
-
end
|
68
|
-
|
69
|
-
repositories.each_with_index do |repo, index|
|
70
|
-
puts "\n#{(index + 1).to_s.rjust(3)}. #{repo["url"]}"
|
71
|
-
|
72
|
-
begin
|
73
|
-
clone_dir = get_clone_directory(repo["url"])
|
74
|
-
|
75
|
-
if Dir.exist?(clone_dir)
|
76
|
-
latest_commit = get_latest_commit_from_clone(clone_dir)
|
77
|
-
commit_info = get_commit_info(clone_dir, latest_commit)
|
78
|
-
|
79
|
-
puts " Status: ✅ Cloned"
|
80
|
-
puts " Latest Commit: #{latest_commit[0..7]}"
|
81
|
-
puts " Message: #{commit_info[:message]}" if commit_info[:message]
|
82
|
-
puts " Author: #{commit_info[:author]}" if commit_info[:author]
|
83
|
-
puts " Date: #{commit_info[:date]}" if commit_info[:date]
|
84
|
-
else
|
85
|
-
puts " Status: 📋 Tracked (not cloned)"
|
86
|
-
puts " Use 'makit repository clone #{repo["url"]}' to clone locally"
|
87
|
-
end
|
88
|
-
rescue StandardError => e
|
89
|
-
puts " Status: ❌ Error: #{e.message}"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
puts "\n=" * 80
|
94
|
-
puts "Total repositories: #{repositories.length}"
|
95
|
-
puts "\nTo build a specific repository: makit build make <repository-url>"
|
96
|
-
end
|
97
|
-
|
98
|
-
def build_repository(url)
|
99
|
-
puts "Building repository: #{url}"
|
100
|
-
puts "Commit: #{commit}"
|
101
|
-
puts "Force rebuild: #{force?}" if force?
|
102
|
-
puts "Verbose: #{verbose?}" if verbose?
|
103
|
-
|
104
|
-
begin
|
105
|
-
make_result = Makit.make(url, commit, force: force?)
|
106
|
-
|
107
|
-
puts "\n✅ Build completed successfully!"
|
108
|
-
puts "Repository: #{make_result.repository}"
|
109
|
-
puts "Commit: #{make_result.commit}"
|
110
|
-
puts "Device: #{make_result.device}"
|
111
|
-
puts "Runtime: #{make_result.runtime_identifier}"
|
112
|
-
|
113
|
-
if verbose? && make_result.commands.any?
|
114
|
-
puts "\nCommand Summary:"
|
115
|
-
make_result.commands.each_with_index do |cmd, index|
|
116
|
-
status = cmd.exit_code.zero? ? "✅" : "❌"
|
117
|
-
puts " #{index + 1}. #{status} #{cmd.name} #{cmd.arguments.join(" ")}"
|
118
|
-
puts " Duration: #{cmd.duration.seconds}s" if cmd.duration
|
119
|
-
puts " Error: #{cmd.error.strip}" if cmd.exit_code != 0 && cmd.error && !cmd.error.empty?
|
120
|
-
end
|
121
|
-
end
|
122
|
-
rescue Makit::BuildError => e
|
123
|
-
puts "\n❌ Build failed: #{e.message}"
|
124
|
-
exit 1
|
125
|
-
rescue StandardError => e
|
126
|
-
puts "\n❌ Unexpected error: #{e.message}"
|
127
|
-
puts e.backtrace.first(5).join("\n") if verbose?
|
128
|
-
exit 1
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def load_tracked_repositories
|
133
|
-
tracked_file = File.join(Makit::Directories::ROOT, "tracked_repositories.json")
|
134
|
-
return [] unless File.exist?(tracked_file)
|
135
|
-
|
136
|
-
begin
|
137
|
-
JSON.parse(File.read(tracked_file))
|
138
|
-
rescue JSON::ParserError => e
|
139
|
-
puts "Warning: Could not parse tracked repositories file: #{e.message}"
|
140
|
-
[]
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def get_clone_directory(url)
|
145
|
-
Makit::Directories.get_clone_directory(url)
|
146
|
-
end
|
147
|
-
|
148
|
-
def get_latest_commit_from_clone(clone_dir)
|
149
|
-
Dir.chdir(clone_dir) do
|
150
|
-
`git rev-parse HEAD`.strip
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def get_commit_info(clone_dir, commit_hash)
|
155
|
-
Dir.chdir(clone_dir) do
|
156
|
-
{
|
157
|
-
message: `git log -1 --format="%s" #{commit_hash}`.strip,
|
158
|
-
author: `git log -1 --format="%an" #{commit_hash}`.strip,
|
159
|
-
date: `git log -1 --format="%ci" #{commit_hash}`.strip,
|
160
|
-
}
|
161
|
-
end
|
162
|
-
rescue StandardError
|
163
|
-
{}
|
164
|
-
end
|
165
|
-
|
166
|
-
def detect_project_type(dir)
|
167
|
-
return "ruby" if File.exist?(File.join(dir, "Rakefile")) || File.exist?(File.join(dir, "Gemfile"))
|
168
|
-
return "dotnet" if Dir.glob(File.join(dir, "*.csproj")).any? || Dir.glob(File.join(dir, "*.sln")).any?
|
169
|
-
return "node" if File.exist?(File.join(dir, "package.json"))
|
170
|
-
return "rust" if File.exist?(File.join(dir, "Cargo.toml"))
|
171
|
-
|
172
|
-
"unknown"
|
173
|
-
end
|
174
|
-
|
175
|
-
def clean_if_requested
|
176
|
-
puts "Cleaning before build..." if verbose?
|
177
|
-
|
178
|
-
# Use the clean command internally
|
179
|
-
clean_cmd = CleanBuildCommand.new("")
|
180
|
-
clean_cmd.run([])
|
181
|
-
end
|
182
|
-
|
183
|
-
def build_project(project_type)
|
184
|
-
case project_type
|
185
|
-
when "ruby"
|
186
|
-
build_ruby_project
|
187
|
-
when "dotnet"
|
188
|
-
build_dotnet_project
|
189
|
-
when "node"
|
190
|
-
build_node_project
|
191
|
-
when "rust"
|
192
|
-
build_rust_project
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def build_ruby_project
|
197
|
-
puts " Building Ruby gem..." if verbose?
|
198
|
-
|
199
|
-
# Check for Rakefile and run default task
|
200
|
-
if File.exist?("Rakefile")
|
201
|
-
cmd = "bundle exec rake"
|
202
|
-
cmd += " --verbose" if verbose?
|
203
|
-
|
204
|
-
puts " Running: #{cmd}" if verbose?
|
205
|
-
success = system(cmd)
|
206
|
-
|
207
|
-
unless success
|
208
|
-
puts "❌ Rake build failed"
|
209
|
-
exit 1
|
210
|
-
end
|
211
|
-
else
|
212
|
-
# Fallback: just run bundle install and try to build gem
|
213
|
-
puts " Installing dependencies..." if verbose?
|
214
|
-
system("bundle install") if File.exist?("Gemfile")
|
215
|
-
|
216
|
-
if Dir.glob("*.gemspec").any?
|
217
|
-
puts " Building gem..." if verbose?
|
218
|
-
system("gem build *.gemspec")
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
puts " ✅ Ruby build complete" if verbose?
|
223
|
-
end
|
224
|
-
|
225
|
-
def build_dotnet_project
|
226
|
-
puts " Building .NET project..." if verbose?
|
227
|
-
|
228
|
-
build_args = []
|
229
|
-
build_args << "--configuration #{target.capitalize}"
|
230
|
-
build_args << "--verbosity detailed" if verbose?
|
231
|
-
|
232
|
-
cmd = "dotnet build #{build_args.join(" ")}"
|
233
|
-
puts " Running: #{cmd}" if verbose?
|
234
|
-
|
235
|
-
success = system(cmd)
|
236
|
-
unless success
|
237
|
-
puts "❌ .NET build failed"
|
238
|
-
exit 1
|
239
|
-
end
|
240
|
-
|
241
|
-
puts " ✅ .NET build complete" if verbose?
|
242
|
-
end
|
243
|
-
|
244
|
-
def build_node_project
|
245
|
-
puts " Building Node.js project..." if verbose?
|
246
|
-
|
247
|
-
# Install dependencies if needed
|
248
|
-
if File.exist?("package.json") && !Dir.exist?("node_modules")
|
249
|
-
puts " Installing dependencies..." if verbose?
|
250
|
-
install_cmd = File.exist?("package-lock.json") ? "npm ci" : "npm install"
|
251
|
-
system(install_cmd)
|
252
|
-
end
|
253
|
-
|
254
|
-
# Check for build script in package.json
|
255
|
-
if File.exist?("package.json")
|
256
|
-
package_data = JSON.parse(File.read("package.json"))
|
257
|
-
scripts = package_data["scripts"] || {}
|
258
|
-
|
259
|
-
if scripts["build"]
|
260
|
-
puts " Running build script..." if verbose?
|
261
|
-
cmd = "npm run build"
|
262
|
-
cmd += " --verbose" if verbose?
|
263
|
-
|
264
|
-
success = system(cmd)
|
265
|
-
unless success
|
266
|
-
puts "❌ npm build failed"
|
267
|
-
exit 1
|
268
|
-
end
|
269
|
-
elsif verbose?
|
270
|
-
puts " No build script found in package.json"
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
puts " ✅ Node.js build complete" if verbose?
|
275
|
-
end
|
276
|
-
|
277
|
-
def build_rust_project
|
278
|
-
puts " Building Rust project..." if verbose?
|
279
|
-
|
280
|
-
build_args = []
|
281
|
-
build_args << "--release" if target == "release"
|
282
|
-
build_args << "--verbose" if verbose?
|
283
|
-
|
284
|
-
cmd = "cargo build #{build_args.join(" ")}"
|
285
|
-
puts " Running: #{cmd}" if verbose?
|
286
|
-
|
287
|
-
success = system(cmd)
|
288
|
-
unless success
|
289
|
-
puts "❌ Cargo build failed"
|
290
|
-
exit 1
|
291
|
-
end
|
292
|
-
|
293
|
-
puts " ✅ Rust build complete" if verbose?
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
# Clean build artifacts and temporary files
|
298
|
-
class CleanBuildCommand < Clamp::Command
|
299
|
-
self.description = <<~DESC
|
300
|
-
Clean build artifacts, temporary files, and caches.
|
301
|
-
|
302
|
-
Examples:
|
303
|
-
makit build clean
|
304
|
-
makit build clean --deep
|
305
|
-
makit build clean --dry-run
|
306
|
-
DESC
|
307
|
-
|
308
|
-
option ["--deep"], :flag, "Perform deep clean (including dependencies)"
|
309
|
-
option ["--dry-run"], :flag, "Show what would be cleaned without actually cleaning"
|
310
|
-
option ["--verbose", "-v"], :flag, "Show verbose output"
|
311
|
-
|
312
|
-
def execute
|
313
|
-
project_type = detect_project_type(Dir.pwd)
|
314
|
-
|
315
|
-
puts "Cleaning #{project_type} project artifacts..."
|
316
|
-
puts "Deep clean: #{deep?}" if verbose? && deep?
|
317
|
-
puts "Dry run: #{dry_run?}" if verbose? && dry_run?
|
318
|
-
|
319
|
-
clean_common_artifacts
|
320
|
-
clean_project_specific_artifacts(project_type)
|
321
|
-
clean_dependencies if deep?
|
322
|
-
|
323
|
-
if dry_run?
|
324
|
-
puts "✅ Dry run completed - no files were actually removed"
|
325
|
-
else
|
326
|
-
puts "✅ Clean completed successfully"
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
private
|
331
|
-
|
332
|
-
def detect_project_type(dir)
|
333
|
-
return "ruby" if File.exist?(File.join(dir, "Rakefile")) || File.exist?(File.join(dir, "Gemfile"))
|
334
|
-
return "dotnet" if Dir.glob(File.join(dir, "*.csproj")).any? || Dir.glob(File.join(dir, "*.sln")).any?
|
335
|
-
return "node" if File.exist?(File.join(dir, "package.json"))
|
336
|
-
return "rust" if File.exist?(File.join(dir, "Cargo.toml"))
|
337
|
-
|
338
|
-
"unknown"
|
339
|
-
end
|
340
|
-
|
341
|
-
def clean_common_artifacts
|
342
|
-
common_patterns = [
|
343
|
-
"**/*.log",
|
344
|
-
"**/tmp/**/*",
|
345
|
-
"**/temp/**/*",
|
346
|
-
"**/.DS_Store",
|
347
|
-
"**/Thumbs.db",
|
348
|
-
"**/*.tmp",
|
349
|
-
"**/*.bak",
|
350
|
-
"**/*.swp",
|
351
|
-
"**/*.swo",
|
352
|
-
]
|
353
|
-
|
354
|
-
common_patterns.each do |pattern|
|
355
|
-
clean_by_pattern(pattern, "Common temp files")
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
def clean_project_specific_artifacts(project_type)
|
360
|
-
case project_type
|
361
|
-
when "ruby"
|
362
|
-
clean_ruby_artifacts
|
363
|
-
when "dotnet"
|
364
|
-
clean_dotnet_artifacts
|
365
|
-
when "node"
|
366
|
-
clean_node_artifacts
|
367
|
-
when "rust"
|
368
|
-
clean_rust_artifacts
|
369
|
-
else
|
370
|
-
puts " Unknown project type - only cleaning common artifacts" if verbose?
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
def clean_ruby_artifacts
|
375
|
-
# Clean gem files
|
376
|
-
clean_by_pattern("*.gem", "Ruby gem files")
|
377
|
-
|
378
|
-
# Clean pkg directory
|
379
|
-
clean_directory("pkg", "Ruby package directory")
|
380
|
-
|
381
|
-
# Clean coverage directory
|
382
|
-
clean_directory("coverage", "Ruby coverage reports")
|
383
|
-
|
384
|
-
# Clean bundler cache if deep clean
|
385
|
-
clean_directory("vendor/bundle", "Bundler cache") if deep?
|
386
|
-
|
387
|
-
puts " ✅ Ruby artifacts cleaned" if verbose?
|
388
|
-
end
|
389
|
-
|
390
|
-
def clean_dotnet_artifacts
|
391
|
-
# Clean bin and obj directories
|
392
|
-
clean_by_pattern("**/bin/**/*", ".NET bin directories")
|
393
|
-
clean_by_pattern("**/obj/**/*", ".NET obj directories")
|
394
|
-
|
395
|
-
# Clean test results
|
396
|
-
clean_by_pattern("**/TestResults/**/*", ".NET test results")
|
397
|
-
|
398
|
-
# Clean packages if deep clean
|
399
|
-
clean_directory("packages", ".NET packages directory") if deep?
|
400
|
-
|
401
|
-
puts " ✅ .NET artifacts cleaned" if verbose?
|
402
|
-
end
|
403
|
-
|
404
|
-
def clean_node_artifacts
|
405
|
-
# Clean build directory
|
406
|
-
clean_directory("build", "Node.js build directory")
|
407
|
-
clean_directory("dist", "Node.js dist directory")
|
408
|
-
|
409
|
-
# Clean coverage and test reports
|
410
|
-
clean_directory("coverage", "Node.js coverage reports")
|
411
|
-
clean_directory("nyc_output", "NYC coverage output")
|
412
|
-
|
413
|
-
# Clean logs
|
414
|
-
clean_by_pattern("npm-debug.log*", "npm debug logs")
|
415
|
-
clean_by_pattern("yarn-debug.log*", "Yarn debug logs")
|
416
|
-
clean_by_pattern("yarn-error.log*", "Yarn error logs")
|
417
|
-
|
418
|
-
# Clean node_modules if deep clean
|
419
|
-
clean_directory("node_modules", "Node.js dependencies") if deep?
|
420
|
-
|
421
|
-
puts " ✅ Node.js artifacts cleaned" if verbose?
|
422
|
-
end
|
423
|
-
|
424
|
-
def clean_rust_artifacts
|
425
|
-
# Clean target directory
|
426
|
-
clean_directory("target", "Rust target directory")
|
427
|
-
|
428
|
-
# Clean Cargo lock if deep clean
|
429
|
-
clean_file("Cargo.lock", "Cargo lock file") if deep?
|
430
|
-
|
431
|
-
puts " ✅ Rust artifacts cleaned" if verbose?
|
432
|
-
end
|
433
|
-
|
434
|
-
def clean_dependencies
|
435
|
-
puts " Performing deep clean of dependencies..." if verbose?
|
436
|
-
|
437
|
-
project_type = detect_project_type(Dir.pwd)
|
438
|
-
|
439
|
-
case project_type
|
440
|
-
when "ruby"
|
441
|
-
clean_directory("vendor/bundle", "Ruby vendor directory")
|
442
|
-
clean_file("Gemfile.lock", "Ruby Gemfile lock") if File.exist?("Gemfile.lock")
|
443
|
-
when "dotnet"
|
444
|
-
clean_directory("packages", ".NET packages")
|
445
|
-
# NOTE: Don't clean packages.lock.json as it's source controlled
|
446
|
-
when "node"
|
447
|
-
clean_directory("node_modules", "Node.js modules")
|
448
|
-
clean_file("package-lock.json", "npm lock file") if File.exist?("package-lock.json")
|
449
|
-
clean_file("yarn.lock", "Yarn lock file") if File.exist?("yarn.lock")
|
450
|
-
when "rust"
|
451
|
-
# Rust doesn't really have a separate dependency directory to clean
|
452
|
-
# Dependencies are in target/ which is already cleaned above
|
453
|
-
puts " Rust dependencies are cleaned with target directory" if verbose?
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
def clean_by_pattern(pattern, description)
|
458
|
-
matching_files = Dir.glob(pattern)
|
459
|
-
|
460
|
-
if matching_files.any?
|
461
|
-
puts " Cleaning #{description}: #{matching_files.length} items" if verbose?
|
462
|
-
|
463
|
-
unless dry_run?
|
464
|
-
matching_files.each do |file|
|
465
|
-
if File.directory?(file)
|
466
|
-
FileUtils.rm_rf(file)
|
467
|
-
else
|
468
|
-
FileUtils.rm_f(file)
|
469
|
-
end
|
470
|
-
end
|
471
|
-
end
|
472
|
-
elsif verbose?
|
473
|
-
puts " No #{description} found"
|
474
|
-
end
|
475
|
-
end
|
476
|
-
|
477
|
-
def clean_directory(dir_path, description)
|
478
|
-
if Dir.exist?(dir_path)
|
479
|
-
puts " Cleaning #{description}: #{dir_path}" if verbose?
|
480
|
-
FileUtils.rm_rf(dir_path) unless dry_run?
|
481
|
-
elsif verbose?
|
482
|
-
puts " #{description} not found: #{dir_path}"
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
def clean_file(file_path, description)
|
487
|
-
if File.exist?(file_path)
|
488
|
-
puts " Cleaning #{description}: #{file_path}" if verbose?
|
489
|
-
FileUtils.rm_f(file_path) unless dry_run?
|
490
|
-
elsif verbose?
|
491
|
-
puts " #{description} not found: #{file_path}"
|
492
|
-
end
|
493
|
-
end
|
494
|
-
end
|
495
|
-
|
496
|
-
# Add subcommand declarations after all classes are defined
|
497
|
-
BuildCommand.subcommand "make", "Build project artifacts", MakeBuildCommand
|
498
|
-
BuildCommand.subcommand "clean", "Clean build artifacts", CleanBuildCommand
|
499
|
-
end
|
500
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "clamp"
|
4
|
+
require "fileutils"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module Makit
|
8
|
+
module Cli
|
9
|
+
# Consolidated build operations commands
|
10
|
+
# Combines: make, clean functionality
|
11
|
+
class BuildCommand < Clamp::Command
|
12
|
+
self.description = <<~DESC
|
13
|
+
Manage project build operations and artifact cleanup.
|
14
|
+
|
15
|
+
Available operations:
|
16
|
+
make - Build project and generate artifacts
|
17
|
+
clean - Clean build artifacts and temporary files
|
18
|
+
DESC
|
19
|
+
end
|
20
|
+
|
21
|
+
# Build project artifacts
|
22
|
+
class MakeBuildCommand < Clamp::Command
|
23
|
+
self.description = <<~DESC
|
24
|
+
Build project artifacts and execute build tasks.
|
25
|
+
|
26
|
+
When called without arguments, enumerates all tracked repositories
|
27
|
+
and displays their latest commit IDs.
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
makit build make # Show all repositories and latest commits
|
31
|
+
makit build make https://github.com/user/repo # Build specific repository
|
32
|
+
makit build make --target release # Build current project with release target
|
33
|
+
makit build make --parallel # Build with parallel execution
|
34
|
+
DESC
|
35
|
+
|
36
|
+
parameter "[REPOSITORY_URL]", "Git repository URL to build (optional)", attribute_name: :repository_url,
|
37
|
+
required: false
|
38
|
+
option ["--commit"], "COMMIT", "Specific commit to build (default: latest)", default: "latest"
|
39
|
+
option ["--target"], "TARGET", "Build target (debug, release)", default: "debug"
|
40
|
+
option ["--parallel", "-j"], :flag, "Enable parallel build"
|
41
|
+
option ["--verbose", "-v"], :flag, "Show verbose build output"
|
42
|
+
option ["--clean"], :flag, "Clean before building"
|
43
|
+
option ["--force"], :flag, "Force rebuild even if cached result exists"
|
44
|
+
|
45
|
+
def execute
|
46
|
+
if repository_url
|
47
|
+
# Build specific repository
|
48
|
+
build_repository(repository_url)
|
49
|
+
else
|
50
|
+
# No arguments - enumerate all tracked repositories and show latest commits
|
51
|
+
enumerate_repositories
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def enumerate_repositories
|
58
|
+
puts "Enumerating all tracked repositories and their latest commit IDs..."
|
59
|
+
puts "=" * 80
|
60
|
+
|
61
|
+
repositories = load_tracked_repositories
|
62
|
+
|
63
|
+
if repositories.empty?
|
64
|
+
puts "No tracked repositories found."
|
65
|
+
puts "Use 'makit repository add <url>' to add repositories to track."
|
66
|
+
return
|
67
|
+
end
|
68
|
+
|
69
|
+
repositories.each_with_index do |repo, index|
|
70
|
+
puts "\n#{(index + 1).to_s.rjust(3)}. #{repo["url"]}"
|
71
|
+
|
72
|
+
begin
|
73
|
+
clone_dir = get_clone_directory(repo["url"])
|
74
|
+
|
75
|
+
if Dir.exist?(clone_dir)
|
76
|
+
latest_commit = get_latest_commit_from_clone(clone_dir)
|
77
|
+
commit_info = get_commit_info(clone_dir, latest_commit)
|
78
|
+
|
79
|
+
puts " Status: ✅ Cloned"
|
80
|
+
puts " Latest Commit: #{latest_commit[0..7]}"
|
81
|
+
puts " Message: #{commit_info[:message]}" if commit_info[:message]
|
82
|
+
puts " Author: #{commit_info[:author]}" if commit_info[:author]
|
83
|
+
puts " Date: #{commit_info[:date]}" if commit_info[:date]
|
84
|
+
else
|
85
|
+
puts " Status: 📋 Tracked (not cloned)"
|
86
|
+
puts " Use 'makit repository clone #{repo["url"]}' to clone locally"
|
87
|
+
end
|
88
|
+
rescue StandardError => e
|
89
|
+
puts " Status: ❌ Error: #{e.message}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
puts "\n=" * 80
|
94
|
+
puts "Total repositories: #{repositories.length}"
|
95
|
+
puts "\nTo build a specific repository: makit build make <repository-url>"
|
96
|
+
end
|
97
|
+
|
98
|
+
def build_repository(url)
|
99
|
+
puts "Building repository: #{url}"
|
100
|
+
puts "Commit: #{commit}"
|
101
|
+
puts "Force rebuild: #{force?}" if force?
|
102
|
+
puts "Verbose: #{verbose?}" if verbose?
|
103
|
+
|
104
|
+
begin
|
105
|
+
make_result = Makit.make(url, commit, force: force?)
|
106
|
+
|
107
|
+
puts "\n✅ Build completed successfully!"
|
108
|
+
puts "Repository: #{make_result.repository}"
|
109
|
+
puts "Commit: #{make_result.commit}"
|
110
|
+
puts "Device: #{make_result.device}"
|
111
|
+
puts "Runtime: #{make_result.runtime_identifier}"
|
112
|
+
|
113
|
+
if verbose? && make_result.commands.any?
|
114
|
+
puts "\nCommand Summary:"
|
115
|
+
make_result.commands.each_with_index do |cmd, index|
|
116
|
+
status = cmd.exit_code.zero? ? "✅" : "❌"
|
117
|
+
puts " #{index + 1}. #{status} #{cmd.name} #{cmd.arguments.join(" ")}"
|
118
|
+
puts " Duration: #{cmd.duration.seconds}s" if cmd.duration
|
119
|
+
puts " Error: #{cmd.error.strip}" if cmd.exit_code != 0 && cmd.error && !cmd.error.empty?
|
120
|
+
end
|
121
|
+
end
|
122
|
+
rescue Makit::BuildError => e
|
123
|
+
puts "\n❌ Build failed: #{e.message}"
|
124
|
+
exit 1
|
125
|
+
rescue StandardError => e
|
126
|
+
puts "\n❌ Unexpected error: #{e.message}"
|
127
|
+
puts e.backtrace.first(5).join("\n") if verbose?
|
128
|
+
exit 1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def load_tracked_repositories
|
133
|
+
tracked_file = File.join(Makit::Directories::ROOT, "tracked_repositories.json")
|
134
|
+
return [] unless File.exist?(tracked_file)
|
135
|
+
|
136
|
+
begin
|
137
|
+
JSON.parse(File.read(tracked_file))
|
138
|
+
rescue JSON::ParserError => e
|
139
|
+
puts "Warning: Could not parse tracked repositories file: #{e.message}"
|
140
|
+
[]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_clone_directory(url)
|
145
|
+
Makit::Directories.get_clone_directory(url)
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_latest_commit_from_clone(clone_dir)
|
149
|
+
Dir.chdir(clone_dir) do
|
150
|
+
`git rev-parse HEAD`.strip
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_commit_info(clone_dir, commit_hash)
|
155
|
+
Dir.chdir(clone_dir) do
|
156
|
+
{
|
157
|
+
message: `git log -1 --format="%s" #{commit_hash}`.strip,
|
158
|
+
author: `git log -1 --format="%an" #{commit_hash}`.strip,
|
159
|
+
date: `git log -1 --format="%ci" #{commit_hash}`.strip,
|
160
|
+
}
|
161
|
+
end
|
162
|
+
rescue StandardError
|
163
|
+
{}
|
164
|
+
end
|
165
|
+
|
166
|
+
def detect_project_type(dir)
|
167
|
+
return "ruby" if File.exist?(File.join(dir, "Rakefile")) || File.exist?(File.join(dir, "Gemfile"))
|
168
|
+
return "dotnet" if Dir.glob(File.join(dir, "*.csproj")).any? || Dir.glob(File.join(dir, "*.sln")).any?
|
169
|
+
return "node" if File.exist?(File.join(dir, "package.json"))
|
170
|
+
return "rust" if File.exist?(File.join(dir, "Cargo.toml"))
|
171
|
+
|
172
|
+
"unknown"
|
173
|
+
end
|
174
|
+
|
175
|
+
def clean_if_requested
|
176
|
+
puts "Cleaning before build..." if verbose?
|
177
|
+
|
178
|
+
# Use the clean command internally
|
179
|
+
clean_cmd = CleanBuildCommand.new("")
|
180
|
+
clean_cmd.run([])
|
181
|
+
end
|
182
|
+
|
183
|
+
def build_project(project_type)
|
184
|
+
case project_type
|
185
|
+
when "ruby"
|
186
|
+
build_ruby_project
|
187
|
+
when "dotnet"
|
188
|
+
build_dotnet_project
|
189
|
+
when "node"
|
190
|
+
build_node_project
|
191
|
+
when "rust"
|
192
|
+
build_rust_project
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def build_ruby_project
|
197
|
+
puts " Building Ruby gem..." if verbose?
|
198
|
+
|
199
|
+
# Check for Rakefile and run default task
|
200
|
+
if File.exist?("Rakefile")
|
201
|
+
cmd = "bundle exec rake"
|
202
|
+
cmd += " --verbose" if verbose?
|
203
|
+
|
204
|
+
puts " Running: #{cmd}" if verbose?
|
205
|
+
success = system(cmd)
|
206
|
+
|
207
|
+
unless success
|
208
|
+
puts "❌ Rake build failed"
|
209
|
+
exit 1
|
210
|
+
end
|
211
|
+
else
|
212
|
+
# Fallback: just run bundle install and try to build gem
|
213
|
+
puts " Installing dependencies..." if verbose?
|
214
|
+
system("bundle install") if File.exist?("Gemfile")
|
215
|
+
|
216
|
+
if Dir.glob("*.gemspec").any?
|
217
|
+
puts " Building gem..." if verbose?
|
218
|
+
system("gem build *.gemspec")
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
puts " ✅ Ruby build complete" if verbose?
|
223
|
+
end
|
224
|
+
|
225
|
+
def build_dotnet_project
|
226
|
+
puts " Building .NET project..." if verbose?
|
227
|
+
|
228
|
+
build_args = []
|
229
|
+
build_args << "--configuration #{target.capitalize}"
|
230
|
+
build_args << "--verbosity detailed" if verbose?
|
231
|
+
|
232
|
+
cmd = "dotnet build #{build_args.join(" ")}"
|
233
|
+
puts " Running: #{cmd}" if verbose?
|
234
|
+
|
235
|
+
success = system(cmd)
|
236
|
+
unless success
|
237
|
+
puts "❌ .NET build failed"
|
238
|
+
exit 1
|
239
|
+
end
|
240
|
+
|
241
|
+
puts " ✅ .NET build complete" if verbose?
|
242
|
+
end
|
243
|
+
|
244
|
+
def build_node_project
|
245
|
+
puts " Building Node.js project..." if verbose?
|
246
|
+
|
247
|
+
# Install dependencies if needed
|
248
|
+
if File.exist?("package.json") && !Dir.exist?("node_modules")
|
249
|
+
puts " Installing dependencies..." if verbose?
|
250
|
+
install_cmd = File.exist?("package-lock.json") ? "npm ci" : "npm install"
|
251
|
+
system(install_cmd)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Check for build script in package.json
|
255
|
+
if File.exist?("package.json")
|
256
|
+
package_data = JSON.parse(File.read("package.json"))
|
257
|
+
scripts = package_data["scripts"] || {}
|
258
|
+
|
259
|
+
if scripts["build"]
|
260
|
+
puts " Running build script..." if verbose?
|
261
|
+
cmd = "npm run build"
|
262
|
+
cmd += " --verbose" if verbose?
|
263
|
+
|
264
|
+
success = system(cmd)
|
265
|
+
unless success
|
266
|
+
puts "❌ npm build failed"
|
267
|
+
exit 1
|
268
|
+
end
|
269
|
+
elsif verbose?
|
270
|
+
puts " No build script found in package.json"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
puts " ✅ Node.js build complete" if verbose?
|
275
|
+
end
|
276
|
+
|
277
|
+
def build_rust_project
|
278
|
+
puts " Building Rust project..." if verbose?
|
279
|
+
|
280
|
+
build_args = []
|
281
|
+
build_args << "--release" if target == "release"
|
282
|
+
build_args << "--verbose" if verbose?
|
283
|
+
|
284
|
+
cmd = "cargo build #{build_args.join(" ")}"
|
285
|
+
puts " Running: #{cmd}" if verbose?
|
286
|
+
|
287
|
+
success = system(cmd)
|
288
|
+
unless success
|
289
|
+
puts "❌ Cargo build failed"
|
290
|
+
exit 1
|
291
|
+
end
|
292
|
+
|
293
|
+
puts " ✅ Rust build complete" if verbose?
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Clean build artifacts and temporary files
|
298
|
+
class CleanBuildCommand < Clamp::Command
|
299
|
+
self.description = <<~DESC
|
300
|
+
Clean build artifacts, temporary files, and caches.
|
301
|
+
|
302
|
+
Examples:
|
303
|
+
makit build clean
|
304
|
+
makit build clean --deep
|
305
|
+
makit build clean --dry-run
|
306
|
+
DESC
|
307
|
+
|
308
|
+
option ["--deep"], :flag, "Perform deep clean (including dependencies)"
|
309
|
+
option ["--dry-run"], :flag, "Show what would be cleaned without actually cleaning"
|
310
|
+
option ["--verbose", "-v"], :flag, "Show verbose output"
|
311
|
+
|
312
|
+
def execute
|
313
|
+
project_type = detect_project_type(Dir.pwd)
|
314
|
+
|
315
|
+
puts "Cleaning #{project_type} project artifacts..."
|
316
|
+
puts "Deep clean: #{deep?}" if verbose? && deep?
|
317
|
+
puts "Dry run: #{dry_run?}" if verbose? && dry_run?
|
318
|
+
|
319
|
+
clean_common_artifacts
|
320
|
+
clean_project_specific_artifacts(project_type)
|
321
|
+
clean_dependencies if deep?
|
322
|
+
|
323
|
+
if dry_run?
|
324
|
+
puts "✅ Dry run completed - no files were actually removed"
|
325
|
+
else
|
326
|
+
puts "✅ Clean completed successfully"
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
private
|
331
|
+
|
332
|
+
def detect_project_type(dir)
|
333
|
+
return "ruby" if File.exist?(File.join(dir, "Rakefile")) || File.exist?(File.join(dir, "Gemfile"))
|
334
|
+
return "dotnet" if Dir.glob(File.join(dir, "*.csproj")).any? || Dir.glob(File.join(dir, "*.sln")).any?
|
335
|
+
return "node" if File.exist?(File.join(dir, "package.json"))
|
336
|
+
return "rust" if File.exist?(File.join(dir, "Cargo.toml"))
|
337
|
+
|
338
|
+
"unknown"
|
339
|
+
end
|
340
|
+
|
341
|
+
def clean_common_artifacts
|
342
|
+
common_patterns = [
|
343
|
+
"**/*.log",
|
344
|
+
"**/tmp/**/*",
|
345
|
+
"**/temp/**/*",
|
346
|
+
"**/.DS_Store",
|
347
|
+
"**/Thumbs.db",
|
348
|
+
"**/*.tmp",
|
349
|
+
"**/*.bak",
|
350
|
+
"**/*.swp",
|
351
|
+
"**/*.swo",
|
352
|
+
]
|
353
|
+
|
354
|
+
common_patterns.each do |pattern|
|
355
|
+
clean_by_pattern(pattern, "Common temp files")
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def clean_project_specific_artifacts(project_type)
|
360
|
+
case project_type
|
361
|
+
when "ruby"
|
362
|
+
clean_ruby_artifacts
|
363
|
+
when "dotnet"
|
364
|
+
clean_dotnet_artifacts
|
365
|
+
when "node"
|
366
|
+
clean_node_artifacts
|
367
|
+
when "rust"
|
368
|
+
clean_rust_artifacts
|
369
|
+
else
|
370
|
+
puts " Unknown project type - only cleaning common artifacts" if verbose?
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def clean_ruby_artifacts
|
375
|
+
# Clean gem files
|
376
|
+
clean_by_pattern("*.gem", "Ruby gem files")
|
377
|
+
|
378
|
+
# Clean pkg directory
|
379
|
+
clean_directory("pkg", "Ruby package directory")
|
380
|
+
|
381
|
+
# Clean coverage directory
|
382
|
+
clean_directory("coverage", "Ruby coverage reports")
|
383
|
+
|
384
|
+
# Clean bundler cache if deep clean
|
385
|
+
clean_directory("vendor/bundle", "Bundler cache") if deep?
|
386
|
+
|
387
|
+
puts " ✅ Ruby artifacts cleaned" if verbose?
|
388
|
+
end
|
389
|
+
|
390
|
+
def clean_dotnet_artifacts
|
391
|
+
# Clean bin and obj directories
|
392
|
+
clean_by_pattern("**/bin/**/*", ".NET bin directories")
|
393
|
+
clean_by_pattern("**/obj/**/*", ".NET obj directories")
|
394
|
+
|
395
|
+
# Clean test results
|
396
|
+
clean_by_pattern("**/TestResults/**/*", ".NET test results")
|
397
|
+
|
398
|
+
# Clean packages if deep clean
|
399
|
+
clean_directory("packages", ".NET packages directory") if deep?
|
400
|
+
|
401
|
+
puts " ✅ .NET artifacts cleaned" if verbose?
|
402
|
+
end
|
403
|
+
|
404
|
+
def clean_node_artifacts
|
405
|
+
# Clean build directory
|
406
|
+
clean_directory("build", "Node.js build directory")
|
407
|
+
clean_directory("dist", "Node.js dist directory")
|
408
|
+
|
409
|
+
# Clean coverage and test reports
|
410
|
+
clean_directory("coverage", "Node.js coverage reports")
|
411
|
+
clean_directory("nyc_output", "NYC coverage output")
|
412
|
+
|
413
|
+
# Clean logs
|
414
|
+
clean_by_pattern("npm-debug.log*", "npm debug logs")
|
415
|
+
clean_by_pattern("yarn-debug.log*", "Yarn debug logs")
|
416
|
+
clean_by_pattern("yarn-error.log*", "Yarn error logs")
|
417
|
+
|
418
|
+
# Clean node_modules if deep clean
|
419
|
+
clean_directory("node_modules", "Node.js dependencies") if deep?
|
420
|
+
|
421
|
+
puts " ✅ Node.js artifacts cleaned" if verbose?
|
422
|
+
end
|
423
|
+
|
424
|
+
def clean_rust_artifacts
|
425
|
+
# Clean target directory
|
426
|
+
clean_directory("target", "Rust target directory")
|
427
|
+
|
428
|
+
# Clean Cargo lock if deep clean
|
429
|
+
clean_file("Cargo.lock", "Cargo lock file") if deep?
|
430
|
+
|
431
|
+
puts " ✅ Rust artifacts cleaned" if verbose?
|
432
|
+
end
|
433
|
+
|
434
|
+
def clean_dependencies
|
435
|
+
puts " Performing deep clean of dependencies..." if verbose?
|
436
|
+
|
437
|
+
project_type = detect_project_type(Dir.pwd)
|
438
|
+
|
439
|
+
case project_type
|
440
|
+
when "ruby"
|
441
|
+
clean_directory("vendor/bundle", "Ruby vendor directory")
|
442
|
+
clean_file("Gemfile.lock", "Ruby Gemfile lock") if File.exist?("Gemfile.lock")
|
443
|
+
when "dotnet"
|
444
|
+
clean_directory("packages", ".NET packages")
|
445
|
+
# NOTE: Don't clean packages.lock.json as it's source controlled
|
446
|
+
when "node"
|
447
|
+
clean_directory("node_modules", "Node.js modules")
|
448
|
+
clean_file("package-lock.json", "npm lock file") if File.exist?("package-lock.json")
|
449
|
+
clean_file("yarn.lock", "Yarn lock file") if File.exist?("yarn.lock")
|
450
|
+
when "rust"
|
451
|
+
# Rust doesn't really have a separate dependency directory to clean
|
452
|
+
# Dependencies are in target/ which is already cleaned above
|
453
|
+
puts " Rust dependencies are cleaned with target directory" if verbose?
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
def clean_by_pattern(pattern, description)
|
458
|
+
matching_files = Dir.glob(pattern)
|
459
|
+
|
460
|
+
if matching_files.any?
|
461
|
+
puts " Cleaning #{description}: #{matching_files.length} items" if verbose?
|
462
|
+
|
463
|
+
unless dry_run?
|
464
|
+
matching_files.each do |file|
|
465
|
+
if File.directory?(file)
|
466
|
+
FileUtils.rm_rf(file)
|
467
|
+
else
|
468
|
+
FileUtils.rm_f(file)
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
elsif verbose?
|
473
|
+
puts " No #{description} found"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def clean_directory(dir_path, description)
|
478
|
+
if Dir.exist?(dir_path)
|
479
|
+
puts " Cleaning #{description}: #{dir_path}" if verbose?
|
480
|
+
FileUtils.rm_rf(dir_path) unless dry_run?
|
481
|
+
elsif verbose?
|
482
|
+
puts " #{description} not found: #{dir_path}"
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
def clean_file(file_path, description)
|
487
|
+
if File.exist?(file_path)
|
488
|
+
puts " Cleaning #{description}: #{file_path}" if verbose?
|
489
|
+
FileUtils.rm_f(file_path) unless dry_run?
|
490
|
+
elsif verbose?
|
491
|
+
puts " #{description} not found: #{file_path}"
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
# Add subcommand declarations after all classes are defined
|
497
|
+
BuildCommand.subcommand "make", "Build project artifacts", MakeBuildCommand
|
498
|
+
BuildCommand.subcommand "clean", "Clean build artifacts", CleanBuildCommand
|
499
|
+
end
|
500
|
+
end
|