makit 0.0.144 → 0.0.145

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 (165) 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/cli/base.rb +17 -0
  7. data/lib/makit/cli/build_commands.rb +500 -500
  8. data/lib/makit/cli/generators/base_generator.rb +74 -74
  9. data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
  10. data/lib/makit/cli/generators/generator_factory.rb +49 -49
  11. data/lib/makit/cli/generators/node_generator.rb +50 -50
  12. data/lib/makit/cli/generators/ruby_generator.rb +77 -77
  13. data/lib/makit/cli/generators/rust_generator.rb +50 -50
  14. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
  15. data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
  16. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
  17. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +41 -40
  18. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
  19. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
  20. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
  21. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
  22. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
  23. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
  24. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
  25. data/lib/makit/cli/main.rb +78 -69
  26. data/lib/makit/cli/pipeline_commands.rb +311 -0
  27. data/lib/makit/cli/project_commands.rb +868 -868
  28. data/lib/makit/cli/repository_commands.rb +661 -661
  29. data/lib/makit/cli/strategy_commands.rb +207 -212
  30. data/lib/makit/cli/utility_commands.rb +521 -521
  31. data/lib/makit/commands/factory.rb +359 -359
  32. data/lib/makit/commands/middleware/base.rb +73 -73
  33. data/lib/makit/commands/middleware/cache.rb +248 -248
  34. data/lib/makit/commands/middleware/command_logger.rb +312 -312
  35. data/lib/makit/commands/middleware/validator.rb +269 -269
  36. data/lib/makit/commands/request.rb +316 -316
  37. data/lib/makit/commands/result.rb +323 -323
  38. data/lib/makit/commands/runner.rb +386 -386
  39. data/lib/makit/commands/strategies/base.rb +171 -171
  40. data/lib/makit/commands/strategies/child_process.rb +162 -162
  41. data/lib/makit/commands/strategies/factory.rb +136 -136
  42. data/lib/makit/commands/strategies/synchronous.rb +139 -139
  43. data/lib/makit/commands.rb +50 -50
  44. data/lib/makit/configuration/dotnet_project.rb +48 -48
  45. data/lib/makit/configuration/gitlab_helper.rb +61 -58
  46. data/lib/makit/configuration/project.rb +446 -168
  47. data/lib/makit/configuration/rakefile_helper.rb +43 -43
  48. data/lib/makit/configuration/step.rb +34 -34
  49. data/lib/makit/configuration/timeout.rb +74 -74
  50. data/lib/makit/configuration.rb +21 -16
  51. data/lib/makit/content/default_gitignore.rb +7 -7
  52. data/lib/makit/content/default_gitignore.txt +225 -225
  53. data/lib/makit/content/default_rakefile.rb +13 -13
  54. data/lib/makit/content/gem_rakefile.rb +16 -16
  55. data/lib/makit/context.rb +1 -1
  56. data/lib/makit/data.rb +49 -49
  57. data/lib/makit/directories.rb +140 -140
  58. data/lib/makit/directory.rb +262 -262
  59. data/lib/makit/docs/files.rb +89 -89
  60. data/lib/makit/docs/rake.rb +102 -102
  61. data/lib/makit/dotnet/cli.rb +69 -69
  62. data/lib/makit/dotnet/project.rb +217 -217
  63. data/lib/makit/dotnet/solution.rb +38 -38
  64. data/lib/makit/dotnet/solution_classlib.rb +239 -239
  65. data/lib/makit/dotnet/solution_console.rb +264 -264
  66. data/lib/makit/dotnet/solution_maui.rb +354 -354
  67. data/lib/makit/dotnet/solution_wasm.rb +275 -275
  68. data/lib/makit/dotnet/solution_wpf.rb +304 -304
  69. data/lib/makit/dotnet.rb +102 -102
  70. data/lib/makit/email.rb +90 -90
  71. data/lib/makit/environment.rb +142 -142
  72. data/lib/makit/examples/runner.rb +370 -370
  73. data/lib/makit/exceptions.rb +45 -45
  74. data/lib/makit/fileinfo.rb +32 -24
  75. data/lib/makit/files.rb +43 -43
  76. data/lib/makit/gems.rb +40 -40
  77. data/lib/makit/git/cli.rb +54 -54
  78. data/lib/makit/git/repository.rb +266 -90
  79. data/lib/makit/git.rb +104 -98
  80. data/lib/makit/gitlab/pipeline.rb +857 -0
  81. data/lib/makit/gitlab/pipeline_service_impl.rb +1536 -0
  82. data/lib/makit/gitlab_runner.rb +59 -59
  83. data/lib/makit/humanize.rb +218 -137
  84. data/lib/makit/indexer.rb +47 -47
  85. data/lib/makit/io/filesystem.rb +111 -0
  86. data/lib/makit/io/filesystem_service_impl.rb +337 -0
  87. data/lib/makit/logging/configuration.rb +308 -308
  88. data/lib/makit/logging/format_registry.rb +84 -84
  89. data/lib/makit/logging/formatters/base.rb +39 -39
  90. data/lib/makit/logging/formatters/console_formatter.rb +140 -140
  91. data/lib/makit/logging/formatters/json_formatter.rb +65 -65
  92. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
  93. data/lib/makit/logging/formatters/text_formatter.rb +64 -64
  94. data/lib/makit/logging/log_request.rb +119 -119
  95. data/lib/makit/logging/logger.rb +199 -199
  96. data/lib/makit/logging/sinks/base.rb +91 -91
  97. data/lib/makit/logging/sinks/console.rb +72 -72
  98. data/lib/makit/logging/sinks/file_sink.rb +92 -92
  99. data/lib/makit/logging/sinks/structured.rb +123 -123
  100. data/lib/makit/logging/sinks/unified_file_sink.rb +296 -296
  101. data/lib/makit/logging.rb +565 -565
  102. data/lib/makit/markdown.rb +75 -75
  103. data/lib/makit/mp/basic_object_mp.rb +17 -17
  104. data/lib/makit/mp/command_mp.rb +13 -13
  105. data/lib/makit/mp/command_request.mp.rb +17 -17
  106. data/lib/makit/mp/project_mp.rb +199 -199
  107. data/lib/makit/mp/string_mp.rb +205 -199
  108. data/lib/makit/nuget.rb +74 -74
  109. data/lib/makit/podman/podman.rb +458 -0
  110. data/lib/makit/podman/podman_service_impl.rb +1081 -0
  111. data/lib/makit/port.rb +32 -32
  112. data/lib/makit/process.rb +377 -377
  113. data/lib/makit/protoc.rb +112 -107
  114. data/lib/makit/rake/cli.rb +196 -196
  115. data/lib/makit/rake/trace_controller.rb +174 -174
  116. data/lib/makit/rake.rb +81 -81
  117. data/lib/makit/ruby/cli.rb +185 -185
  118. data/lib/makit/ruby.rb +25 -25
  119. data/lib/makit/secrets.rb +51 -51
  120. data/lib/makit/serializer.rb +130 -130
  121. data/lib/makit/services/builder.rb +186 -186
  122. data/lib/makit/services/error_handler.rb +226 -226
  123. data/lib/makit/services/repository_manager.rb +367 -231
  124. data/lib/makit/services/validator.rb +112 -112
  125. data/lib/makit/setup/classlib.rb +101 -101
  126. data/lib/makit/setup/gem.rb +268 -268
  127. data/lib/makit/setup/pages.rb +11 -11
  128. data/lib/makit/setup/razorclasslib.rb +101 -101
  129. data/lib/makit/setup/runner.rb +54 -54
  130. data/lib/makit/setup.rb +5 -5
  131. data/lib/makit/show.rb +110 -110
  132. data/lib/makit/storage.rb +126 -126
  133. data/lib/makit/symbols.rb +175 -170
  134. data/lib/makit/task_info.rb +130 -130
  135. data/lib/makit/tasks/at_exit.rb +15 -15
  136. data/lib/makit/tasks/build.rb +22 -22
  137. data/lib/makit/tasks/clean.rb +13 -13
  138. data/lib/makit/tasks/configure.rb +10 -10
  139. data/lib/makit/tasks/format.rb +10 -10
  140. data/lib/makit/tasks/hook_manager.rb +443 -443
  141. data/lib/makit/tasks/init.rb +49 -49
  142. data/lib/makit/tasks/integrate.rb +29 -29
  143. data/lib/makit/tasks/pull_incoming.rb +13 -13
  144. data/lib/makit/tasks/setup.rb +16 -16
  145. data/lib/makit/tasks/sync.rb +17 -17
  146. data/lib/makit/tasks/tag.rb +16 -16
  147. data/lib/makit/tasks/task_monkey_patch.rb +81 -81
  148. data/lib/makit/tasks/test.rb +22 -22
  149. data/lib/makit/tasks/update.rb +18 -18
  150. data/lib/makit/tasks.rb +20 -20
  151. data/lib/makit/test_cache.rb +239 -239
  152. data/lib/makit/tree.rb +37 -37
  153. data/lib/makit/v1/configuration/project_service_impl.rb +371 -0
  154. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -0
  155. data/lib/makit/v1/makit.v1_pb.rb +35 -35
  156. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  157. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -0
  158. data/lib/makit/version.rb +100 -100
  159. data/lib/makit/version_util.rb +21 -21
  160. data/lib/makit/wix.rb +95 -95
  161. data/lib/makit/yaml.rb +29 -29
  162. data/lib/makit/zip.rb +17 -17
  163. data/lib/makit copy.rb +44 -44
  164. data/lib/makit.rb +111 -43
  165. metadata +61 -36
