makit 0.0.99 → 0.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -0
  3. data/exe/makit +5 -0
  4. data/lib/makit/apache.rb +28 -32
  5. data/lib/makit/cli/build_commands.rb +500 -0
  6. data/lib/makit/cli/generators/base_generator.rb +74 -0
  7. data/lib/makit/cli/generators/dotnet_generator.rb +50 -0
  8. data/lib/makit/cli/generators/generator_factory.rb +49 -0
  9. data/lib/makit/cli/generators/node_generator.rb +50 -0
  10. data/lib/makit/cli/generators/ruby_generator.rb +77 -0
  11. data/lib/makit/cli/generators/rust_generator.rb +50 -0
  12. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -0
  13. data/lib/makit/cli/generators/templates/node_templates.rb +161 -0
  14. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -0
  15. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -0
  16. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -0
  17. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -0
  18. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -0
  19. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -0
  20. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -0
  21. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -0
  22. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -0
  23. data/lib/makit/cli/main.rb +62 -33
  24. data/lib/makit/cli/project_commands.rb +868 -0
  25. data/lib/makit/cli/repository_commands.rb +661 -0
  26. data/lib/makit/cli/utility_commands.rb +521 -0
  27. data/lib/makit/commands/factory.rb +359 -0
  28. data/lib/makit/commands/middleware/base.rb +73 -0
  29. data/lib/makit/commands/middleware/cache.rb +248 -0
  30. data/lib/makit/commands/middleware/command_logger.rb +320 -0
  31. data/lib/makit/commands/middleware/unified_logger.rb +243 -0
  32. data/lib/makit/commands/middleware/validator.rb +269 -0
  33. data/lib/makit/commands/request.rb +254 -0
  34. data/lib/makit/commands/result.rb +323 -0
  35. data/lib/makit/commands/runner.rb +337 -0
  36. data/lib/makit/commands/strategies/base.rb +160 -0
  37. data/lib/makit/commands/strategies/synchronous.rb +134 -0
  38. data/lib/makit/commands.rb +51 -21
  39. data/lib/makit/configuration/gitlab_helper.rb +60 -0
  40. data/lib/makit/configuration/project.rb +127 -0
  41. data/lib/makit/configuration/rakefile_helper.rb +43 -0
  42. data/lib/makit/configuration/step.rb +34 -0
  43. data/lib/makit/configuration.rb +14 -0
  44. data/lib/makit/content/default_gitignore.rb +7 -5
  45. data/lib/makit/content/default_rakefile.rb +13 -11
  46. data/lib/makit/content/gem_rakefile.rb +16 -14
  47. data/lib/makit/context.rb +1 -0
  48. data/lib/makit/data.rb +49 -50
  49. data/lib/makit/directories.rb +141 -145
  50. data/lib/makit/directory.rb +262 -276
  51. data/lib/makit/docs/files.rb +89 -94
  52. data/lib/makit/docs/rake.rb +102 -106
  53. data/lib/makit/dotnet/cli.rb +65 -0
  54. data/lib/makit/dotnet/project.rb +153 -0
  55. data/lib/makit/dotnet/solution.rb +38 -0
  56. data/lib/makit/dotnet/solution_classlib.rb +239 -0
  57. data/lib/makit/dotnet/solution_console.rb +264 -0
  58. data/lib/makit/dotnet/solution_maui.rb +354 -0
  59. data/lib/makit/dotnet/solution_wasm.rb +275 -0
  60. data/lib/makit/dotnet/solution_wpf.rb +304 -0
  61. data/lib/makit/dotnet.rb +102 -219
  62. data/lib/makit/email.rb +90 -61
  63. data/lib/makit/environment.rb +142 -139
  64. data/lib/makit/examples/runner.rb +370 -0
  65. data/lib/makit/exceptions.rb +45 -0
  66. data/lib/makit/fileinfo.rb +24 -26
  67. data/lib/makit/files.rb +43 -47
  68. data/lib/makit/gems.rb +29 -28
  69. data/lib/makit/git/cli.rb +54 -0
  70. data/lib/makit/git/repository.rb +90 -0
  71. data/lib/makit/git.rb +98 -145
  72. data/lib/makit/gitlab_runner.rb +59 -60
  73. data/lib/makit/humanize.rb +137 -129
  74. data/lib/makit/indexer.rb +47 -56
  75. data/lib/makit/logging/configuration.rb +305 -0
  76. data/lib/makit/logging/format_registry.rb +84 -0
  77. data/lib/makit/logging/formatters/base.rb +39 -0
  78. data/lib/makit/logging/formatters/console_formatter.rb +140 -0
  79. data/lib/makit/logging/formatters/json_formatter.rb +65 -0
  80. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -0
  81. data/lib/makit/logging/formatters/text_formatter.rb +64 -0
  82. data/lib/makit/logging/log_request.rb +115 -0
  83. data/lib/makit/logging/logger.rb +163 -0
  84. data/lib/makit/logging/sinks/base.rb +91 -0
  85. data/lib/makit/logging/sinks/console.rb +72 -0
  86. data/lib/makit/logging/sinks/file_sink.rb +92 -0
  87. data/lib/makit/logging/sinks/structured.rb +129 -0
  88. data/lib/makit/logging/sinks/unified_file_sink.rb +303 -0
  89. data/lib/makit/logging.rb +530 -106
  90. data/lib/makit/markdown.rb +75 -75
  91. data/lib/makit/mp/basic_object_mp.rb +17 -16
  92. data/lib/makit/mp/command_mp.rb +13 -13
  93. data/lib/makit/mp/command_request.mp.rb +17 -16
  94. data/lib/makit/mp/project_mp.rb +199 -210
  95. data/lib/makit/mp/string_mp.rb +193 -176
  96. data/lib/makit/nuget.rb +74 -72
  97. data/lib/makit/port.rb +32 -34
  98. data/lib/makit/process.rb +163 -65
  99. data/lib/makit/protoc.rb +107 -104
  100. data/lib/makit/rake/cli.rb +196 -0
  101. data/lib/makit/rake.rb +25 -25
  102. data/lib/makit/ruby/cli.rb +185 -0
  103. data/lib/makit/ruby.rb +25 -0
  104. data/lib/makit/secrets.rb +51 -51
  105. data/lib/makit/serializer.rb +130 -115
  106. data/lib/makit/services/builder.rb +186 -0
  107. data/lib/makit/services/error_handler.rb +226 -0
  108. data/lib/makit/services/repository_manager.rb +229 -0
  109. data/lib/makit/services/validator.rb +112 -0
  110. data/lib/makit/setup/classlib.rb +53 -0
  111. data/lib/makit/setup/gem.rb +263 -0
  112. data/lib/makit/setup/runner.rb +45 -0
  113. data/lib/makit/setup.rb +5 -0
  114. data/lib/makit/show.rb +110 -110
  115. data/lib/makit/storage.rb +126 -131
  116. data/lib/makit/symbols.rb +170 -149
  117. data/lib/makit/task_info.rb +128 -86
  118. data/lib/makit/tasks/at_exit.rb +13 -0
  119. data/lib/makit/tasks/build.rb +19 -0
  120. data/lib/makit/tasks/clean.rb +11 -0
  121. data/lib/makit/tasks/hook_manager.rb +393 -0
  122. data/lib/makit/tasks/init.rb +47 -0
  123. data/lib/makit/tasks/integrate.rb +17 -0
  124. data/lib/makit/tasks/pull_incoming.rb +11 -0
  125. data/lib/makit/tasks/setup.rb +6 -0
  126. data/lib/makit/tasks/sync.rb +12 -0
  127. data/lib/makit/tasks/tag.rb +15 -0
  128. data/lib/makit/tasks/task_monkey_patch.rb +79 -0
  129. data/lib/makit/tasks.rb +15 -150
  130. data/lib/makit/test_cache.rb +239 -0
  131. data/lib/makit/tree.rb +37 -37
  132. data/lib/makit/v1/makit.v1_pb.rb +3 -4
  133. data/lib/makit/v1/makit.v1_services_pb.rb +27 -25
  134. data/lib/makit/version.rb +5 -61
  135. data/lib/makit/version_util.rb +21 -0
  136. data/lib/makit/wix.rb +95 -95
  137. data/lib/makit/yaml.rb +29 -17
  138. data/lib/makit/zip.rb +17 -17
  139. data/lib/makit copy.rb +44 -0
  140. data/lib/makit.rb +40 -267
  141. metadata +117 -110
  142. data/lib/makit/cli/clean.rb +0 -14
  143. data/lib/makit/cli/clone.rb +0 -59
  144. data/lib/makit/cli/init.rb +0 -38
  145. data/lib/makit/cli/make.rb +0 -54
  146. data/lib/makit/cli/new.rb +0 -37
  147. data/lib/makit/cli/nuget_cache.rb +0 -38
  148. data/lib/makit/cli/pull.rb +0 -31
  149. data/lib/makit/cli/setup.rb +0 -71
  150. data/lib/makit/cli/work.rb +0 -21
  151. data/lib/makit/command_runner.rb +0 -404
  152. data/lib/makit/content/default_gitignore.txt +0 -222
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a90f6822da244e01bde51ceea9147ff5e096c65ba77ff1d0eb447080d47682af
4
- data.tar.gz: cda17895074379e842eb717a8e2d0af7580ab134d6037ac0411862421af3c939
3
+ metadata.gz: 46838a2ffa0f2b330292a5be247d3f8cec628ce299d10adcf780e13ba63e2f0b
4
+ data.tar.gz: 3160279cb7e06f6e38a0c65028c22e6446a43978ddd138cad816492709832424
5
5
  SHA512:
