makit 0.0.143 → 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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/makit/cli/base.rb +17 -0
  3. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +1 -0
  4. data/lib/makit/cli/main.rb +9 -0
  5. data/lib/makit/cli/pipeline_commands.rb +311 -0
  6. data/lib/makit/cli/strategy_commands.rb +2 -7
  7. data/lib/makit/commands/result.rb +1 -1
  8. data/lib/makit/configuration/dotnet_project.rb +9 -0
  9. data/lib/makit/configuration/gitlab_helper.rb +4 -1
  10. data/lib/makit/configuration/project.rb +362 -84
  11. data/lib/makit/configuration/timeout.rb +1 -1
  12. data/lib/makit/configuration.rb +5 -0
  13. data/lib/makit/fileinfo.rb +8 -0
  14. data/lib/makit/git/repository.rb +207 -31
  15. data/lib/makit/git.rb +6 -0
  16. data/lib/makit/gitlab/pipeline.rb +857 -0
  17. data/lib/makit/gitlab/pipeline_service_impl.rb +1536 -0
  18. data/lib/makit/humanize.rb +81 -0
  19. data/lib/makit/io/filesystem.rb +111 -0
  20. data/lib/makit/io/filesystem_service_impl.rb +337 -0
  21. data/lib/makit/mp/string_mp.rb +15 -9
  22. data/lib/makit/podman/podman.rb +458 -0
  23. data/lib/makit/podman/podman_service_impl.rb +1081 -0
  24. data/lib/makit/process.rb +214 -0
  25. data/lib/makit/protoc.rb +6 -1
  26. data/lib/makit/services/repository_manager.rb +268 -132
  27. data/lib/makit/symbols.rb +5 -0
  28. data/lib/makit/v1/configuration/project_service_impl.rb +371 -0
  29. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -0
  30. data/lib/makit/v1/makit.v1_pb.rb +1 -1
  31. data/lib/makit/v1/makit.v1_services_pb.rb +1 -1
  32. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -0
  33. data/lib/makit/version.rb +1 -1
  34. data/lib/makit.rb +68 -0
  35. metadata +61 -36
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "validator"
4
+ # Note: RepositoryManagerService intermediate class removed after Phase 4 cleanup
4
5
 
5
6
  module Makit
6
7
  module Services
7
8
  # Service class responsible for git repository management operations
8
9
  # Handles cloning, pulling, logging, and working directory setup
10
+ #
11
+ # This class now acts as a Ruby wrapper around the gRPC service implementation,
12
+ # maintaining backward compatibility while providing the benefits of the new architecture.
9
13
  class RepositoryManager
10
14
  class << self
11
15
  # Initialize a new git repository in the specified directory
@@ -15,21 +19,25 @@ module Makit
15
19
  # @raise [Makit::DirectoryError] if the directory cannot be created
16
20
  # @raise [Makit::GitError] if git initialization fails
17
21
  def initialize_repository(directory)
18
- Validator.validate_directory_parameter(directory)
19
- FileUtils.mkdir_p(directory)
20
-
21
- raise Makit::DirectoryError, "directory does not exist: #{directory}" unless Dir.exist?(directory)
22
-
23
- Dir.chdir(directory) do
24
- File.write(".gitignore", Makit::Content::GITIGNORE) unless File.exist?(".gitignore")
25
- init_command = Makit::Commands::Runner.default.execute("git init")
26
-
27
- if init_command.exit_code != 0
28
- raise Makit::GitError, "failed to initialize local repository: #{directory}\\n#{Makit::Humanize.get_command_summary(init_command)}"
29
- end
30
-
31
- init_command
32
- end
22
+ # Create a new repository model directly
23
+ model = create_empty_repository_model
24
+
25
+ # Call the gRPC service
26
+ request = Makit::V1::Services::InitializeRepositoryRequest.new(
27
+ model: convert_to_proto_model(model),
28
+ directory: directory
29
+ )
30
+
31
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.initialize_repository(request, nil)
32
+
33
+ # Convert back to Ruby model and extract the command result
34
+ ruby_model = convert_from_proto_model(result_model)
35
+
36
+ # Return the last command result as a Makit::V1::Command
37
+ return create_command_from_result(ruby_model.command_results.last) if ruby_model.command_results.any?
38
+
39
+ # Fallback: create a mock command if no results
40
+ create_mock_command(0, "Repository initialized", "")
33
41
  end
