makit 0.0.111 → 0.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) 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/cli/build_commands.rb +500 -500
  6. data/lib/makit/cli/generators/base_generator.rb +74 -74
  7. data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
  8. data/lib/makit/cli/generators/generator_factory.rb +49 -49
  9. data/lib/makit/cli/generators/node_generator.rb +50 -50
  10. data/lib/makit/cli/generators/ruby_generator.rb +77 -77
  11. data/lib/makit/cli/generators/rust_generator.rb +50 -50
  12. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
  13. data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
  14. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
  15. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +40 -40
  16. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
  17. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
  18. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
  19. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
  20. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
  21. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
  22. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
  23. data/lib/makit/cli/main.rb +62 -62
  24. data/lib/makit/cli/project_commands.rb +868 -868
  25. data/lib/makit/cli/repository_commands.rb +661 -661
  26. data/lib/makit/cli/utility_commands.rb +521 -521
  27. data/lib/makit/commands/factory.rb +359 -359
  28. data/lib/makit/commands/middleware/base.rb +73 -73
  29. data/lib/makit/commands/middleware/cache.rb +248 -248
  30. data/lib/makit/commands/middleware/command_logger.rb +320 -323
  31. data/lib/makit/commands/middleware/unified_logger.rb +243 -243
  32. data/lib/makit/commands/middleware/validator.rb +269 -269
  33. data/lib/makit/commands/request.rb +254 -254
  34. data/lib/makit/commands/result.rb +323 -323
  35. data/lib/makit/commands/runner.rb +337 -317
  36. data/lib/makit/commands/strategies/base.rb +160 -160
  37. data/lib/makit/commands/strategies/synchronous.rb +134 -134
  38. data/lib/makit/commands.rb +51 -42
  39. data/lib/makit/configuration/gitlab_helper.rb +60 -60
  40. data/lib/makit/configuration/project.rb +127 -127
  41. data/lib/makit/configuration/rakefile_helper.rb +43 -43
  42. data/lib/makit/configuration/step.rb +34 -34
  43. data/lib/makit/configuration.rb +14 -14
  44. data/lib/makit/content/default_gitignore.rb +7 -7
  45. data/lib/makit/content/default_rakefile.rb +13 -13
  46. data/lib/makit/content/gem_rakefile.rb +16 -16
  47. data/lib/makit/context.rb +1 -1
  48. data/lib/makit/data.rb +49 -49
  49. data/lib/makit/directories.rb +141 -141
  50. data/lib/makit/directory.rb +262 -262
  51. data/lib/makit/docs/files.rb +89 -89
  52. data/lib/makit/docs/rake.rb +102 -102
  53. data/lib/makit/dotnet/project.rb +153 -153
  54. data/lib/makit/dotnet/solution.rb +38 -38
  55. data/lib/makit/dotnet/solution_classlib.rb +239 -239
  56. data/lib/makit/dotnet/solution_console.rb +264 -264
  57. data/lib/makit/dotnet/solution_maui.rb +354 -354
  58. data/lib/makit/dotnet/solution_wasm.rb +275 -275
  59. data/lib/makit/dotnet/solution_wpf.rb +304 -304
  60. data/lib/makit/dotnet.rb +102 -102
  61. data/lib/makit/email.rb +90 -90
  62. data/lib/makit/environment.rb +142 -142
  63. data/lib/makit/examples/runner.rb +370 -370
  64. data/lib/makit/exceptions.rb +45 -45
  65. data/lib/makit/fileinfo.rb +24 -24
  66. data/lib/makit/files.rb +43 -43
  67. data/lib/makit/gems.rb +40 -40
  68. data/lib/makit/git/cli.rb +54 -54
  69. data/lib/makit/git/repository.rb +90 -90
  70. data/lib/makit/git.rb +98 -98
  71. data/lib/makit/gitlab_runner.rb +59 -59
  72. data/lib/makit/humanize.rb +137 -137
  73. data/lib/makit/indexer.rb +47 -47
  74. data/lib/makit/logging/configuration.rb +305 -305
  75. data/lib/makit/logging/formatters/base.rb +39 -39
  76. data/lib/makit/logging/formatters/console_formatter.rb +140 -127
  77. data/lib/makit/logging/formatters/json_formatter.rb +65 -65
  78. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
  79. data/lib/makit/logging/formatters/text_formatter.rb +64 -64
  80. data/lib/makit/logging/log_request.rb +115 -115
  81. data/lib/makit/logging/logger.rb +163 -159
  82. data/lib/makit/logging/sinks/console.rb +72 -72
  83. data/lib/makit/logging/sinks/file_sink.rb +92 -92
  84. data/lib/makit/logging/sinks/unified_file_sink.rb +303 -303
  85. data/lib/makit/logging.rb +530 -521
  86. data/lib/makit/markdown.rb +75 -75
  87. data/lib/makit/mp/basic_object_mp.rb +17 -17
  88. data/lib/makit/mp/command_mp.rb +13 -13
  89. data/lib/makit/mp/command_request.mp.rb +17 -17
  90. data/lib/makit/mp/project_mp.rb +199 -199
  91. data/lib/makit/mp/string_mp.rb +193 -348
  92. data/lib/makit/nuget.rb +74 -74
  93. data/lib/makit/port.rb +32 -32
  94. data/lib/makit/process.rb +163 -163
  95. data/lib/makit/protoc.rb +107 -107
  96. data/lib/makit/rake/cli.rb +196 -196
  97. data/lib/makit/rake.rb +25 -25
  98. data/lib/makit/ruby/cli.rb +185 -185
  99. data/lib/makit/ruby.rb +25 -25
  100. data/lib/makit/secrets.rb +51 -51
  101. data/lib/makit/serializer.rb +130 -117
  102. data/lib/makit/services/builder.rb +186 -186
  103. data/lib/makit/services/error_handler.rb +226 -226
  104. data/lib/makit/services/repository_manager.rb +229 -229
  105. data/lib/makit/services/validator.rb +112 -112
  106. data/lib/makit/setup/classlib.rb +53 -53
  107. data/lib/makit/setup/gem.rb +30 -17
  108. data/lib/makit/setup/runner.rb +45 -40
  109. data/lib/makit/setup.rb +5 -0
  110. data/lib/makit/show.rb +110 -110
  111. data/lib/makit/storage.rb +126 -126
  112. data/lib/makit/symbols.rb +170 -161
  113. data/lib/makit/task_info.rb +128 -128
  114. data/lib/makit/tasks/at_exit.rb +13 -13
  115. data/lib/makit/tasks/build.rb +19 -18
  116. data/lib/makit/tasks/clean.rb +11 -11
  117. data/lib/makit/tasks/hook_manager.rb +393 -239
  118. data/lib/makit/tasks/init.rb +47 -47
  119. data/lib/makit/tasks/integrate.rb +17 -15
  120. data/lib/makit/tasks/pull_incoming.rb +11 -12
  121. data/lib/makit/tasks/setup.rb +6 -6
  122. data/lib/makit/tasks/sync.rb +12 -11
  123. data/lib/makit/tasks/tag.rb +15 -0
  124. data/lib/makit/tasks/task_monkey_patch.rb +79 -79
  125. data/lib/makit/tasks.rb +10 -0
  126. data/lib/makit/test_cache.rb +239 -239
  127. data/lib/makit/tree.rb +37 -37
  128. data/lib/makit/v1/makit.v1_pb.rb +34 -34
  129. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  130. data/lib/makit/version.rb +5 -5
  131. data/lib/makit/version_util.rb +21 -0
  132. data/lib/makit/wix.rb +95 -95
  133. data/lib/makit/yaml.rb +29 -29
  134. data/lib/makit/zip.rb +17 -17
  135. data/lib/makit copy.rb +44 -0
  136. data/lib/makit.rb +40 -8
  137. metadata +50 -7
  138. data/lib/makit/command_runner.rb +0 -463
  139. data/lib/makit/commands/compatibility.rb +0 -365
  140. data/lib/makit/task_hooks.rb +0 -125