6
- metadata.gz: c2cdebafc800836588139bebac0bdf66d96b7a0060a792ab21dafb951f7da111364c631e937c015ded39faa38ee2be82733fea2acd1ecb1be77fb23fab064284
7
- data.tar.gz: 10c1e7ddb62cdeb72e3ddf8beeaf91111441805a3ee046afe51479d4a09d57cd722000cfa10099d8431c68c4b020ac6cb66880371e2c1b6f9e34af6008738adf
6
+ metadata.gz: 60555bc357bb378dd4972a77360beb2dcfd4cd03f494ba654399c341f138e44dfa64a0be44581ca13b019e9956b042128f8ea42ab76d7d9c75643ad529f48918
7
+ data.tar.gz: f8686dc444c15329727defd706e8916014bad0efc134b38ec98006340fe02aaa512d60823ff3a664dc0562b706cb431a4c45e7178feb34386ab48e356cb7600c
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Makit
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/makit`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "makit"
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install makit
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require "makit"
27
+
28
+ # TODO: Write usage instructions here
29
+ ```
30
+
31
+ ## Development
32
+
33
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/makit.
38
+
39
+ ## License
40
+
41
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/exe/makit ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "makit"
5
+ Makit::Cli::MainCommand.run(ARGV)
data/lib/makit/apache.rb CHANGED
@@ -1,32 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- # This module provides classes for the Makit gem.
4
- module Makit
5
- # This class provide methods for working with the system Environment.
6
- #
7
- class Apache
8
- def self.server_root
9
- os = Makit::Environment::get_os
10
- if os == "windows"
11
- "C:\\Apache24"
12
- elsif os == "linux"
13
- "/etc/apache2"
14
- elsif os == "mac"
15
- "/private/etc/apache2"
16
- else
17
- nil
18
- end
19
- # default on windows: C:\Apache24
20
- # default on linux: /etc/apache2
21
- # default on mac: /private/etc/apache2
22
- #nil
23
- end
24
-
25
- def self.document_root
26
- # default on windows: C:\Apache24\htdocs
27
- # default on linux: /var/www/html
28
- # default on mac: /Library/WebServer/Documents
29
- nil
30
- end
31
- end
32
- end
1
+ # frozen_string_literal: true
2
+
3
+ # This module provides classes for the Makit gem.
4
+ module Makit
5
+ # This class provide methods for working with the system Environment.
6
+ #
7
+ class Apache
8
+ def self.server_root
9
+ os = Makit::Environment.get_os
10
+ {
11
+ "windows" => "C:\\Apache24",
12
+ "linux" => "/etc/apache2",
13
+ "mac" => "/private/etc/apache2",
14
+ }[os]
15
+ # default on windows: C:\Apache24
16
+ # default on linux: /etc/apache2
17
+ # default on mac: /private/etc/apache2
18
+ # nil
19
+ end
20
+
21
+ def self.document_root
22
+ # default on windows: C:\Apache24\htdocs
23
+ # default on linux: /var/www/html
24
+ # default on mac: /Library/WebServer/Documents
25
+ nil
26
+ end
27
+ end
28
+ end
@@ -0,0 +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
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Makit
6
+ module Cli
7
+ module Generators
8
+ # Base class for all project generators providing common functionality
9
+ class BaseGenerator
10
+ attr_reader :name, :options
11
+
12
+ def initialize(name, options = {})
13
+ @name = name
14
+ @options = options
15
+ end
16
+
17
+ # Main generation method - creates the complete project structure
18
+ def generate(project_dir)
19
+ create_directory_structure(project_dir)
20
+ create_files(project_dir)
21
+ display_success_message(project_dir)
22
+ end
23
+
24
+ protected
25
+
26
+ # Create the basic directory structure
27
+ def create_directory_structure(project_dir)
28
+ FileUtils.mkdir_p(project_dir)
29
+ end
30
+
31
+ # Create all files defined by the generator
32
+ def create_files(project_dir)
33
+ file_definitions.each do |file_path, template_method|
34
+ content = send(template_method)
35
+ create_file(File.join(project_dir, file_path), content)
36
+ end
37
+ end
38
+
39
+ # Create a single file with given content
40
+ def create_file(path, content)
41
+ FileUtils.mkdir_p(File.dirname(path))
42
+ File.write(path, content)
43
+ end
44
+
45
+ # Display success message and next steps
46
+ def display_success_message(project_dir)
47
+ puts "#{project_type} '#{name}' created successfully!"
48
+ puts "Next steps:"
49
+ puts " cd #{project_dir}"
50
+ display_custom_next_steps
51
+ end
52
+
53
+ # Display project-specific next steps
54
+ def display_custom_next_steps
55
+ puts " git init"
56
+ puts " git add ."
57
+ puts " git commit -m 'Initial commit'"
58
+ end
59
+
60
+ # Template methods to be implemented by subclasses
61
+
62
+ # Returns a hash mapping file paths to template method names
63
+ def file_definitions
64
+ raise NotImplementedError, "Subclasses must implement file_definitions"
65
+ end
66
+
67
+ # Returns a human-readable description of the project type
68
+ def project_type
69
+ raise NotImplementedError, "Subclasses must implement project_type"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end