34
42
 
35
43
  # Clone a git repository to a local directory
@@ -37,15 +45,22 @@ module Makit
37
45
  # @param git_repository [String] the git repository URL
38
46
  # @return [Array<Makit::V1::Command>] array of command results
39
47
  def clone_repository(git_repository)
40
- Validator.validate_url_parameter(git_repository)
41
- commands = []
42
-
43
- clone_dir = Directories.get_clone_directory(git_repository)
44
- unless Dir.exist?(clone_dir)
45
- commands << Makit::Commands::Runner.default.execute("git clone #{git_repository} #{clone_dir}")
46
- end
47
-
48
- commands
48
+ # Create a new repository model directly
49
+ model = create_empty_repository_model
50
+
51
+ # Call the gRPC service
52
+ request = Makit::V1::Services::CloneRepositoryRequest.new(
53
+ model: convert_to_proto_model(model),
54
+ git_repository: git_repository
55
+ )
56
+
57
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.clone_repository(request, nil)
58
+
59
+ # Convert back to Ruby model and extract command results
60
+ ruby_model = convert_from_proto_model(result_model)
61
+
62
+ # Convert command results to Makit::V1::Command objects
63
+ ruby_model.command_results.map { |result| create_command_from_result(result) }
49
64
  end
50
65
 
51
66
  # Pull the latest changes from the remote repository
@@ -53,14 +68,25 @@ module Makit
53
68
  # @param git_repository [String] the git repository URL
54
69
  # @return [Makit::V1::Command] the git pull command result
55
70
  def pull_repository(git_repository)
56
- Validator.validate_url_parameter(git_repository)
57
- clone_dir = Directories.get_clone_directory(git_repository)
58
-
59
- Validator.validate_directory_exists(clone_dir, "clone directory")
60
-
61
- Dir.chdir(clone_dir) do
62
- execute_git_pull(clone_dir)
63
- end
71
+ # Create a new repository model directly
72
+ model = create_empty_repository_model
73
+
74
+ # Call the gRPC service
75
+ request = Makit::V1::Services::PullRepositoryRequest.new(
76
+ model: convert_to_proto_model(model),
77
+ git_repository: git_repository
78
+ )
79
+
80
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.pull_repository(request, nil)
81
+
82
+ # Convert back to Ruby model and extract the command result
83
+ ruby_model = convert_from_proto_model(result_model)
84
+
85
+ # Return the last command result as a Makit::V1::Command
86
+ return create_command_from_result(ruby_model.command_results.last) if ruby_model.command_results.any?
87
+
88
+ # Fallback: create a mock command if no results
89
+ create_mock_command(0, "Repository pulled", "")
64
90
  end
65
91
 
66
92
  # Clone repository if it doesn't exist, otherwise pull latest changes
@@ -68,15 +94,22 @@ module Makit
68
94
  # @param git_repository [String] the git repository URL
69
95
  # @return [Array<Makit::V1::Command>] array of command results
70
96
  def clone_or_pull_repository(git_repository)