@@ -1,117 +1,130 @@
1
- # frozen_string_literal: true
2
-
3
- require "google/protobuf"
4
- # This module provides classes for the Makit gem.
5
- module Makit
6
- module Proto3Formats
7
- JSON = [0,
8
- PRETTY_JSON = 1,
9
- YAML = 2,
10
- BINARY = 3].freeze
11
- end
12
-
13
- # This class provide methods for serializing and deserializing objects.
14
- #
15
- class Serializer
16
- attr_accessor :format_map
17
-
18
- def self.save_as(filename, object)
19
- extension = File.extname(filename)
20
- case extension
21
- when ".json"
22
- File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::PRETTY_JSON).serialize(object))
23
- when ".yml"
24
- File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::YAML).serialize(object))
25
- when ".pb"
26
- File.binwrite(filename, Makit::Serializer.new(Makit::Proto3Formats::BINARY).serialize(object))
27
-
28
- # File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::BINARY).serialize(object))
29
- else
30
- raise "unsupported file extension: #{extension}"
31
- end
32
- end
33
-
34
- def self.open(filename, type)
35
- extension = File.extname(filename)
36
- case extension
37
- when ".json"
38
- Makit::Serializer.new(Makit::Proto3Formats::PRETTY_JSON).deserialize(type, File.read(filename))
39
- when ".yml"
40
- Makit::Serializer.new(Makit::Proto3Formats::YAML).deserialize(type, File.read(filename))
41
- when ".pb"
42
- data = File.binread(filename)
43
- Makit::Serializer.new(Makit::Proto3Formats::BINARY).deserialize(type, data)
44
- else
45
- raise "unsupported file extension: #{extension}"
46
- end
47
- end
48
-
49
- def initialize(proto3_format = Proto3Formats::PRETTY_JSON)
50
- @format_maps = {
51
- ::Google::Protobuf::MessageExts => proto3_format,
52
- }
53
- end
54
-
55
- # Serialize an object to a byte[] or a string
56
- def serialize(object)
57
- raise "Object is nil" if object.nil?
58
- raise "object is not of type ::Google::Protobuf::MessageExts" unless object.is_a? ::Google::Protobuf::MessageExts
59
-
60
- case @format_maps[::Google::Protobuf::MessageExts]
61
- when Proto3Formats::JSON
62
- # puts "Serializing to protobuf json format"
63
- object.to_json
64
- when Proto3Formats::PRETTY_JSON
65
- # puts "Serializing to protobuf pretty json format"
66
- json = object.to_json
67
- JSON.pretty_generate(JSON.parse(json))
68
- when Proto3Formats::YAML
69
- # puts "Serializing to protobuf yaml format"
70
- data = JSON.parse(object.to_json)
71
- data.to_yaml.sub(/^---\n/, "")
72
- when Proto3Formats::BINARY
73
- # puts "Serializing to protobuf binary format"
74
- object.to_proto
75
- else
76
- raise "Unknown serialization format"
77
- end
78
- end
79
-
80
- # Deserialize a byte[] or a string to an object
81
- def deserialize(type, data)
82
- raise "data is nil" if data.nil?
83
-
84
- case @format_maps[::Google::Protobuf::MessageExts]
85
- when Proto3Formats::JSON
86
- raise "data is not of type string" unless data.is_a? String
87
-
88
- json = data
89
- # puts "Deserializing from protobuf json format into type #{type}"
90
- # use the from_json method to deserialize the object
91
- type.decode_json(json)
92
- when Proto3Formats::PRETTY_JSON
93
- raise "data is not of type string" unless data.is_a? String
94
-
95
- json = data
96
- # puts "Deserializing from protobuf pretty json format into type #{type}"
97
- # use the from_json method to deserialize the object
98
- type.decode_json(json)
99
- when Proto3Formats::YAML
100
- raise "data is not of type string" unless data.is_a? String
101
-
102
- yaml = data
103
- # convert yaml to json
104
- json = JSON.pretty_generate(YAML.safe_load(yaml))
105
- # puts "Deserializing from protobuf yaml format into type #{type}"
106
- type.decode_json(json)
107
- when Proto3Formats::BINARY
108
- # raise "data is not of type byte[]" if !data.is_a? Array
109
- bytes = data
110
- # puts "Deserializing from protobuf binary format into type #{type}"
111
- type.decode(bytes)
112
- else
113
- raise "Unknown serialization format"
114
- end
115
- end
116
- end
117
- end
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "google/protobuf"
5
+ rescue LoadError
6
+ # google-protobuf gem not available, define a minimal protobuf interface
7
+ module Google
8
+ module Protobuf
9
+ class Message
10
+ def to_json(*args)
11
+ {}
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ # This module provides classes for the Makit gem.
18
+ module Makit
19
+ module Proto3Formats
20
+ JSON = [0,
21
+ PRETTY_JSON = 1,
22
+ YAML = 2,
23
+ BINARY = 3].freeze
24
+ end
25
+
26
+ # This class provide methods for serializing and deserializing objects.
27
+ #
28
+ class Serializer
29
+ attr_accessor :format_map
30
+
31
+ def self.save_as(filename, object)
32
+ extension = File.extname(filename)
33
+ case extension
34
+ when ".json"
35
+ File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::PRETTY_JSON).serialize(object))
36
+ when ".yml"
37
+ File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::YAML).serialize(object))
38
+ when ".pb"
39
+ File.binwrite(filename, Makit::Serializer.new(Makit::Proto3Formats::BINARY).serialize(object))
40
+
41
+ # File.write(filename, Makit::Serializer.new(Makit::Proto3Formats::BINARY).serialize(object))
42
+ else
43
+ raise "unsupported file extension: #{extension}"
44
+ end
45
+ end
46
+
47
+ def self.open(filename, type)
48
+ extension = File.extname(filename)
49
+ case extension
50
+ when ".json"
51
+ Makit::Serializer.new(Makit::Proto3Formats::PRETTY_JSON).deserialize(type, File.read(filename))
52
+ when ".yml"
53
+ Makit::Serializer.new(Makit::Proto3Formats::YAML).deserialize(type, File.read(filename))
54
+ when ".pb"
55
+ data = File.binread(filename)
56
+ Makit::Serializer.new(Makit::Proto3Formats::BINARY).deserialize(type, data)
57
+ else
58
+ raise "unsupported file extension: #{extension}"
59
+ end
60
+ end
61
+
62
+ def initialize(proto3_format = Proto3Formats::PRETTY_JSON)
63
+ @format_maps = {
64
+ ::Google::Protobuf::MessageExts => proto3_format,
65
+ }
66
+ end
67
+
68
+ # Serialize an object to a byte[] or a string
69
+ def serialize(object)
70
+ raise "Object is nil" if object.nil?
71
+ raise "object is not of type ::Google::Protobuf::MessageExts" unless object.is_a? ::Google::Protobuf::MessageExts
72
+
73
+ case @format_maps[::Google::Protobuf::MessageExts]
74
+ when Proto3Formats::JSON
75
+ # puts "Serializing to protobuf json format"
76
+ object.to_json
77
+ when Proto3Formats::PRETTY_JSON
78
+ # puts "Serializing to protobuf pretty json format"
79
+ json = object.to_json
80
+ JSON.pretty_generate(JSON.parse(json))
81
+ when Proto3Formats::YAML
82
+ # puts "Serializing to protobuf yaml format"
83
+ data = JSON.parse(object.to_json)
84
+ data.to_yaml.sub(/^---\n/, "")
85
+ when Proto3Formats::BINARY
86
+ # puts "Serializing to protobuf binary format"
87
+ object.to_proto
88
+ else
89
+ raise "Unknown serialization format"
90
+ end
91
+ end
92
+
93
+ # Deserialize a byte[] or a string to an object
94
+ def deserialize(type, data)
95
+ raise "data is nil" if data.nil?
96
+
97
+ case @format_maps[::Google::Protobuf::MessageExts]
98
+ when Proto3Formats::JSON
99
+ raise "data is not of type string" unless data.is_a? String
100
+
101
+ json = data
102
+ # puts "Deserializing from protobuf json format into type #{type}"
103
+ # use the from_json method to deserialize the object
104
+ type.decode_json(json)
105
+ when Proto3Formats::PRETTY_JSON
106
+ raise "data is not of type string" unless data.is_a? String
107
+
108
+ json = data
109
+ # puts "Deserializing from protobuf pretty json format into type #{type}"
110
+ # use the from_json method to deserialize the object
111
+ type.decode_json(json)
112
+ when Proto3Formats::YAML
113
+ raise "data is not of type string" unless data.is_a? String
114
+
115
+ yaml = data
116
+ # convert yaml to json
117
+ json = JSON.pretty_generate(YAML.safe_load(yaml))
118
+ # puts "Deserializing from protobuf yaml format into type #{type}"
119
+ type.decode_json(json)
120
+ when Proto3Formats::BINARY
121
+ # raise "data is not of type byte[]" if !data.is_a? Array
122
+ bytes = data
123
+ # puts "Deserializing from protobuf binary format into type #{type}"
124
+ type.decode(bytes)
125
+ else
126
+ raise "Unknown serialization format"
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,186 +1,186 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "validator"
4
- require_relative "repository_manager"
5
-
6
- module Makit
7
- module Services
8
- # Service class responsible for build operations and make processes
9
- # Handles the complex build workflow including repository setup and execution
10
- class Builder
11
- class << self
12
- # Build a repository at a specific commit
13
- #
14
- # @param url [String] the git repository URL
15
- # @param commit [String] the commit hash or "latest" for the most recent commit
16
- # @param force [Boolean] whether to force rebuild even if cached result exists
17
- # @return [Makit::V1::MakeResult] the build result with all command outputs
18
- def make_repository(url, commit, force: false)
19
- Validator.validate_url_parameter(url)
20
- Validator.validate_commit_parameter(commit)
21
-
22
- log_filename = get_log_filename(url, commit)
23
-
24
- return load_existing_result(log_filename) if should_load_existing_result?(log_filename, force, commit)
25
-
26
- execute_make_process(url, commit, log_filename)
27
- end
28
-
29
- # Ensure .gitignore exists in the current directory
30
- def ensure_gitignore
31
- return if File.exist?(".gitignore")
32
-
33
- Makit::LOGGER.info("added .gitignore file")
34
- File.open(".gitignore", "w") do |file|
35
- file.puts Makit::Content::GITIGNORE
36
- end
37
- end
38
-
39
- private
40
-
41
- # Get the log filename for storing build results
42
- def get_log_filename(url, commit)
43
- File.join(
44
- Directories.get_log_directory(url),
45
- commit,
46
- "#{Makit::RUNTIME_IDENTIFIER}.#{Makit::DEVICE}.json"
47
- )
48
- end
49
-
50
- # Check if we should load an existing cached result
51
- def should_load_existing_result?(log_filename, force, commit)
52
- File.exist?(log_filename) && !force && commit != Validator::COMMIT_LATEST
53
- end
54
-
55
- # Load existing build result from cache
56
- def load_existing_result(log_filename)
57
- Makit::V1::MakeResult.decode_json(File.read(log_filename))
58
- rescue StandardError
59
- FileUtils.rm(log_filename)
60
- nil
61
- end
62
-
63
- # Execute the complete make process
64
- def execute_make_process(url, commit, log_filename)
65
- commands = []
66
- begin
67
- commands = setup_repository_for_build(url, commit, log_filename)
68
- make_result = build_make_result(url, commit, commands)
69
- save_make_result(make_result, log_filename)
70
- make_result
71
- rescue StandardError => e
72
- handle_make_error(e, url, commit, commands)
73
- end
74
- end
75
-
76
- # Set up repository for build process
77
- def setup_repository_for_build(url, commit, log_filename)
78
- commands = initialize_repository_commands(url)
79
-
80
- clone_dir = RepositoryManager.validate_clone_directory(url)
81
- resolved_commit = resolve_commit_reference(commit, clone_dir, commands, log_filename, url)
82
- prepare_make_directory(url, resolved_commit, clone_dir, commands)
83
-
84
- commands
85
- end
86
-
87
- # Initialize repository commands (clone or pull)
88
- def initialize_repository_commands(url)
89
- RepositoryManager.clone_or_pull_repository(url).flatten
90
- end
91
-
92
- # Resolve commit reference (handle "latest" commit)
93
- def resolve_commit_reference(commit, clone_dir, commands, log_filename, url)
94
- return commit unless commit == Validator::COMMIT_LATEST
95
-
96
- latest_commit = RepositoryManager.get_latest_commit(clone_dir, commands)
97
- # Update log filename with resolved commit hash
98
- log_filename.replace(
99
- File.join(
100
- Directories.get_log_directory(url),
101
- latest_commit,
102
- "#{Makit::RUNTIME_IDENTIFIER}.#{Makit::DEVICE}.json"
103
- )
104
- )
105
- latest_commit
106
- end
107
-
108
- # Prepare make directory with repository clone
109
- def prepare_make_directory(url, commit, clone_dir, commands)
110
- make_dir = Directories.get_make_commit_directory(url, commit)
111
- FileUtils.rm_rf(make_dir)
112
-
113
- clone_command = Makit::RUNNER.execute("git clone #{clone_dir} #{make_dir}")
114
- commands << clone_command
115
-
116
- return if Dir.exist?(make_dir)
117
-
118
- raise Makit::CloneError, "failed to clone repository: #{url} to #{make_dir}"
119
- end
120
-
121
- # Build the make result by executing all build steps
122
- def build_make_result(url, commit, commands)
123
- Dir.chdir(Directories.get_make_commit_directory(url, commit)) do
124
- execute_git_commands(commit, commands)
125
- execute_build_commands(commands)
126
-
127
- make_result = create_make_result_object(url, commit)
128
- commands.flatten.each { |command| make_result.commands << command }
129
- make_result
130
- end
131
- end
132
-
133
- # Execute git-specific commands for the build
134
- def execute_git_commands(commit, commands)
135
- commands << Makit::RUNNER.execute("git reset --hard #{commit}")
136
- commands << Makit::RUNNER.execute("git log -n 1")
137
- end
138
-
139
- # Execute build commands (bundle, rake, etc.)
140
- def execute_build_commands(commands)
141
- commands << Makit::RUNNER.execute("bundle install") if File.exist?("Gemfile")
142
-
143
- return unless File.exist?("Rakefile") || File.exist?("rakefile.rb")
144
-
145
- commands << Makit::RUNNER.execute("rake default")
146
- end
147
-
148
- # Create the make result object
149
- def create_make_result_object(url, commit)
150
- Makit::V1::MakeResult.new(
151
- repository: url,
152
- commit: commit,
153
- branch: "?",
154
- tag: "?",
155
- device: Makit::DEVICE,
156
- runtime_identifier: Makit::RUNTIME_IDENTIFIER,
157
- )
158
- end
159
-
160
- # Save make result to file
161
- def save_make_result(make_result, log_filename)
162
- FileUtils.mkdir_p(File.dirname(log_filename))
163
- File.write(log_filename, make_result.to_json)
164
- end
165
-
166
- # Handle make process errors
167
- def handle_make_error(error, url, commit, commands)
168
- message_parts = [
169
- "error raised attempting to make repository: #{url} commit: #{commit}",
170
- "",
171
- error.message,
172
- error.backtrace.join("\\n"),
173
- "",
174
- "commands:",
175
- ]
176
-
177
- commands.flatten.each do |command|
178
- message_parts << Makit::Humanize.get_command_details(command)
179
- end
180
-
181
- raise Makit::BuildError, message_parts.join("\\n")
182
- end
183
- end
184
- end
185
- end
186
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "validator"
4
+ require_relative "repository_manager"
5
+
6
+ module Makit
7
+ module Services
8
+ # Service class responsible for build operations and make processes
9
+ # Handles the complex build workflow including repository setup and execution
10
+ class Builder
11
+ class << self
12
+ # Build a repository at a specific commit
13
+ #
14
+ # @param url [String] the git repository URL
15
+ # @param commit [String] the commit hash or "latest" for the most recent commit
16
+ # @param force [Boolean] whether to force rebuild even if cached result exists
17
+ # @return [Makit::V1::MakeResult] the build result with all command outputs
18
+ def make_repository(url, commit, force: false)
19
+ Validator.validate_url_parameter(url)
20
+ Validator.validate_commit_parameter(commit)
21
+
22
+ log_filename = get_log_filename(url, commit)
23
+
24
+ return load_existing_result(log_filename) if should_load_existing_result?(log_filename, force, commit)
25
+
26
+ execute_make_process(url, commit, log_filename)
27
+ end
28
+
29
+ # Ensure .gitignore exists in the current directory
30
+ def ensure_gitignore
31
+ return if File.exist?(".gitignore")
32
+
33
+ Makit::LOGGER.info("added .gitignore file")
34
+ File.open(".gitignore", "w") do |file|
35
+ file.puts Makit::Content::GITIGNORE
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # Get the log filename for storing build results
42
+ def get_log_filename(url, commit)
43
+ File.join(
44
+ Directories.get_log_directory(url),
45
+ commit,
46
+ "#{Makit::RUNTIME_IDENTIFIER}.#{Makit::DEVICE}.json"
47
+ )
48
+ end
49
+
50
+ # Check if we should load an existing cached result
51
+ def should_load_existing_result?(log_filename, force, commit)
52
+ File.exist?(log_filename) && !force && commit != Validator::COMMIT_LATEST
53
+ end
54
+
55
+ # Load existing build result from cache
56
+ def load_existing_result(log_filename)
57
+ Makit::V1::MakeResult.decode_json(File.read(log_filename))
58
+ rescue StandardError
59
+ FileUtils.rm(log_filename)
60
+ nil
61
+ end
62
+
63
+ # Execute the complete make process
64
+ def execute_make_process(url, commit, log_filename)
65
+ commands = []
66
+ begin
67
+ commands = setup_repository_for_build(url, commit, log_filename)
68
+ make_result = build_make_result(url, commit, commands)
69
+ save_make_result(make_result, log_filename)
70
+ make_result
71
+ rescue StandardError => e
72
+ handle_make_error(e, url, commit, commands)
73
+ end
74
+ end
75
+
76
+ # Set up repository for build process
77
+ def setup_repository_for_build(url, commit, log_filename)
78
+ commands = initialize_repository_commands(url)
79
+
80
+ clone_dir = RepositoryManager.validate_clone_directory(url)
81
+ resolved_commit = resolve_commit_reference(commit, clone_dir, commands, log_filename, url)
82
+ prepare_make_directory(url, resolved_commit, clone_dir, commands)
83
+
84
+ commands
85
+ end
86
+
87
+ # Initialize repository commands (clone or pull)
88
+ def initialize_repository_commands(url)
89
+ RepositoryManager.clone_or_pull_repository(url).flatten
90
+ end
91
+
92
+ # Resolve commit reference (handle "latest" commit)
93
+ def resolve_commit_reference(commit, clone_dir, commands, log_filename, url)
94
+ return commit unless commit == Validator::COMMIT_LATEST
95
+
96
+ latest_commit = RepositoryManager.get_latest_commit(clone_dir, commands)
97
+ # Update log filename with resolved commit hash
98
+ log_filename.replace(
99
+ File.join(
100
+ Directories.get_log_directory(url),
101
+ latest_commit,
102
+ "#{Makit::RUNTIME_IDENTIFIER}.#{Makit::DEVICE}.json"
103
+ )
104
+ )
105
+ latest_commit
106
+ end
107
+
108
+ # Prepare make directory with repository clone
109
+ def prepare_make_directory(url, commit, clone_dir, commands)
110
+ make_dir = Directories.get_make_commit_directory(url, commit)
111
+ FileUtils.rm_rf(make_dir)
112
+
113
+ clone_command = Makit::Commands::Runner.default.execute("git clone #{clone_dir} #{make_dir}")
114
+ commands << clone_command
115
+
116
+ return if Dir.exist?(make_dir)
117
+
118
+ raise Makit::CloneError, "failed to clone repository: #{url} to #{make_dir}"
119
+ end
120
+
121
+ # Build the make result by executing all build steps
122
+ def build_make_result(url, commit, commands)
123
+ Dir.chdir(Directories.get_make_commit_directory(url, commit)) do
124
+ execute_git_commands(commit, commands)
125
+ execute_build_commands(commands)
126
+
127
+ make_result = create_make_result_object(url, commit)
128
+ commands.flatten.each { |command| make_result.commands << command }
129
+ make_result
130
+ end
131
+ end
132
+
133
+ # Execute git-specific commands for the build
134
+ def execute_git_commands(commit, commands)
135
+ commands << Makit::Commands::Runner.default.execute("git reset --hard #{commit}")
136
+ commands << Makit::Commands::Runner.default.execute("git log -n 1")
137
+ end
138
+
139
+ # Execute build commands (bundle, rake, etc.)
140
+ def execute_build_commands(commands)
141
+ commands << Makit::Commands::Runner.default.execute("bundle install") if File.exist?("Gemfile")
142
+
143
+ return unless File.exist?("Rakefile") || File.exist?("rakefile.rb")
144
+
145
+ commands << Makit::Commands::Runner.default.execute("rake default")
146
+ end
147
+
148
+ # Create the make result object
149
+ def create_make_result_object(url, commit)
150
+ Makit::V1::MakeResult.new(
151
+ repository: url,
152
+ commit: commit,
153
+ branch: "?",
154
+ tag: "?",
155
+ device: Makit::DEVICE,
156
+ runtime_identifier: Makit::RUNTIME_IDENTIFIER,
157
+ )
158
+ end
159
+
160
+ # Save make result to file
161
+ def save_make_result(make_result, log_filename)
162
+ FileUtils.mkdir_p(File.dirname(log_filename))
163
+ File.write(log_filename, make_result.to_json)
164
+ end
165
+
166
+ # Handle make process errors
167
+ def handle_make_error(error, url, commit, commands)
168
+ message_parts = [
169
+ "error raised attempting to make repository: #{url} commit: #{commit}",
170
+ "",
171
+ error.message,
172
+ error.backtrace.join("\\n"),
173
+ "",
174
+ "commands:",
175
+ ]
176
+
177
+ commands.flatten.each do |command|
178
+ message_parts << Makit::Humanize.get_command_details(command)
179
+ end
180
+
181
+ raise Makit::BuildError, message_parts.join("\\n")
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end