@@ -0,0 +1,572 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Makit
6
+ module V1
7
+ module Services
8
+ # Implementation of the RepositoryManagerService gRPC service
9
+ class RepositoryManagerServiceImpl < RepositoryManagerService::Service
10
+
11
+ # Initialize a new git repository in the specified directory
12
+ def initialize_repository(request, _unused_call)
13
+ model = convert_from_proto_model(request.model)
14
+ result_model = initialize_repository_impl(model, request.directory)
15
+ convert_to_proto_model(result_model)
16
+ end
17
+
18
+ # Clone a git repository to a local directory
19
+ def clone_repository(request, _unused_call)
20
+ model = convert_from_proto_model(request.model)
21
+ result_model = clone_repository_impl(model, request.git_repository)
22
+ convert_to_proto_model(result_model)
23
+ end
24
+
25
+ # Pull the latest changes from the remote repository
26
+ def pull_repository(request, _unused_call)
27
+ model = convert_from_proto_model(request.model)
28
+ result_model = pull_repository_impl(model, request.git_repository)
29
+ convert_to_proto_model(result_model)
30
+ end
31
+
32
+ # Clone repository if it doesn't exist, otherwise pull latest changes
33
+ def clone_or_pull_repository(request, _unused_call)
34
+ model = convert_from_proto_model(request.model)
35
+ result_model = clone_or_pull_repository_impl(model, request.git_repository)
36
+ convert_to_proto_model(result_model)
37
+ end
38
+
39
+ # Get git log information for a repository
40
+ def get_repository_log(request, _unused_call)
41
+ model = convert_from_proto_model(request.model)
42
+ result_model = get_repository_log_impl(model, request.git_repository, request.limit, request.skip)
43
+ convert_to_proto_model(result_model)
44
+ end
45
+
46
+ # Set up a work directory for a repository
47
+ def setup_work_directory(request, _unused_call)
48
+ model = convert_from_proto_model(request.model)
49
+ result_model = setup_work_directory_impl(model, request.repository)
50
+ convert_to_proto_model(result_model)
51
+ end
52
+
53
+ # Get the latest commit hash from a repository
54
+ def get_latest_commit(request, _unused_call)
55
+ model = convert_from_proto_model(request.model)
56
+ result_model = get_latest_commit_impl(model, request.clone_dir)
57
+ convert_to_proto_model(result_model)
58
+ end
59
+
60
+ # Validate that a clone directory exists for the given repository
61
+ def validate_clone_directory(request, _unused_call)
62
+ model = convert_from_proto_model(request.model)
63
+ result_model = validate_clone_directory_impl(model, request.url)
64
+ convert_to_proto_model(result_model)
65
+ end
66
+
67
+ # Create a new repository manager model with default values
68
+ def create_repository_model(request, _unused_call)
69
+ model = create_repository_model_impl(
70
+ repository_url: request.repository_url,
71
+ clone_directory: request.clone_directory,
72
+ work_directory: request.work_directory,
73
+ is_initialized: request.is_initialized,
74
+ is_cloned: request.is_cloned,
75
+ has_work_directory: request.has_work_directory,
76
+ latest_commit_hash: request.latest_commit_hash,
77
+ last_pull_time: convert_timestamp_from_proto(request.last_pull_time),
78
+ last_clone_time: convert_timestamp_from_proto(request.last_clone_time),
79
+ git_log_entries: convert_git_log_entries_from_proto(request.git_log_entries),
80
+ command_results: convert_command_results_from_proto(request.command_results),
81
+ validation_errors: request.validation_errors.to_a,
82
+ configuration: request.configuration.to_h
83
+ )
84
+ convert_to_proto_model(model)
85
+ end
86
+
87
+ # Update an existing repository model
88
+ def update_repository_model(request, _unused_call)
89
+ model = convert_from_proto_model(request.model)
90
+ result_model = update_repository_model_impl(model, request.updates.to_h)
91
+ convert_to_proto_model(result_model)
92
+ end
93
+
94
+ private
95
+
96
+ # Implementation methods that directly execute git commands
97
+ def initialize_repository_impl(model, directory)
98
+ model[:clone_directory] = directory
99
+ model[:validation_errors] = []
100
+
101
+ begin
102
+ FileUtils.mkdir_p(directory)
103
+ raise Makit::DirectoryError, "directory does not exist: #{directory}" unless Dir.exist?(directory)
104
+
105
+ Dir.chdir(directory) do
106
+ File.write(".gitignore", Makit::Content::GITIGNORE) unless File.exist?(".gitignore")
107
+ init_command = Makit::Commands::Runner.default.execute("git init")
108
+
109
+ command_result = {
110
+ exit_code: init_command.exit_code,
111
+ output: init_command.output,
112
+ error: init_command.error
113
+ }
114
+ model[:command_results] << command_result
115
+
116
+ if init_command.exit_code != 0
117
+ error_msg = "failed to initialize local repository: #{directory}\n#{Makit::Humanize.get_command_summary(init_command)}"
118
+ model[:validation_errors] << error_msg
119
+ raise Makit::GitError, error_msg
120
+ end
121
+
122
+ model[:is_initialized] = true
123
+ end
124
+ rescue StandardError => e
125
+ model[:validation_errors] << e.message
126
+ raise
127
+ end
128
+
129
+ model
130
+ end
131
+
132
+ def clone_repository_impl(model, git_repository)
133
+ model[:repository_url] = git_repository
134
+ model[:validation_errors] = []
135
+
136
+ begin
137
+ clone_dir = Directories.get_clone_directory(git_repository)
138
+ model[:clone_directory] = clone_dir
139
+
140
+ unless Dir.exist?(clone_dir)
141
+ clone_command = Makit::Commands::Runner.default.execute("git clone #{git_repository} #{clone_dir}")
142
+
143
+ command_result = {
144
+ exit_code: clone_command.exit_code,
145
+ output: clone_command.output,
146
+ error: clone_command.error
147
+ }
148
+ model[:command_results] << command_result
149
+
150
+ if clone_command.exit_code != 0
151
+ error_msg = "failed to clone repository: #{git_repository}\n#{Makit::Humanize.get_command_summary(clone_command)}"
152
+ model[:validation_errors] << error_msg
153
+ raise Makit::GitError, error_msg
154
+ end
155
+
156
+ model[:is_cloned] = true
157
+ model[:last_clone_time] = Time.now
158
+ else
159
+ model[:is_cloned] = true
160
+ end
161
+ rescue StandardError => e
162
+ model[:validation_errors] << e.message
163
+ raise
164
+ end
165
+
166
+ model
167
+ end
168
+
169
+ def pull_repository_impl(model, git_repository)
170
+ model[:repository_url] = git_repository
171
+ model[:validation_errors] = []
172
+
173
+ begin
174
+ clone_dir = Directories.get_clone_directory(git_repository)
175
+ model[:clone_directory] = clone_dir
176
+
177
+ raise Makit::DirectoryError, "clone directory does not exist: #{clone_dir}" unless Dir.exist?(clone_dir)
178
+
179
+ Dir.chdir(clone_dir) do
180
+ pull_command = execute_git_pull(clone_dir)
181
+
182
+ command_result = {
183
+ exit_code: pull_command.exit_code,
184
+ output: pull_command.output,
185
+ error: pull_command.error
186
+ }
187
+ model[:command_results] << command_result
188
+
189
+ model[:last_pull_time] = Time.now
190
+ end
191
+ rescue StandardError => e
192
+ model[:validation_errors] << e.message
193
+ raise
194
+ end
195
+
196
+ model
197
+ end
198
+
199
+ def clone_or_pull_repository_impl(model, git_repository)
200
+ model[:repository_url] = git_repository
201
+ clone_dir = Directories.get_clone_directory(git_repository)
202
+ model[:clone_directory] = clone_dir
203
+
204
+ if Dir.exist?(clone_dir)
205
+ pull_repository_impl(model, git_repository)
206
+ else
207
+ clone_repository_impl(model, git_repository)
208
+ end
209
+
210
+ model
211
+ end
212
+
213
+ def get_repository_log_impl(model, git_repository, limit, skip)
214
+ model[:repository_url] = git_repository
215
+ model[:validation_errors] = []
216
+
217
+ begin
218
+ clone_dir = Directories.get_clone_directory(git_repository)
219
+ model[:clone_directory] = clone_dir
220
+
221
+ raise Makit::DirectoryError, "clone directory does not exist: #{clone_dir}" unless Dir.exist?(clone_dir)
222
+
223
+ Dir.chdir(clone_dir) do
224
+ log_command = Makit::Commands::Runner.default.execute("git log -n #{limit} --skip #{skip} --date=iso")
225
+
226
+ command_result = {
227
+ exit_code: log_command.exit_code,
228
+ output: log_command.output,
229
+ error: log_command.error
230
+ }
231
+ model[:command_results] << command_result
232
+
233
+ if log_command.exit_code == 0
234
+ model[:git_log_entries] = parse_git_log_output(log_command)
235
+ else
236
+ model[:validation_errors] << "failed to get git log: #{log_command.error}"
237
+ end
238
+ end
239
+ rescue StandardError => e
240
+ model[:validation_errors] << e.message
241
+ raise
242
+ end
243
+
244
+ model
245
+ end
246
+
247
+ def setup_work_directory_impl(model, repository)
248
+ model[:repository_url] = repository
249
+ model[:validation_errors] = []
250
+
251
+ begin
252
+ clone_or_pull_repository_impl(model, repository)
253
+ create_work_directory_impl(model, repository)
254
+ rescue StandardError => e
255
+ model[:validation_errors] << e.message
256
+ raise
257
+ end
258
+
259
+ model
260
+ end
261
+
262
+ def get_latest_commit_impl(model, clone_dir)
263
+ model[:clone_directory] = clone_dir
264
+ model[:validation_errors] = []
265
+
266
+ begin
267
+ Dir.chdir(clone_dir) do
268
+ git_log = Makit::Commands::Runner.default.execute("git log -n 1 --date=iso")
269
+
270
+ command_result = {
271
+ exit_code: git_log.exit_code,
272
+ output: git_log.output,
273
+ error: git_log.error
274
+ }
275
+ model[:command_results] << command_result
276
+
277
+ if git_log.exit_code == 0
278
+ commit = git_log.output.match(/^commit ([0-9a-f]{40})$/i)&.captures&.first
279
+
280
+ if commit.nil? || commit.empty? || !commit.match?(/\A[0-9a-f]{40}\z/i)
281
+ error_msg = "invalid commit: #{commit}"
282
+ model[:validation_errors] << error_msg
283
+ raise Makit::InvalidCommitError, error_msg
284
+ end
285
+
286
+ model[:latest_commit_hash] = commit
287
+ else
288
+ model[:validation_errors] << "failed to get latest commit: #{git_log.error}"
289
+ end
290
+ end
291
+ rescue StandardError => e
292
+ model[:validation_errors] << e.message
293
+ raise
294
+ end
295
+
296
+ model
297
+ end
298
+
299
+ def validate_clone_directory_impl(model, url)
300
+ model[:repository_url] = url
301
+ model[:validation_errors] = []
302
+
303
+ begin
304
+ clone_dir = Directories.get_clone_directory(url)
305
+ model[:clone_directory] = clone_dir
306
+
307
+ raise Makit::DirectoryError, "clone directory does not exist: #{clone_dir}" unless Dir.exist?(clone_dir)
308
+ rescue StandardError => e
309
+ model[:validation_errors] << e.message
310
+ raise
311
+ end
312
+
313
+ model
314
+ end
315
+
316
+ def create_repository_model_impl(**params)
317
+ {
318
+ repository_url: params[:repository_url],
319
+ clone_directory: params[:clone_directory],
320
+ work_directory: params[:work_directory],
321
+ is_initialized: params[:is_initialized] || false,
322
+ is_cloned: params[:is_cloned] || false,
323
+ has_work_directory: params[:has_work_directory] || false,
324
+ latest_commit_hash: params[:latest_commit_hash],
325
+ last_pull_time: params[:last_pull_time],
326
+ last_clone_time: params[:last_clone_time],
327
+ git_log_entries: params[:git_log_entries] || [],
328
+ command_results: params[:command_results] || [],
329
+ validation_errors: params[:validation_errors] || [],
330
+ configuration: params[:configuration] || {}
331
+ }
332
+ end
333
+
334
+ def update_repository_model_impl(model, updates)
335
+ updates.each do |key, value|
336
+ case key.to_sym
337
+ when :repository_url
338
+ model[:repository_url] = value
339
+ when :clone_directory
340
+ model[:clone_directory] = value
341
+ when :work_directory
342
+ model[:work_directory] = value
343
+ when :is_initialized
344
+ model[:is_initialized] = (value == "true" || value == true)
345
+ when :is_cloned
346
+ model[:is_cloned] = (value == "true" || value == true)
347
+ when :has_work_directory
348
+ model[:has_work_directory] = (value == "true" || value == true)
349
+ when :latest_commit_hash
350
+ model[:latest_commit_hash] = value
351
+ when :last_pull_time
352
+ model[:last_pull_time] = value
353
+ when :last_clone_time
354
+ model[:last_clone_time] = value
355
+ when :git_log_entries
356
+ model[:git_log_entries] = value
357
+ when :command_results
358
+ model[:command_results] = value
359
+ when :validation_errors
360
+ model[:validation_errors] = value
361
+ when :configuration
362
+ model[:configuration] = value
363
+ end
364
+ end
365
+ model
366
+ end
367
+
368
+ # Helper methods
369
+ def execute_git_pull(clone_dir)
370
+ request = Makit::V1::CommandRequest.new(
371
+ name: "git",
372
+ arguments: ["pull"],
373
+ directory: clone_dir,
374
+ )
375
+ pull_command = Makit::Commands::Runner.default.execute(request)
376
+
377
+ raise Makit::PullError, Makit::Humanize.get_command_details(pull_command) if pull_command.exit_code != 0
378
+
379
+ pull_command
380
+ end
381
+
382
+ def create_work_directory_impl(model, repository)
383
+ work_dir = Makit::Directories.get_work_directory(repository)
384
+ clone_dir = Makit::Directories.get_clone_directory(repository)
385
+ model[:work_directory] = work_dir
386
+
387
+ unless Dir.exist?(work_dir)
388
+ FileUtils.mkdir_p(File.dirname(work_dir))
389
+ clone_command = Makit::Commands::Runner.default.execute("git clone #{clone_dir} #{work_dir}")
390
+
391
+ command_result = {
392
+ exit_code: clone_command.exit_code,
393
+ output: clone_command.output,
394
+ error: clone_command.error
395
+ }
396
+ model[:command_results] << command_result
397
+
398
+ if clone_command.exit_code != 0
399
+ error_msg = "failed to create work directory: #{work_dir}\n#{Makit::Humanize.get_command_summary(clone_command)}"
400
+ model[:validation_errors] << error_msg
401
+ raise Makit::GitError, error_msg
402
+ end
403
+
404
+ model[:has_work_directory] = true
405
+ else
406
+ model[:has_work_directory] = true
407
+ end
408
+
409
+ Dir.chdir(work_dir) do
410
+ File.write(".gitignore", Makit::Content::GITIGNORE) unless File.exist?(".gitignore")
411
+ end
412
+ end
413
+
414
+ def parse_git_log_output(log_command)
415
+ entries = []
416
+ return entries if log_command.exit_code != 0
417
+
418
+ lines = log_command.output.split("\n")
419
+ current_entry = nil
420
+
421
+ lines.each do |line|
422
+ current_entry = process_git_log_line(line, current_entry, entries)
423
+ end
424
+
425
+ entries
426
+ end
427
+
428
+ def process_git_log_line(line, current_entry, entries)
429
+ case line
430
+ when /^commit/
431
+ create_new_log_entry(line, entries)
432
+ when /^Author:/
433
+ current_entry ? update_entry_author(line, current_entry) : current_entry
434
+ when /^Date:/
435
+ current_entry ? update_entry_date(line, current_entry) : current_entry
436
+ when /^ /
437
+ current_entry ? update_entry_message(line, current_entry) : current_entry
438
+ else
439
+ current_entry
440
+ end
441
+ end
442
+
443
+ def create_new_log_entry(line, entries)
444
+ current_entry = {
445
+ commit_hash: line.split[1],
446
+ author: nil,
447
+ date: nil,
448
+ message: ""
449
+ }
450
+ entries << current_entry
451
+ current_entry
452
+ end
453
+
454
+ def update_entry_author(line, current_entry)
455
+ current_entry[:author] = line.split[1..].join(" ")
456
+ current_entry
457
+ end
458
+
459
+ def update_entry_date(line, current_entry)
460
+ current_entry[:date] = line.split[1..].join(" ")
461
+ current_entry
462
+ end
463
+
464
+ def update_entry_message(line, current_entry)
465
+ current_entry[:message] += line[4..]
466
+ current_entry
467
+ end
468
+
469
+ # Convert Ruby RepositoryManagerModel to Protobuf RepositoryManagerModel
470
+ def convert_to_proto_model(ruby_model)
471
+ Makit::V1::Services::RepositoryManagerModel.new(
472
+ repository_url: ruby_model[:repository_url],
473
+ clone_directory: ruby_model[:clone_directory],
474
+ work_directory: ruby_model[:work_directory],
475
+ is_initialized: ruby_model[:is_initialized],
476
+ is_cloned: ruby_model[:is_cloned],
477
+ has_work_directory: ruby_model[:has_work_directory],
478
+ latest_commit_hash: ruby_model[:latest_commit_hash],
479
+ last_pull_time: convert_timestamp_to_proto(ruby_model[:last_pull_time]),
480
+ last_clone_time: convert_timestamp_to_proto(ruby_model[:last_clone_time]),
481
+ git_log_entries: convert_git_log_entries_to_proto(ruby_model[:git_log_entries]),
482
+ command_results: convert_command_results_to_proto(ruby_model[:command_results]),
483
+ validation_errors: ruby_model[:validation_errors],
484
+ configuration: ruby_model[:configuration]
485
+ )
486
+ end
487
+
488
+ # Convert Protobuf RepositoryManagerModel to Ruby RepositoryManagerModel
489
+ def convert_from_proto_model(proto_model)
490
+ {
491
+ repository_url: proto_model.repository_url,
492
+ clone_directory: proto_model.clone_directory,
493
+ work_directory: proto_model.work_directory,
494
+ is_initialized: proto_model.is_initialized,
495
+ is_cloned: proto_model.is_cloned,
496
+ has_work_directory: proto_model.has_work_directory,
497
+ latest_commit_hash: proto_model.latest_commit_hash,
498
+ last_pull_time: convert_timestamp_from_proto(proto_model.last_pull_time),
499
+ last_clone_time: convert_timestamp_from_proto(proto_model.last_clone_time),
500
+ git_log_entries: convert_git_log_entries_from_proto(proto_model.git_log_entries),
501
+ command_results: convert_command_results_from_proto(proto_model.command_results),
502
+ validation_errors: proto_model.validation_errors.to_a,
503
+ configuration: proto_model.configuration.to_h
504
+ }
505
+ end
506
+
507
+ # Convert Ruby Time to Protobuf Timestamp
508
+ def convert_timestamp_to_proto(time)
509
+ return nil if time.nil?
510
+
511
+ Google::Protobuf::Timestamp.new(
512
+ seconds: time.to_i,
513
+ nanos: time.nsec
514
+ )
515
+ end
516
+
517
+ # Convert Protobuf Timestamp to Ruby Time
518
+ def convert_timestamp_from_proto(timestamp)
519
+ return nil if timestamp.nil?
520
+
521
+ Time.at(timestamp.seconds, timestamp.nanos, :nsec)
522
+ end
523
+
524
+ # Convert Ruby GitLogEntry array to Protobuf GitLogEntry array
525
+ def convert_git_log_entries_to_proto(ruby_entries)
526
+ ruby_entries.map do |entry|
527
+ Makit::V1::Services::GitLogEntry.new(
528
+ commit_hash: entry[:commit_hash],
529
+ author: entry[:author],
530
+ date: entry[:date],
531
+ message: entry[:message]
532
+ )
533
+ end
534
+ end
535
+
536
+ # Convert Protobuf GitLogEntry array to Ruby GitLogEntry array
537
+ def convert_git_log_entries_from_proto(proto_entries)
538
+ proto_entries.map do |entry|
539
+ {
540
+ commit_hash: entry.commit_hash,
541
+ author: entry.author,
542
+ date: entry.date,
543
+ message: entry.message
544
+ }
545
+ end
546
+ end
547
+
548
+ # Convert Ruby CommandResult array to Protobuf CommandResult array
549
+ def convert_command_results_to_proto(ruby_results)
550
+ ruby_results.map do |result|
551
+ Makit::V1::Services::CommandResult.new(
552
+ exit_code: result[:exit_code],
553
+ output: result[:output],
554
+ error: result[:error]
555
+ )
556
+ end
557
+ end
558
+
559
+ # Convert Protobuf CommandResult array to Ruby CommandResult array
560
+ def convert_command_results_from_proto(proto_results)
561
+ proto_results.map do |result|
562
+ {
563
+ exit_code: result.exit_code,
564
+ output: result.output,
565
+ error: result.error
566
+ }
567
+ end
568
+ end
569
+ end
570
+ end
571
+ end
572
+ end