71
- commands = []
72
- clone_dir = Directories.get_clone_directory(git_repository)
73
-
74
- commands << if Dir.exist?(clone_dir)
75
- pull_repository(git_repository)
76
- else
77
- clone_repository(git_repository)
78
- end
79
- commands
97
+ # Create a new repository model directly
98
+ model = create_empty_repository_model
99
+
100
+ # Call the gRPC service
101
+ request = Makit::V1::Services::CloneOrPullRepositoryRequest.new(
102
+ model: convert_to_proto_model(model),
103
+ git_repository: git_repository
104
+ )
105
+
106
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.clone_or_pull_repository(request, nil)
107
+
108
+ # Convert back to Ruby model and extract command results
109
+ ruby_model = convert_from_proto_model(result_model)
110
+
111
+ # Convert command results to Makit::V1::Command objects
112
+ ruby_model.command_results.map { |result| create_command_from_result(result) }
80
113
  end
81
114
 
82
115
  # Get git log information for a repository
@@ -86,16 +119,24 @@ module Makit
86
119
  # @param skip [Integer] number of commits to skip
87
120
  # @return [Array<Makit::V1::GitLogEntry>] array of log entries
88
121
  def get_repository_log(git_repository, limit, skip)
89
- Validator.validate_url_parameter(git_repository)
90
- Validator.validate_pagination_parameters(limit, skip)
91
-
92
- clone_dir = Directories.get_clone_directory(git_repository)
93
- Validator.validate_directory_exists(clone_dir, "clone directory")
94
-
95
- Dir.chdir(clone_dir) do
96
- log_command = Makit::Commands::Runner.default.execute("git log -n #{limit} --skip #{skip} --date=iso")
97
- parse_git_log_output(log_command)
98
- end
122
+ # Create a new repository model directly
123
+ model = create_empty_repository_model
124
+
125
+ # Call the gRPC service
126
+ request = Makit::V1::Services::GetRepositoryLogRequest.new(
127
+ model: convert_to_proto_model(model),
128
+ git_repository: git_repository,
129
+ limit: limit,
130
+ skip: skip
131
+ )
132
+
133
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.get_repository_log(request, nil)
134
+
135
+ # Convert back to Ruby model and extract git log entries
136
+ ruby_model = convert_from_proto_model(result_model)
137
+
138
+ # Convert to Makit::V1::GitLogEntry objects
139
+ ruby_model.git_log_entries.map { |entry| create_git_log_entry_from_model(entry) }
99
140
  end
100
141
 
101
142
  # Set up a work directory for a repository
@@ -103,9 +144,18 @@ module Makit
103
144
  # @param repository [String] the git repository URL
104
145
  # @return [nil] always returns nil
105
146
  def setup_work_directory(repository)
106
- Validator.validate_url_parameter(repository)
107
- clone_or_pull_repository(repository)
108
- create_work_directory(repository)
147
+ # Create a new repository model directly
148
+ model = create_empty_repository_model
149
+
150
+ # Call the gRPC service
151
+ request = Makit::V1::Services::SetupWorkDirectoryRequest.new(
152
+ model: convert_to_proto_model(model),
153
+ repository: repository
154
+ )
155
+
156
+ Makit::V1::Services::RepositoryManagerServiceImpl.new.setup_work_directory(request, nil)
157
+
158
+ # Always return nil as per original API
109
159
  nil
110
160
  end
111
161
 
@@ -115,18 +165,25 @@ module Makit
115
165
  # @param commands [Array] array to append command results to
116
166
  # @return [String] the latest commit hash
117
167
  def get_latest_commit(clone_dir, commands)
