makit 0.0.158 → 0.0.162

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -41
  3. data/exe/makit +5 -5
  4. data/lib/makit/apache.rb +28 -28
  5. data/lib/makit/auto.rb +48 -48
  6. data/lib/makit/azure/blob_storage.rb +257 -257
  7. data/lib/makit/azure/cli.rb +284 -284
  8. data/lib/makit/cli/base.rb +17 -17
  9. data/lib/makit/cli/build_commands.rb +500 -500
  10. data/lib/makit/cli/generators/base_generator.rb +74 -74
  11. data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
  12. data/lib/makit/cli/generators/generator_factory.rb +49 -49
  13. data/lib/makit/cli/generators/node_generator.rb +50 -50
  14. data/lib/makit/cli/generators/ruby_generator.rb +77 -77
  15. data/lib/makit/cli/generators/rust_generator.rb +50 -50
  16. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
  17. data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
  18. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
  19. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +41 -41
  20. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
  21. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
  22. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
  23. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
  24. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
  25. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
  26. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
  27. data/lib/makit/cli/main.rb +78 -78
  28. data/lib/makit/cli/pipeline_commands.rb +311 -311
  29. data/lib/makit/cli/project_commands.rb +868 -868
  30. data/lib/makit/cli/repository_commands.rb +661 -661
  31. data/lib/makit/cli/strategy_commands.rb +207 -207
  32. data/lib/makit/cli/utility_commands.rb +521 -521
  33. data/lib/makit/commands/factory.rb +359 -359
  34. data/lib/makit/commands/middleware/base.rb +73 -73
  35. data/lib/makit/commands/middleware/cache.rb +248 -248
  36. data/lib/makit/commands/middleware/command_logger.rb +312 -312
  37. data/lib/makit/commands/middleware/validator.rb +269 -269
  38. data/lib/makit/commands/request.rb +316 -316
  39. data/lib/makit/commands/result.rb +323 -323
  40. data/lib/makit/commands/runner.rb +386 -386
  41. data/lib/makit/commands/strategies/base.rb +171 -171
  42. data/lib/makit/commands/strategies/child_process.rb +162 -162
  43. data/lib/makit/commands/strategies/factory.rb +136 -136
  44. data/lib/makit/commands/strategies/synchronous.rb +139 -139
  45. data/lib/makit/commands.rb +50 -50
  46. data/lib/makit/configuration/dotnet_project.rb +48 -48
  47. data/lib/makit/configuration/gitlab_helper.rb +61 -61
  48. data/lib/makit/configuration/project.rb +292 -292
  49. data/lib/makit/configuration/rakefile_helper.rb +43 -43
  50. data/lib/makit/configuration/step.rb +34 -34
  51. data/lib/makit/configuration/timeout.rb +74 -74
  52. data/lib/makit/configuration.rb +21 -21
  53. data/lib/makit/content/default_gitignore.rb +7 -7
  54. data/lib/makit/content/default_gitignore.txt +225 -225
  55. data/lib/makit/content/default_rakefile.rb +13 -13
  56. data/lib/makit/content/gem_rakefile.rb +16 -16
  57. data/lib/makit/context.rb +1 -1
  58. data/lib/makit/data.rb +49 -49
  59. data/lib/makit/directories.rb +170 -170
  60. data/lib/makit/directory.rb +262 -262
  61. data/lib/makit/docs/files.rb +89 -89
  62. data/lib/makit/docs/rake.rb +102 -102
  63. data/lib/makit/dotnet/cli.rb +69 -69
  64. data/lib/makit/dotnet/project.rb +217 -217
  65. data/lib/makit/dotnet/solution.rb +38 -38
  66. data/lib/makit/dotnet/solution_classlib.rb +239 -239
  67. data/lib/makit/dotnet/solution_console.rb +264 -264
  68. data/lib/makit/dotnet/solution_maui.rb +354 -354
  69. data/lib/makit/dotnet/solution_wasm.rb +275 -275
  70. data/lib/makit/dotnet/solution_wpf.rb +304 -304
  71. data/lib/makit/dotnet.rb +102 -102
  72. data/lib/makit/email.rb +90 -90
  73. data/lib/makit/environment.rb +142 -142
  74. data/lib/makit/examples/runner.rb +370 -370
  75. data/lib/makit/exceptions.rb +45 -45
  76. data/lib/makit/fileinfo.rb +32 -32
  77. data/lib/makit/files.rb +43 -43
  78. data/lib/makit/gems.rb +49 -40
  79. data/lib/makit/git/cli.rb +103 -78
  80. data/lib/makit/git/repository.rb +100 -100
  81. data/lib/makit/git.rb +104 -104
  82. data/lib/makit/gitlab/pipeline.rb +857 -857
  83. data/lib/makit/gitlab/pipeline_service_impl.rb +1535 -1535
  84. data/lib/makit/gitlab_runner.rb +59 -59
  85. data/lib/makit/humanize.rb +218 -218
  86. data/lib/makit/indexer.rb +47 -47
  87. data/lib/makit/io/filesystem.rb +111 -111
  88. data/lib/makit/io/filesystem_service_impl.rb +337 -337
  89. data/lib/makit/lint.rb +212 -212
  90. data/lib/makit/logging/configuration.rb +309 -309
  91. data/lib/makit/logging/format_registry.rb +84 -84
  92. data/lib/makit/logging/formatters/base.rb +39 -39
  93. data/lib/makit/logging/formatters/console_formatter.rb +140 -140
  94. data/lib/makit/logging/formatters/json_formatter.rb +65 -65
  95. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
  96. data/lib/makit/logging/formatters/text_formatter.rb +64 -64
  97. data/lib/makit/logging/log_request.rb +119 -119
  98. data/lib/makit/logging/logger.rb +199 -199
  99. data/lib/makit/logging/sinks/base.rb +91 -91
  100. data/lib/makit/logging/sinks/console.rb +72 -72
  101. data/lib/makit/logging/sinks/file_sink.rb +92 -92
  102. data/lib/makit/logging/sinks/structured.rb +123 -123
  103. data/lib/makit/logging/sinks/unified_file_sink.rb +296 -296
  104. data/lib/makit/logging.rb +578 -578
  105. data/lib/makit/markdown.rb +75 -75
  106. data/lib/makit/mp/basic_object_mp.rb +17 -17
  107. data/lib/makit/mp/command_mp.rb +13 -13
  108. data/lib/makit/mp/command_request.mp.rb +17 -17
  109. data/lib/makit/mp/project_mp.rb +199 -199
  110. data/lib/makit/mp/string_mp.rb +205 -205
  111. data/lib/makit/nuget.rb +243 -74
  112. data/lib/makit/nuget_cache.rb +123 -0
  113. data/lib/makit/podman/podman.rb +458 -458
  114. data/lib/makit/podman/podman_service_impl.rb +1081 -1081
  115. data/lib/makit/port.rb +32 -32
  116. data/lib/makit/port_utility.rb +128 -0
  117. data/lib/makit/process.rb +377 -377
  118. data/lib/makit/protoc.rb +112 -112
  119. data/lib/makit/rake/cli.rb +196 -196
  120. data/lib/makit/rake/trace_controller.rb +174 -174
  121. data/lib/makit/rake.rb +81 -81
  122. data/lib/makit/ruby/cli.rb +185 -185
  123. data/lib/makit/ruby.rb +25 -25
  124. data/lib/makit/rubygems.rb +137 -137
  125. data/lib/makit/secrets/azure_key_vault.rb +322 -322
  126. data/lib/makit/secrets/azure_secrets.rb +183 -183
  127. data/lib/makit/secrets/local_secrets.rb +72 -72
  128. data/lib/makit/secrets/secrets_manager.rb +105 -105
  129. data/lib/makit/secrets.rb +16 -16
  130. data/lib/makit/serializer.rb +130 -130
  131. data/lib/makit/services/builder.rb +186 -186
  132. data/lib/makit/services/error_handler.rb +226 -226
  133. data/lib/makit/services/repository_manager.rb +367 -367
  134. data/lib/makit/services/validator.rb +112 -112
  135. data/lib/makit/setup/classlib.rb +101 -101
  136. data/lib/makit/setup/gem.rb +268 -268
  137. data/lib/makit/setup/pages.rb +11 -11
  138. data/lib/makit/setup/razorclasslib.rb +101 -101
  139. data/lib/makit/setup/runner.rb +54 -54
  140. data/lib/makit/setup.rb +5 -5
  141. data/lib/makit/show.rb +110 -110
  142. data/lib/makit/storage.rb +126 -126
  143. data/lib/makit/symbols.rb +175 -175
  144. data/lib/makit/task_info.rb +130 -130
  145. data/lib/makit/tasks/at_exit.rb +15 -15
  146. data/lib/makit/tasks/build.rb +22 -22
  147. data/lib/makit/tasks/bump.rb +7 -7
  148. data/lib/makit/tasks/clean.rb +13 -13
  149. data/lib/makit/tasks/configure.rb +10 -10
  150. data/lib/makit/tasks/format.rb +10 -10
  151. data/lib/makit/tasks/hook_manager.rb +443 -443
  152. data/lib/makit/tasks/info.rb +368 -368
  153. data/lib/makit/tasks/init.rb +49 -49
  154. data/lib/makit/tasks/integrate.rb +60 -60
  155. data/lib/makit/tasks/pull_incoming.rb +13 -13
  156. data/lib/makit/tasks/secrets.rb +7 -7
  157. data/lib/makit/tasks/setup.rb +16 -16
  158. data/lib/makit/tasks/sync.rb +14 -14
  159. data/lib/makit/tasks/tag.rb +27 -27
  160. data/lib/makit/tasks/task_monkey_patch.rb +81 -81
  161. data/lib/makit/tasks/test.rb +22 -22
  162. data/lib/makit/tasks/update.rb +21 -18
  163. data/lib/makit/tasks/version.rb +6 -6
  164. data/lib/makit/tasks.rb +24 -24
  165. data/lib/makit/test_cache.rb +239 -239
  166. data/lib/makit/tree.rb +37 -37
  167. data/lib/makit/v1/configuration/project_service_impl.rb +370 -370
  168. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -295
  169. data/lib/makit/v1/makit.v1_pb.rb +35 -35
  170. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  171. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -572
  172. data/lib/makit/version.rb +661 -661
  173. data/lib/makit/version_util.rb +21 -21
  174. data/lib/makit/wix.rb +95 -95
  175. data/lib/makit/yaml.rb +29 -29
  176. data/lib/makit/zip.rb +17 -17
  177. data/lib/makit/zip_utility.rb +97 -0
  178. data/lib/makit copy.rb +44 -44
  179. data/lib/makit.rb +119 -115
  180. metadata +5 -2
