makit 0.0.157 → 0.0.158

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 (177) 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 +40 -40
  79. data/lib/makit/git/cli.rb +78 -54
  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 +74 -74
  112. data/lib/makit/podman/podman.rb +458 -458
  113. data/lib/makit/podman/podman_service_impl.rb +1081 -1081
  114. data/lib/makit/port.rb +32 -32
  115. data/lib/makit/process.rb +377 -377
  116. data/lib/makit/protoc.rb +112 -112
  117. data/lib/makit/rake/cli.rb +196 -196
  118. data/lib/makit/rake/trace_controller.rb +174 -174
  119. data/lib/makit/rake.rb +81 -81
  120. data/lib/makit/ruby/cli.rb +185 -185
  121. data/lib/makit/ruby.rb +25 -25
  122. data/lib/makit/rubygems.rb +137 -0
  123. data/lib/makit/secrets/azure_key_vault.rb +322 -322
  124. data/lib/makit/secrets/azure_secrets.rb +183 -183
  125. data/lib/makit/secrets/local_secrets.rb +72 -72
  126. data/lib/makit/secrets/secrets_manager.rb +105 -105
  127. data/lib/makit/secrets.rb +16 -16
  128. data/lib/makit/serializer.rb +130 -130
  129. data/lib/makit/services/builder.rb +186 -186
  130. data/lib/makit/services/error_handler.rb +226 -226
  131. data/lib/makit/services/repository_manager.rb +367 -367
  132. data/lib/makit/services/validator.rb +112 -112
  133. data/lib/makit/setup/classlib.rb +101 -101
  134. data/lib/makit/setup/gem.rb +268 -268
  135. data/lib/makit/setup/pages.rb +11 -11
  136. data/lib/makit/setup/razorclasslib.rb +101 -101
  137. data/lib/makit/setup/runner.rb +54 -54
  138. data/lib/makit/setup.rb +5 -5
  139. data/lib/makit/show.rb +110 -110
  140. data/lib/makit/storage.rb +126 -126
  141. data/lib/makit/symbols.rb +175 -175
  142. data/lib/makit/task_info.rb +130 -130
  143. data/lib/makit/tasks/at_exit.rb +15 -15
  144. data/lib/makit/tasks/build.rb +22 -22
  145. data/lib/makit/tasks/bump.rb +7 -7
  146. data/lib/makit/tasks/clean.rb +13 -13
  147. data/lib/makit/tasks/configure.rb +10 -10
  148. data/lib/makit/tasks/format.rb +10 -10
  149. data/lib/makit/tasks/hook_manager.rb +443 -443
  150. data/lib/makit/tasks/info.rb +368 -368
  151. data/lib/makit/tasks/init.rb +49 -49
  152. data/lib/makit/tasks/integrate.rb +60 -56
  153. data/lib/makit/tasks/pull_incoming.rb +13 -13
  154. data/lib/makit/tasks/secrets.rb +7 -7
  155. data/lib/makit/tasks/setup.rb +16 -16
  156. data/lib/makit/tasks/sync.rb +14 -17
  157. data/lib/makit/tasks/tag.rb +27 -27
  158. data/lib/makit/tasks/task_monkey_patch.rb +81 -81
  159. data/lib/makit/tasks/test.rb +22 -22
  160. data/lib/makit/tasks/update.rb +18 -18
  161. data/lib/makit/tasks/version.rb +6 -6
  162. data/lib/makit/tasks.rb +24 -24
  163. data/lib/makit/test_cache.rb +239 -239
  164. data/lib/makit/tree.rb +37 -37
  165. data/lib/makit/v1/configuration/project_service_impl.rb +370 -370
  166. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -295
  167. data/lib/makit/v1/makit.v1_pb.rb +35 -35
  168. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  169. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -572
  170. data/lib/makit/version.rb +661 -503
  171. data/lib/makit/version_util.rb +21 -21
  172. data/lib/makit/wix.rb +95 -95
  173. data/lib/makit/yaml.rb +29 -29
  174. data/lib/makit/zip.rb +17 -17
  175. data/lib/makit copy.rb +44 -44
  176. data/lib/makit.rb +115 -114
  177. metadata +3 -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