118
- Dir.chdir(clone_dir) do
119
- git_log = Makit::Commands::Runner.default.execute("git log -n 1 --date=iso")
120
- commands << git_log
121
-
122
- commit = git_log.output.match(/^commit ([0-9a-f]{#{Validator::COMMIT_HASH_LENGTH}})$/i)&.captures&.first
123
-
124
- if commit.nil? || commit.empty? || !commit.match?(/\\A[0-9a-f]{#{Validator::COMMIT_HASH_LENGTH}}\\z/i)
125
- raise Makit::InvalidCommitError, "invalid commit: #{commit}"
126
- end
127
-
128
- commit
129
- end
168
+ # Create a new repository model directly
169
+ model = create_empty_repository_model
170
+
171
+ # Call the gRPC service
172
+ request = Makit::V1::Services::GetLatestCommitRequest.new(
173
+ model: convert_to_proto_model(model),
174
+ clone_dir: clone_dir
175
+ )
176
+
177
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.get_latest_commit(request, nil)
178
+
179
+ # Convert back to Ruby model
180
+ ruby_model = convert_from_proto_model(result_model)
181
+
182
+ # Append command results to the provided commands array
183
+ ruby_model.command_results.each { |result| commands << create_command_from_result(result) }
184
+
185
+ # Return the latest commit hash
186
+ ruby_model.latest_commit_hash || ""
130
187
  end
131
188
 
132
189
  # Validate that a clone directory exists for the given repository
@@ -134,96 +191,175 @@ module Makit
134
191
  # @param url [String] the git repository URL
135
192
  # @return [String] the clone directory path
136
193
  def validate_clone_directory(url)
137
- clone_dir = Directories.get_clone_directory(url)
138
- Validator.validate_directory_exists(clone_dir, "clone directory")
139
- clone_dir
194
+ # Create a new repository model directly
195
+ model = create_empty_repository_model
196
+
197
+ # Call the gRPC service
198
+ request = Makit::V1::Services::ValidateCloneDirectoryRequest.new(
199
+ model: convert_to_proto_model(model),
200
+ url: url
201
+ )
202
+
203
+ result_model = Makit::V1::Services::RepositoryManagerServiceImpl.new.validate_clone_directory(request, nil)
204
+
205
+ # Convert back to Ruby model and return clone directory
206
+ ruby_model = convert_from_proto_model(result_model)
207
+ ruby_model.clone_directory || ""
140
208
  end
141
209
 
142
210
  private
143
211
 
144
- # Execute git pull command with proper error handling
145
- def execute_git_pull(clone_dir)
146
- request = Makit::V1::CommandRequest.new(
147
- name: "git",
148
- arguments: ["pull"],
149
- directory: clone_dir,
150
- )
151
- pull_command = Makit::Commands::Runner.default.execute(request)
212
+ # Create an empty repository model for gRPC service calls
213
+ def create_empty_repository_model
214
+ # Create a simple hash-based model since we removed the intermediate classes
215
+ {
216
+ repository_url: nil,
217
+ clone_directory: nil,
218
+ work_directory: nil,
219
+ is_initialized: false,
220
+ is_cloned: false,
221
+ has_work_directory: false,
222
+ latest_commit_hash: nil,
223
+ last_pull_time: nil,
224
+ last_clone_time: nil,
225
+ git_log_entries: [],
226
+ command_results: [],
227
+ validation_errors: [],
228
+ configuration: {}
229
+ }
230
+ end
152
231
 
153
- raise Makit::PullError, Makit::Humanize.get_command_details(pull_command) if pull_command.exit_code != 0
232
+ # Convert Ruby RepositoryManagerModel to Protobuf RepositoryManagerModel
233
+ def convert_to_proto_model(ruby_model)
234
+ Makit::V1::Services::RepositoryManagerModel.new(
235
+ repository_url: ruby_model[:repository_url],
236
+ clone_directory: ruby_model[:clone_directory],
237
+ work_directory: ruby_model[:work_directory],
238
+ is_initialized: ruby_model[:is_initialized],
239
+ is_cloned: ruby_model[:is_cloned],
240
+ has_work_directory: ruby_model[:has_work_directory],
241
+ latest_commit_hash: ruby_model[:latest_commit_hash],
242
+ last_pull_time: convert_time_to_timestamp(ruby_model[:last_pull_time]),
243
+ last_clone_time: convert_time_to_timestamp(ruby_model[:last_clone_time]),
244
+ git_log_entries: convert_git_log_entries_to_proto(ruby_model[:git_log_entries]),
245
+ command_results: convert_command_results_to_proto(ruby_model[:command_results]),
246
+ validation_errors: ruby_model[:validation_errors],
247
+ configuration: ruby_model[:configuration]
248
+ )
249
+ end
154
250
 
155
- pull_command
251
+ # Convert Protobuf RepositoryManagerModel to Ruby RepositoryManagerModel
252
+ def convert_from_proto_model(proto_model)
253
+ {
254
+ repository_url: proto_model.repository_url,
255
+ clone_directory: proto_model.clone_directory,
256
+ work_directory: proto_model.work_directory,
257
+ is_initialized: proto_model.is_initialized,
258
+ is_cloned: proto_model.is_cloned,
259
+ has_work_directory: proto_model.has_work_directory,
260
+ latest_commit_hash: proto_model.latest_commit_hash,
261
+ last_pull_time: convert_timestamp_to_time(proto_model.last_pull_time),
262
+ last_clone_time: convert_timestamp_to_time(proto_model.last_clone_time),
263
+ git_log_entries: convert_git_log_entries_from_proto(proto_model.git_log_entries),
264
+ command_results: convert_command_results_from_proto(proto_model.command_results),
265
+ validation_errors: proto_model.validation_errors.to_a,
266
+ configuration: proto_model.configuration.to_h
267
+ }
156
268
  end
157
269
 
158
- # Create work directory for development
159
- def create_work_directory(repository)
160
- work_dir = Makit::Directories.get_work_directory(repository)
161
- clone_dir = Makit::Directories.get_clone_directory(repository)
270
+ # Convert Ruby Time to Protobuf Timestamp
271
+ def convert_time_to_timestamp(time)
272
+ return nil if time.nil?
273
+
274
+ Google::Protobuf::Timestamp.new(
275
+ seconds: time.to_i,
276
+ nanos: time.nsec
277
+ )
278
+ end
162
279
 
163
- unless Dir.exist?(work_dir)
164
- FileUtils.mkdir_p(File.dirname(work_dir))
165
- Makit::Commands::Runner.default.execute("git clone #{clone_dir} #{work_dir}")
166
- end
280
+ # Convert Protobuf Timestamp to Ruby Time
281
+ def convert_timestamp_to_time(timestamp)
282
+ return nil if timestamp.nil?
283
+
284
+ Time.at(timestamp.seconds, timestamp.nanos, :nsec)
285
+ end
167
286
 
168
- Dir.chdir(work_dir) do
169
- File.write(".gitignore", Makit::Content::GITIGNORE) unless File.exist?(".gitignore")
287
+ # Convert Ruby GitLogEntry array to Protobuf GitLogEntry array
288
+ def convert_git_log_entries_to_proto(ruby_entries)
289
+ ruby_entries.map do |entry|
290
+ Makit::V1::Services::GitLogEntry.new(
291
+ commit_hash: entry[:commit_hash],
292
+ author: entry[:author],
293
+ date: entry[:date],
294
+ message: entry[:message]
295
+ )
170
296
  end
171
297
  end
172
298
 
173
- # Parse git log output into structured log entries
174
- def parse_git_log_output(log_command)
175
- entries = []
176
- return entries if log_command.exit_code != 0
177
-
178
- lines = log_command.output.split("\\n")
179
- current_entry = nil
180
-
181
- lines.each do |line|
182
- current_entry = process_git_log_line(line, current_entry, entries)
299
+ # Convert Protobuf GitLogEntry array to Ruby GitLogEntry array
300
+ def convert_git_log_entries_from_proto(proto_entries)
301
+ proto_entries.map do |entry|
302
+ {
303
+ commit_hash: entry.commit_hash,
304
+ author: entry.author,
305
+ date: entry.date,
306
+ message: entry.message
307
+ }
183
308
  end
309
+ end
184
310
 
185
- entries
186
- end
187
-
188
- # Process a single line from git log output
189
- def process_git_log_line(line, current_entry, entries)
190
- case line
191
- when /^commit/
192
- create_new_log_entry(line, entries)
193
- when /^Author:/
194
- current_entry ? update_entry_author(line, current_entry) : current_entry
195
- when /^Date:/
196
- current_entry ? update_entry_date(line, current_entry) : current_entry
197
- when /^ /
198
- current_entry ? update_entry_message(line, current_entry) : current_entry
199
- else
200
- current_entry
311
+ # Convert Ruby CommandResult array to Protobuf CommandResult array
312
+ def convert_command_results_to_proto(ruby_results)
313
+ ruby_results.map do |result|
314
+ Makit::V1::Services::CommandResult.new(
315
+ exit_code: result[:exit_code],
316
+ output: result[:output],
317
+ error: result[:error]
318
+ )
201
319
  end
202
320
  end
203
321
 
204
- # Create new git log entry from commit line
205
- def create_new_log_entry(line, entries)
206
- current_entry = GitLogEntry.new(line.split[1])
207
- entries << current_entry
208
- current_entry
322
+ # Convert Protobuf CommandResult array to Ruby CommandResult array
323
+ def convert_command_results_from_proto(proto_results)
324
+ proto_results.map do |result|
325
+ {
326
+ exit_code: result.exit_code,
327
+ output: result.output,
328
+ error: result.error
329
+ }
330
+ end
209
331
  end
210
332
 
211
- # Update log entry with author information
212
- def update_entry_author(line, current_entry)
213
- current_entry.author = line.split[1..].join(" ")
214
- current_entry
333
+ # Create a Makit::V1::Command from a CommandResult
334
+ def create_command_from_result(result)
335
+ # Create a mock Makit::V1::Command object
336
+ # This maintains compatibility with the original API
337
+ command = Object.new
338
+ command.define_singleton_method(:exit_code) { result[:exit_code] }
339
+ command.define_singleton_method(:output) { result[:output] }
340
+ command.define_singleton_method(:error) { result[:error] }
341
+ command
215
342
  end
216
343
 
217
- # Update log entry with date information
218
- def update_entry_date(line, current_entry)
219
- current_entry.date = line.split[1..].join(" ")
220
- current_entry
344
+ # Create a mock Makit::V1::Command for fallback cases
345
+ def create_mock_command(exit_code, output, error)
346
+ command = Object.new
347
+ command.define_singleton_method(:exit_code) { exit_code }
348
+ command.define_singleton_method(:output) { output }
349
+ command.define_singleton_method(:error) { error }
350
+ command
221
351
  end
222
352
 
223
- # Update log entry with commit message
224
- def update_entry_message(line, current_entry)
225
- current_entry.message += line[4..]
226
- current_entry
353
+ # Create a Makit::V1::GitLogEntry from a GitLogEntry model
354
+ def create_git_log_entry_from_model(entry)
355
+ # Create a mock Makit::V1::GitLogEntry object
356
+ # This maintains compatibility with the original API
357
+ git_log_entry = Object.new
358
+ git_log_entry.define_singleton_method(:commit_hash) { entry[:commit_hash] }
359
+ git_log_entry.define_singleton_method(:author) { entry[:author] }
360
+ git_log_entry.define_singleton_method(:date) { entry[:date] }
361
+ git_log_entry.define_singleton_method(:message) { entry[:message] }
362
+ git_log_entry
227
363
  end
228
364
  end
229
365
  end
data/lib/makit/symbols.rb CHANGED
@@ -9,6 +9,11 @@ rescue LoadError
9
9
  self
10
10
  end
11
11
  end
12
+
13
+ # Define Rainbow as a function that returns the string
14
+ def Rainbow(string)
15
+ string
16
+ end
12
17
  end
13
18
 
14
19
  # https://symbl.cc/en/unicode/table/