@@ -1,371 +1,371 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../../generated/makit/v1/configuration/project_service_services_pb"
4
- require_relative "../../configuration/gitlab_helper"
5
- require_relative "../../configuration/rakefile_helper"
6
- require_relative "../../configuration/step"
7
-
8
- module Makit
9
- module V1
10
- module Configuration
11
- # gRPC service implementation for ProjectService
12
- # Implements all the RPC methods defined in the protobuf service definition
13
- class ProjectServiceImpl < ProjectService::Service
14
- # Load a project from a JSON file
15
- def load_from_file(request, _unused_call)
16
- raise ArgumentError, "File does not exist: #{request.path}" unless File.exist?(request.path)
17
-
18
- content = File.read(request.path)
19
- data = JSON.parse(content, symbolize_names: true)
20
-
21
- project = convert_from_json_data(data)
22
- project
23
- rescue ArgumentError => e
24
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
25
- rescue StandardError => e
26
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
27
- end
28
-
29
- # Load a project from JSON string
30
- def load_from_json(request, _unused_call)
31
- raise ArgumentError, "JSON string cannot be empty" if request.json_string.nil? || request.json_string.strip.empty?
32
-
33
- data = JSON.parse(request.json_string, symbolize_names: true)
34
- project = convert_from_json_data(data)
35
- project
36
- rescue ArgumentError => e
37
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
38
- rescue StandardError => e
39
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
40
- end
41
-
42
- # Save a project to a specific path as pretty JSON
43
- def save_to_file(request, _unused_call)
44
- validate_project_model(request.project)
45
- raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
46
-
47
- File.write(request.path, convert_to_json_pretty(request.project))
48
- Google::Protobuf::Empty.new
49
- rescue ArgumentError => e
50
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
51
- rescue StandardError => e
52
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
53
- end
54
-
55
- # Save a project to the default .makit.json file
56
- def save_to_default(request, _unused_call)
57
- validate_project_model(request.project)
58
- File.write(".makit.json", convert_to_json_pretty(request.project))
59
- Google::Protobuf::Empty.new
60
- rescue ArgumentError => e
61
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
62
- rescue StandardError => e
63
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
64
- end
65
-
66
- # Load the default project from .makit.json or create a new one
67
- def load_default(request, _unused_call)
68
- if File.exist?(".makit.json")
69
- load_from_file(LoadFromFileRequest.new(path: ".makit.json"), nil)
70
- else
71
- project = Project.new(
72
- name: "",
73
- version: "0.0.0",
74
- project_type: "",
75
- authors: "authors",
76
- description: "description",
77
- license_expression: "MIT",
78
- steps: []
79
- )
80
- #Makit::Logging.default_logger.warn("Project not configured")
81
- project
82
- end
83
- rescue StandardError => e
84
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
85
- end
86
-
87
- # Generate GitLab CI YAML from project
88
- def generate_gitlab_ci(request, _unused_call)
89
- validate_project_model(request.project)
90
- raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
91
-
92
- # Convert protobuf model to Ruby model for GitLab helper
93
- ruby_model = convert_to_ruby_model(request.project)
94
- Makit::Configuration::GitLabHelper.to_yaml(ruby_model, request.path)
95
- Google::Protobuf::Empty.new
96
- rescue ArgumentError => e
97
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
98
- rescue StandardError => e
99
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
100
- end
101
-
102
- # Generate Rakefile from project
103
- def generate_rakefile(request, _unused_call)
104
- validate_project_model(request.project)
105
-
106
- # Convert protobuf model to Ruby model for Rakefile helper
107
- ruby_model = convert_to_ruby_model(request.project)
108
- content = Makit::Configuration::RakefileHelper.generate(ruby_model)
109
- GenerateRakefileResponse.new(content: content)
110
- rescue ArgumentError => e
111
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
112
- rescue StandardError => e
113
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
114
- end
115
-
116
- # Write Rakefile to file
117
- def write_rakefile(request, _unused_call)
118
- validate_project_model(request.project)
119
- raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
120
-
121
- # Convert protobuf model to Ruby model for Rakefile helper
122
- ruby_model = convert_to_ruby_model(request.project)
123
- Makit::Configuration::RakefileHelper.write(ruby_model, request.path)
124
- Google::Protobuf::Empty.new
125
- rescue ArgumentError => e
126
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
127
- rescue StandardError => e
128
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
129
- end
130
-
131
- # Validate project configuration
132
- def validate_project(request, _unused_call)
133
- errors = validate_project_model_errors(request.project)
134
- ValidateProjectResponse.new(errors: errors)
135
- rescue StandardError => e
136
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
137
- end
138
-
139
- # Merge two project configurations
140
- def merge_projects(request, _unused_call)
141
- merged = Project.new(
142
- git_remote_url: request.override_project.git_remote_url || request.base_project.git_remote_url,
143
- name: request.override_project.name || request.base_project.name,
144
- version: request.override_project.version || request.base_project.version,
145
- project_type: request.override_project.project_type || request.base_project.project_type,
146
- authors: request.override_project.authors || request.base_project.authors,
147
- description: request.override_project.description || request.base_project.description,
148
- license_expression: request.override_project.license_expression || request.base_project.license_expression,
149
- dotnet_projects: request.override_project.dotnet_projects.any? ? request.override_project.dotnet_projects.to_a : request.base_project.dotnet_projects.to_a,
150
- steps: request.override_project.steps.any? ? request.override_project.steps.to_a : request.base_project.steps.to_a
151
- )
152
- merged
153
- rescue StandardError => e
154
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
155
- end
156
-
157
- # Create a new project with default values
158
- def create_project(request, _unused_call)
159
- raise ArgumentError, "Project name cannot be empty" if request.name.nil? || request.name.strip.empty?
160
-
161
- project = Project.new(
162
- name: request.name,
163
- version: request.version || "0.0.0",
164
- project_type: request.project_type || "gem",
165
- authors: "authors",
166
- description: "description",
167
- license_expression: "MIT",
168
- steps: []
169
- )
170
- project
171
- rescue ArgumentError => e
172
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
173
- rescue StandardError => e
174
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
175
- end
176
-
177
- # Update project with new values
178
- def update_project(request, _unused_call)
179
- updated_project = Project.new(
180
- git_remote_url: request.project.git_remote_url,
181
- name: request.project.name,
182
- version: request.project.version,
183
- project_type: request.project.project_type,
184
- authors: request.project.authors,
185
- description: request.project.description,
186
- license_expression: request.project.license_expression,
187
- dotnet_projects: request.project.dotnet_projects.to_a,
188
- steps: request.project.steps.to_a
189
- )
190
-
191
- # Apply updates
192
- request.updates.each do |key, value|
193
- case key.to_sym
194
- when :name
195
- updated_project.name = value
196
- when :version
197
- updated_project.version = value
198
- when :project_type
199
- updated_project.project_type = value
200
- when :authors
201
- updated_project.authors = value
202
- when :description
203
- updated_project.description = value
204
- when :license_expression
205
- updated_project.license_expression = value
206
- when :git_remote_url
207
- updated_project.git_remote_url = value
208
- end
209
- end
210
-
211
- updated_project
212
- rescue StandardError => e
213
- raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
214
- end
215
-
216
- private
217
-
218
- # Validate project model
219
- def validate_project_model(project)
220
- errors = validate_project_model_errors(project)
221
- raise ArgumentError, errors.join(", ") if errors.any?
222
- errors
223
- end
224
-
225
- # Validate project model and return errors without raising
226
- def validate_project_model_errors(project)
227
- errors = []
228
-
229
- errors << "Project name cannot be empty" if project.name.nil? || project.name.strip.empty?
230
- errors << "Project version cannot be empty" if project.version.nil? || project.version.strip.empty?
231
- errors << "Project type cannot be empty" if project.project_type.nil? || project.project_type.strip.empty?
232
-
233
- # Validate steps
234
- project.steps.each_with_index do |step, index|
235
- errors << "Step #{index} name cannot be empty" if step.name.nil? || step.name.strip.empty?
236
- errors << "Step #{index} description cannot be empty" if step.description.nil? || step.description.strip.empty?
237
- errors << "Step #{index} commands cannot be empty" if step.commands.nil? || step.commands.empty?
238
- end
239
-
240
- errors
241
- end
242
-
243
- # Convert JSON data to Project
244
- def convert_from_json_data(data)
245
- project = Project.new(
246
- git_remote_url: data[:git_remote_url] || "",
247
- name: data[:name] || "",
248
- version: data[:version] || "",
249
- project_type: data[:project_type] || "",
250
- authors: data[:authors] || "authors",
251
- description: data[:description] || "description",
252
- license_expression: data[:license_expression] || "MIT",
253
- dotnet_projects: data[:dotnet_projects] || []
254
- )
255
-
256
- # Convert steps
257
- (data[:steps] || []).each do |step_data|
258
- step = Step.new(
259
- name: step_data[:name] || "",
260
- description: step_data[:description] || "",
261
- commands: step_data[:commands] || []
262
- )
263
- project.steps << step
264
- end
265
-
266
- project
267
- end
268
-
269
- # Convert Project to pretty JSON
270
- def convert_to_json_pretty(project)
271
- project_data = {
272
- name: project.name,
273
- version: project.version,
274
- project_type: project.project_type,
275
- authors: project.authors,
276
- description: project.description,
277
- license_expression: project.license_expression,
278
- steps: project.steps.map do |step|
279
- {
280
- name: step.name,
281
- description: step.description,
282
- commands: step.commands.to_a
283
- }
284
- end
285
- }
286
-
287
- JSON.pretty_generate(project_data)
288
- end
289
-
290
- # Convert Protobuf Project to Ruby model for helper classes
291
- def convert_to_ruby_model(proto_model)
292
- # Create a simple Ruby object that mimics the Project interface
293
- ruby_model = Object.new
294
-
295
- def ruby_model.name
296
- @name
297
- end
298
-
299
- def ruby_model.name=(value)
300
- @name = value
301
- end
302
-
303
- def ruby_model.version
304
- @version
305
- end
306
-
307
- def ruby_model.version=(value)
308
- @version = value
309
- end
310
-
311
- def ruby_model.project_type
312
- @project_type
313
- end
314
-
315
- def ruby_model.project_type=(value)
316
- @project_type = value
317
- end
318
-
319
- def ruby_model.steps
320
- @steps ||= []
321
- end
322
-
323
- def ruby_model.steps=(value)
324
- @steps = value
325
- end
326
-
327
- ruby_model.name = proto_model.name
328
- ruby_model.version = proto_model.version
329
- ruby_model.project_type = proto_model.project_type
330
-
331
- # Convert steps
332
- ruby_steps = proto_model.steps.map do |proto_step|
333
- ruby_step = Object.new
334
-
335
- def ruby_step.name
336
- @name
337
- end
338
-
339
- def ruby_step.name=(value)
340
- @name = value
341
- end
342
-
343
- def ruby_step.description
344
- @description
345
- end
346
-
347
- def ruby_step.description=(value)
348
- @description = value
349
- end
350
-
351
- def ruby_step.commands
352
- @commands ||= []
353
- end
354
-
355
- def ruby_step.commands=(value)
356
- @commands = value
357
- end
358
-
359
- ruby_step.name = proto_step.name
360
- ruby_step.description = proto_step.description
361
- ruby_step.commands = proto_step.commands.to_a
362
- ruby_step
363
- end
364
-
365
- ruby_model.steps = ruby_steps
366
- ruby_model
367
- end
368
- end
369
- end
370
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../generated/makit/v1/configuration/project_service_services_pb"
4
+ require_relative "../../configuration/gitlab_helper"
5
+ require_relative "../../configuration/rakefile_helper"
6
+ require_relative "../../configuration/step"
7
+
8
+ module Makit
9
+ module V1
10
+ module Configuration
11
+ # gRPC service implementation for ProjectService
12
+ # Implements all the RPC methods defined in the protobuf service definition
13
+ class ProjectServiceImpl < ProjectService::Service
14
+ # Load a project from a JSON file
15
+ def load_from_file(request, _unused_call)
16
+ raise ArgumentError, "File does not exist: #{request.path}" unless File.exist?(request.path)
17
+
18
+ content = File.read(request.path)
19
+ data = JSON.parse(content, symbolize_names: true)
20
+
21
+ project = convert_from_json_data(data)
22
+ project
23
+ rescue ArgumentError => e
24
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
25
+ rescue StandardError => e
26
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
27
+ end
28
+
29
+ # Load a project from JSON string
30
+ def load_from_json(request, _unused_call)
31
+ raise ArgumentError, "JSON string cannot be empty" if request.json_string.nil? || request.json_string.strip.empty?
32
+
33
+ data = JSON.parse(request.json_string, symbolize_names: true)
34
+ project = convert_from_json_data(data)
35
+ project
36
+ rescue ArgumentError => e
37
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
38
+ rescue StandardError => e
39
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
40
+ end
41
+
42
+ # Save a project to a specific path as pretty JSON
43
+ def save_to_file(request, _unused_call)
44
+ validate_project_model(request.project)
45
+ raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
46
+
47
+ File.write(request.path, convert_to_json_pretty(request.project))
48
+ Google::Protobuf::Empty.new
49
+ rescue ArgumentError => e
50
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
51
+ rescue StandardError => e
52
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
53
+ end
54
+
55
+ # Save a project to the default .makit.json file
56
+ def save_to_default(request, _unused_call)
57
+ validate_project_model(request.project)
58
+ File.write(".makit.json", convert_to_json_pretty(request.project))
59
+ Google::Protobuf::Empty.new
60
+ rescue ArgumentError => e
61
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
62
+ rescue StandardError => e
63
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
64
+ end
65
+
66
+ # Load the default project from .makit.json or create a new one
67
+ def load_default(request, _unused_call)
68
+ if File.exist?(".makit.json")
69
+ load_from_file(LoadFromFileRequest.new(path: ".makit.json"), nil)
70
+ else
71
+ project = Project.new(
72
+ name: "",
73
+ version: "0.0.0",
74
+ project_type: "",
75
+ authors: "authors",
76
+ description: "description",
77
+ license_expression: "MIT",
78
+ steps: []
79
+ )
80
+ #Makit::Logging.default_logger.warn("Project not configured")
81
+ project
82
+ end
83
+ rescue StandardError => e
84
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
85
+ end
86
+
87
+ # Generate GitLab CI YAML from project
88
+ def generate_gitlab_ci(request, _unused_call)
89
+ validate_project_model(request.project)
90
+ raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
91
+
92
+ # Convert protobuf model to Ruby model for GitLab helper
93
+ ruby_model = convert_to_ruby_model(request.project)
94
+ Makit::Configuration::GitLabHelper.to_yaml(ruby_model, request.path)
95
+ Google::Protobuf::Empty.new
96
+ rescue ArgumentError => e
97
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
98
+ rescue StandardError => e
99
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
100
+ end
101
+
102
+ # Generate Rakefile from project
103
+ def generate_rakefile(request, _unused_call)
104
+ validate_project_model(request.project)
105
+
106
+ # Convert protobuf model to Ruby model for Rakefile helper
107
+ ruby_model = convert_to_ruby_model(request.project)
108
+ content = Makit::Configuration::RakefileHelper.generate(ruby_model)
109
+ GenerateRakefileResponse.new(content: content)
110
+ rescue ArgumentError => e
111
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
112
+ rescue StandardError => e
113
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
114
+ end
115
+
116
+ # Write Rakefile to file
117
+ def write_rakefile(request, _unused_call)
118
+ validate_project_model(request.project)
119
+ raise ArgumentError, "Path cannot be empty" if request.path.nil? || request.path.strip.empty?
120
+
121
+ # Convert protobuf model to Ruby model for Rakefile helper
122
+ ruby_model = convert_to_ruby_model(request.project)
123
+ Makit::Configuration::RakefileHelper.write(ruby_model, request.path)
124
+ Google::Protobuf::Empty.new
125
+ rescue ArgumentError => e
126
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
127
+ rescue StandardError => e
128
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
129
+ end
130
+
131
+ # Validate project configuration
132
+ def validate_project(request, _unused_call)
133
+ errors = validate_project_model_errors(request.project)
134
+ ValidateProjectResponse.new(errors: errors)
135
+ rescue StandardError => e
136
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
137
+ end
138
+
139
+ # Merge two project configurations
140
+ def merge_projects(request, _unused_call)
141
+ merged = Project.new(
142
+ git_remote_url: request.override_project.git_remote_url || request.base_project.git_remote_url,
143
+ name: request.override_project.name || request.base_project.name,
144
+ version: request.override_project.version || request.base_project.version,
145
+ project_type: request.override_project.project_type || request.base_project.project_type,
146
+ authors: request.override_project.authors || request.base_project.authors,
147
+ description: request.override_project.description || request.base_project.description,
148
+ license_expression: request.override_project.license_expression || request.base_project.license_expression,
149
+ dotnet_projects: request.override_project.dotnet_projects.any? ? request.override_project.dotnet_projects.to_a : request.base_project.dotnet_projects.to_a,
150
+ steps: request.override_project.steps.any? ? request.override_project.steps.to_a : request.base_project.steps.to_a
151
+ )
152
+ merged
153
+ rescue StandardError => e
154
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
155
+ end
156
+
157
+ # Create a new project with default values
158
+ def create_project(request, _unused_call)
159
+ raise ArgumentError, "Project name cannot be empty" if request.name.nil? || request.name.strip.empty?
160
+
161
+ project = Project.new(
162
+ name: request.name,
163
+ version: request.version || "0.0.0",
164
+ project_type: request.project_type || "gem",
165
+ authors: "authors",
166
+ description: "description",
167
+ license_expression: "MIT",
168
+ steps: []
169
+ )
170
+ project
171
+ rescue ArgumentError => e
172
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INVALID_ARGUMENT, e.message)
173
+ rescue StandardError => e
174
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
175
+ end
176
+
177
+ # Update project with new values
178
+ def update_project(request, _unused_call)
179
+ updated_project = Project.new(
180
+ git_remote_url: request.project.git_remote_url,
181
+ name: request.project.name,
182
+ version: request.project.version,
183
+ project_type: request.project.project_type,
184
+ authors: request.project.authors,
185
+ description: request.project.description,
186
+ license_expression: request.project.license_expression,
187
+ dotnet_projects: request.project.dotnet_projects.to_a,
188
+ steps: request.project.steps.to_a
189
+ )
190
+
191
+ # Apply updates
192
+ request.updates.each do |key, value|
193
+ case key.to_sym
194
+ when :name
195
+ updated_project.name = value
196
+ when :version
197
+ updated_project.version = value
198
+ when :project_type
199
+ updated_project.project_type = value
200
+ when :authors
201
+ updated_project.authors = value
202
+ when :description
203
+ updated_project.description = value
204
+ when :license_expression
205
+ updated_project.license_expression = value
206
+ when :git_remote_url
207
+ updated_project.git_remote_url = value
208
+ end
209
+ end
210
+
211
+ updated_project
212
+ rescue StandardError => e
213
+ raise GRPC::BadStatus.new(GRPC::Core::StatusCodes::INTERNAL, e.message)
214
+ end
215
+
216
+ private
217
+
218
+ # Validate project model
219
+ def validate_project_model(project)
220
+ errors = validate_project_model_errors(project)
221
+ raise ArgumentError, errors.join(", ") if errors.any?
222
+ errors
223
+ end
224
+
225
+ # Validate project model and return errors without raising
226
+ def validate_project_model_errors(project)
227
+ errors = []
228
+
229
+ errors << "Project name cannot be empty" if project.name.nil? || project.name.strip.empty?
230
+ errors << "Project version cannot be empty" if project.version.nil? || project.version.strip.empty?
231
+ errors << "Project type cannot be empty" if project.project_type.nil? || project.project_type.strip.empty?
232
+
233
+ # Validate steps
234
+ project.steps.each_with_index do |step, index|
235
+ errors << "Step #{index} name cannot be empty" if step.name.nil? || step.name.strip.empty?
236
+ errors << "Step #{index} description cannot be empty" if step.description.nil? || step.description.strip.empty?
237
+ errors << "Step #{index} commands cannot be empty" if step.commands.nil? || step.commands.empty?
238
+ end
239
+
240
+ errors
241
+ end
242
+
243
+ # Convert JSON data to Project
244
+ def convert_from_json_data(data)
245
+ project = Project.new(
246
+ git_remote_url: data[:git_remote_url] || "",
247
+ name: data[:name] || "",
248
+ version: data[:version] || "",
249
+ project_type: data[:project_type] || "",
250
+ authors: data[:authors] || "authors",
251
+ description: data[:description] || "description",
252
+ license_expression: data[:license_expression] || "MIT",
253
+ dotnet_projects: data[:dotnet_projects] || []
254
+ )
255
+
256
+ # Convert steps
257
+ (data[:steps] || []).each do |step_data|
258
+ step = Step.new(
259
+ name: step_data[:name] || "",
260
+ description: step_data[:description] || "",
261
+ commands: step_data[:commands] || []
262
+ )
263
+ project.steps << step
264
+ end
265
+
266
+ project
267
+ end
268
+
269
+ # Convert Project to pretty JSON
270
+ def convert_to_json_pretty(project)
271
+ project_data = {
272
+ name: project.name,
273
+ version: project.version,
274
+ project_type: project.project_type,
275
+ authors: project.authors,
276
+ description: project.description,
277
+ license_expression: project.license_expression,
278
+ steps: project.steps.map do |step|
279
+ {
280
+ name: step.name,
281
+ description: step.description,
282
+ commands: step.commands.to_a
283
+ }
284
+ end
285
+ }
286
+
287
+ JSON.pretty_generate(project_data)
288
+ end
289
+
290
+ # Convert Protobuf Project to Ruby model for helper classes
291
+ def convert_to_ruby_model(proto_model)
292
+ # Create a simple Ruby object that mimics the Project interface
293
+ ruby_model = Object.new
294
+
295
+ def ruby_model.name
296
+ @name
297
+ end
298
+
299
+ def ruby_model.name=(value)
300
+ @name = value
301
+ end
302
+
303
+ def ruby_model.version
304
+ @version
305
+ end
306
+
307
+ def ruby_model.version=(value)
308
+ @version = value
309
+ end
310
+
311
+ def ruby_model.project_type
312
+ @project_type
313
+ end
314
+
315
+ def ruby_model.project_type=(value)
316
+ @project_type = value
317
+ end
318
+
319
+ def ruby_model.steps
320
+ @steps ||= []
321
+ end
322
+
323
+ def ruby_model.steps=(value)
324
+ @steps = value
325
+ end
326
+
327
+ ruby_model.name = proto_model.name
328
+ ruby_model.version = proto_model.version
329
+ ruby_model.project_type = proto_model.project_type
330
+
331
+ # Convert steps
332
+ ruby_steps = proto_model.steps.map do |proto_step|
333
+ ruby_step = Object.new
334
+
335
+ def ruby_step.name
336
+ @name
337
+ end
338
+
339
+ def ruby_step.name=(value)
340
+ @name = value
341
+ end
342
+
343
+ def ruby_step.description
344
+ @description
345
+ end
346
+
347
+ def ruby_step.description=(value)
348
+ @description = value
349
+ end
350
+
351
+ def ruby_step.commands
352
+ @commands ||= []
353
+ end
354
+
355
+ def ruby_step.commands=(value)
356
+ @commands = value
357
+ end
358
+
359
+ ruby_step.name = proto_step.name
360
+ ruby_step.description = proto_step.description
361
+ ruby_step.commands = proto_step.commands.to_a
362
+ ruby_step
363
+ end
364
+
365
+ ruby_model.steps = ruby_steps
366
+ ruby_model
367
+ end
368
+ end
369
+ end
370
+ end
371
371
  end