makit 0.0.167 → 0.0.169

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 (179) 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/azure-pipelines.rb +187 -187
  9. data/lib/makit/cli/base.rb +17 -17
  10. data/lib/makit/cli/build_commands.rb +500 -500
  11. data/lib/makit/cli/generators/base_generator.rb +74 -74
  12. data/lib/makit/cli/generators/dotnet_generator.rb +50 -50
  13. data/lib/makit/cli/generators/generator_factory.rb +49 -49
  14. data/lib/makit/cli/generators/node_generator.rb +50 -50
  15. data/lib/makit/cli/generators/ruby_generator.rb +77 -77
  16. data/lib/makit/cli/generators/rust_generator.rb +50 -50
  17. data/lib/makit/cli/generators/templates/dotnet_templates.rb +167 -167
  18. data/lib/makit/cli/generators/templates/node_templates.rb +161 -161
  19. data/lib/makit/cli/generators/templates/ruby/gemfile.rb +26 -26
  20. data/lib/makit/cli/generators/templates/ruby/gemspec.rb +41 -41
  21. data/lib/makit/cli/generators/templates/ruby/main_lib.rb +33 -33
  22. data/lib/makit/cli/generators/templates/ruby/rakefile.rb +35 -35
  23. data/lib/makit/cli/generators/templates/ruby/readme.rb +63 -63
  24. data/lib/makit/cli/generators/templates/ruby/test.rb +39 -39
  25. data/lib/makit/cli/generators/templates/ruby/test_helper.rb +29 -29
  26. data/lib/makit/cli/generators/templates/ruby/version.rb +29 -29
  27. data/lib/makit/cli/generators/templates/rust_templates.rb +128 -128
  28. data/lib/makit/cli/main.rb +78 -78
  29. data/lib/makit/cli/pipeline_commands.rb +311 -311
  30. data/lib/makit/cli/project_commands.rb +868 -868
  31. data/lib/makit/cli/repository_commands.rb +661 -661
  32. data/lib/makit/cli/strategy_commands.rb +207 -207
  33. data/lib/makit/cli/utility_commands.rb +521 -521
  34. data/lib/makit/commands/factory.rb +359 -359
  35. data/lib/makit/commands/middleware/base.rb +73 -73
  36. data/lib/makit/commands/middleware/cache.rb +248 -248
  37. data/lib/makit/commands/middleware/command_logger.rb +312 -312
  38. data/lib/makit/commands/middleware/validator.rb +269 -269
  39. data/lib/makit/commands/request.rb +316 -316
  40. data/lib/makit/commands/result.rb +323 -323
  41. data/lib/makit/commands/runner.rb +386 -386
  42. data/lib/makit/commands/strategies/base.rb +171 -171
  43. data/lib/makit/commands/strategies/child_process.rb +162 -162
  44. data/lib/makit/commands/strategies/factory.rb +136 -136
  45. data/lib/makit/commands/strategies/synchronous.rb +139 -139
  46. data/lib/makit/commands.rb +50 -50
  47. data/lib/makit/configuration/dotnet_project.rb +48 -48
  48. data/lib/makit/configuration/gitlab_helper.rb +61 -61
  49. data/lib/makit/configuration/project.rb +292 -292
  50. data/lib/makit/configuration/rakefile_helper.rb +43 -43
  51. data/lib/makit/configuration/step.rb +34 -34
  52. data/lib/makit/configuration/timeout.rb +74 -74
  53. data/lib/makit/configuration.rb +21 -21
  54. data/lib/makit/content/default_gitignore.rb +7 -7
  55. data/lib/makit/content/default_gitignore.txt +225 -225
  56. data/lib/makit/content/default_rakefile.rb +13 -13
  57. data/lib/makit/content/gem_rakefile.rb +16 -16
  58. data/lib/makit/context.rb +1 -1
  59. data/lib/makit/data.rb +49 -49
  60. data/lib/makit/directories.rb +170 -170
  61. data/lib/makit/directory.rb +262 -262
  62. data/lib/makit/docs/files.rb +89 -89
  63. data/lib/makit/docs/rake.rb +102 -102
  64. data/lib/makit/dotnet/cli.rb +224 -224
  65. data/lib/makit/dotnet/project.rb +217 -217
  66. data/lib/makit/dotnet/solution.rb +38 -38
  67. data/lib/makit/dotnet/solution_classlib.rb +239 -239
  68. data/lib/makit/dotnet/solution_console.rb +264 -264
  69. data/lib/makit/dotnet/solution_maui.rb +354 -354
  70. data/lib/makit/dotnet/solution_wasm.rb +275 -275
  71. data/lib/makit/dotnet/solution_wpf.rb +304 -304
  72. data/lib/makit/dotnet.rb +110 -110
  73. data/lib/makit/email.rb +90 -90
  74. data/lib/makit/environment.rb +142 -142
  75. data/lib/makit/examples/runner.rb +370 -370
  76. data/lib/makit/exceptions.rb +45 -45
  77. data/lib/makit/fileinfo.rb +32 -32
  78. data/lib/makit/files.rb +43 -43
  79. data/lib/makit/gems.rb +49 -49
  80. data/lib/makit/git/cli.rb +103 -103
  81. data/lib/makit/git/repository.rb +100 -100
  82. data/lib/makit/git.rb +104 -104
  83. data/lib/makit/github_actions.rb +202 -0
  84. data/lib/makit/gitlab/pipeline.rb +857 -857
  85. data/lib/makit/gitlab/pipeline_service_impl.rb +1535 -1535
  86. data/lib/makit/gitlab_runner.rb +59 -59
  87. data/lib/makit/humanize.rb +218 -218
  88. data/lib/makit/indexer.rb +47 -47
  89. data/lib/makit/io/filesystem.rb +111 -111
  90. data/lib/makit/io/filesystem_service_impl.rb +337 -337
  91. data/lib/makit/lint.rb +212 -212
  92. data/lib/makit/logging/configuration.rb +309 -309
  93. data/lib/makit/logging/format_registry.rb +84 -84
  94. data/lib/makit/logging/formatters/base.rb +39 -39
  95. data/lib/makit/logging/formatters/console_formatter.rb +140 -140
  96. data/lib/makit/logging/formatters/json_formatter.rb +65 -65
  97. data/lib/makit/logging/formatters/plain_text_formatter.rb +71 -71
  98. data/lib/makit/logging/formatters/text_formatter.rb +64 -64
  99. data/lib/makit/logging/log_request.rb +119 -119
  100. data/lib/makit/logging/logger.rb +199 -199
  101. data/lib/makit/logging/sinks/base.rb +91 -91
  102. data/lib/makit/logging/sinks/console.rb +72 -72
  103. data/lib/makit/logging/sinks/file_sink.rb +92 -92
  104. data/lib/makit/logging/sinks/structured.rb +123 -123
  105. data/lib/makit/logging/sinks/unified_file_sink.rb +296 -296
  106. data/lib/makit/logging.rb +578 -578
  107. data/lib/makit/markdown.rb +75 -75
  108. data/lib/makit/mp/basic_object_mp.rb +17 -17
  109. data/lib/makit/mp/command_mp.rb +13 -13
  110. data/lib/makit/mp/command_request.mp.rb +17 -17
  111. data/lib/makit/mp/project_mp.rb +199 -199
  112. data/lib/makit/mp/string_mp.rb +205 -205
  113. data/lib/makit/nuget.rb +460 -454
  114. data/lib/makit/podman/podman.rb +458 -458
  115. data/lib/makit/podman/podman_service_impl.rb +1081 -1081
  116. data/lib/makit/port.rb +32 -32
  117. data/lib/makit/process.rb +377 -377
  118. data/lib/makit/protoc.rb +112 -112
  119. data/lib/makit/rake/cli.rb +196 -196
  120. data/lib/makit/rake/trace_controller.rb +174 -174
  121. data/lib/makit/rake.rb +81 -81
  122. data/lib/makit/ruby/cli.rb +185 -185
  123. data/lib/makit/ruby.rb +25 -25
  124. data/lib/makit/rubygems.rb +137 -137
  125. data/lib/makit/secrets/azure_key_vault.rb +322 -322
  126. data/lib/makit/secrets/azure_secrets.rb +221 -221
  127. data/lib/makit/secrets/local_secrets.rb +72 -72
  128. data/lib/makit/secrets/secrets_manager.rb +105 -105
  129. data/lib/makit/secrets.rb +96 -96
  130. data/lib/makit/serializer.rb +130 -130
  131. data/lib/makit/services/builder.rb +186 -186
  132. data/lib/makit/services/error_handler.rb +226 -226
  133. data/lib/makit/services/repository_manager.rb +367 -367
  134. data/lib/makit/services/validator.rb +112 -112
  135. data/lib/makit/setup/classlib.rb +101 -101
  136. data/lib/makit/setup/gem.rb +268 -268
  137. data/lib/makit/setup/pages.rb +11 -11
  138. data/lib/makit/setup/razorclasslib.rb +101 -101
  139. data/lib/makit/setup/runner.rb +54 -54
  140. data/lib/makit/setup.rb +5 -5
  141. data/lib/makit/show.rb +110 -110
  142. data/lib/makit/storage.rb +126 -126
  143. data/lib/makit/symbols.rb +175 -175
  144. data/lib/makit/task_info.rb +130 -130
  145. data/lib/makit/tasks/at_exit.rb +15 -15
  146. data/lib/makit/tasks/build.rb +22 -22
  147. data/lib/makit/tasks/bump.rb +7 -7
  148. data/lib/makit/tasks/clean.rb +13 -13
  149. data/lib/makit/tasks/configure.rb +10 -10
  150. data/lib/makit/tasks/format.rb +10 -10
  151. data/lib/makit/tasks/hook_manager.rb +443 -443
  152. data/lib/makit/tasks/info.rb +368 -368
  153. data/lib/makit/tasks/init.rb +49 -49
  154. data/lib/makit/tasks/integrate.rb +60 -60
  155. data/lib/makit/tasks/pull_incoming.rb +13 -13
  156. data/lib/makit/tasks/secrets.rb +7 -7
  157. data/lib/makit/tasks/setup.rb +16 -16
  158. data/lib/makit/tasks/sync.rb +14 -14
  159. data/lib/makit/tasks/tag.rb +27 -27
  160. data/lib/makit/tasks/task_monkey_patch.rb +81 -81
  161. data/lib/makit/tasks/test.rb +22 -22
  162. data/lib/makit/tasks/update.rb +21 -21
  163. data/lib/makit/tasks/version.rb +6 -6
  164. data/lib/makit/tasks.rb +24 -24
  165. data/lib/makit/test_cache.rb +239 -239
  166. data/lib/makit/tree.rb +37 -37
  167. data/lib/makit/v1/configuration/project_service_impl.rb +370 -370
  168. data/lib/makit/v1/git/git_repository_service_impl.rb +295 -295
  169. data/lib/makit/v1/makit.v1_pb.rb +35 -35
  170. data/lib/makit/v1/makit.v1_services_pb.rb +27 -27
  171. data/lib/makit/v1/services/repository_manager_service_impl.rb +572 -572
  172. data/lib/makit/version.rb +661 -661
  173. data/lib/makit/version_util.rb +21 -21
  174. data/lib/makit/wix.rb +95 -95
  175. data/lib/makit/yaml.rb +29 -29
  176. data/lib/makit/zip.rb +17 -17
  177. data/lib/makit copy.rb +44 -44
  178. data/lib/makit.rb +121 -120
  179. metadata +3 -2
@@ -1,221 +1,221 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "azure_key_vault"
4
-
5
- module Makit
6
- module Secrets
7
- # Azure Key Vault adapter that implements the LocalSecrets interface
8
- # Uses Azure CLI to store and retrieve individual secrets
9
- class AzureSecrets
10
- def initialize(keyvault_name: nil, secret_prefix: nil)
11
- @keyvault_name = keyvault_name || AzureKeyVault.keyvault_name
12
- @secret_prefix = secret_prefix || AzureKeyVault.secret_prefix
13
- raise "Azure Key Vault name is required" if @keyvault_name.nil? || @keyvault_name.empty?
14
- end
15
-
16
- def add(key, value)
17
- set(key, value)
18
- end
19
-
20
- def remove(key)
21
- secret_name = build_secret_name(key)
22
- return true unless secret_exists?(secret_name)
23
-
24
- unless AzureKeyVault.azure_cli_authenticated?
25
- raise "Azure CLI is not authenticated. Run 'az login' first"
26
- end
27
-
28
- cmd = [
29
- "az keyvault secret delete",
30
- "--vault-name '#{@keyvault_name}'",
31
- "--name '#{secret_name}'",
32
- "2>&1"
33
- ].join(" ")
34
-
35
- output = `#{cmd}`
36
- exit_code = $?.exitstatus
37
-
38
- if exit_code != 0
39
- raise "Failed to delete secret '#{secret_name}': #{output}"
40
- end
41
-
42
- true
43
- end
44
-
45
- def has_key?(key)
46
- secret_name = build_secret_name(key)
47
- secret_exists?(secret_name)
48
- end
49
-
50
- def get(key)
51
- secret_name = build_secret_name(key)
52
- return nil unless secret_exists?(secret_name)
53
-
54
- unless AzureKeyVault.azure_cli_authenticated?
55
- raise "Azure CLI is not authenticated. Run 'az login' first"
56
- end
57
-
58
- cmd = [
59
- "az keyvault secret show",
60
- "--vault-name '#{@keyvault_name}'",
61
- "--name '#{secret_name}'",
62
- "--query value",
63
- "-o tsv",
64
- "2>&1"
65
- ].join(" ")
66
-
67
- output = `#{cmd}`.strip
68
- exit_code = $?.exitstatus
69
-
70
- if exit_code != 0
71
- nil
72
- else
73
- output
74
- end
75
- end
76
-
77
- def set(key, value)
78
- secret_name = build_secret_name(key)
79
- success = AzureKeyVault.set(secret_name, value.to_s, keyvault_name: @keyvault_name)
80
- unless success
81
- raise "Failed to set secret '#{secret_name}' in Azure Key Vault '#{@keyvault_name}'"
82
- end
83
- true
84
- end
85
-
86
- def get_secrets_filename
87
- "#{@keyvault_name}/secrets"
88
- end
89
-
90
- def get_secrets_hash
91
- # Load all secrets from Azure Key Vault
92
- # This is a simplified version - in practice, you might want to list all secrets
93
- # For now, we'll return an empty hash and let individual get() calls retrieve secrets
94
- {}
95
- end
96
-
97
- def save_secrets_hash(hash)
98
- # Save all secrets from hash to Azure Key Vault
99
- hash.each do |key, value|
100
- set(key, value)
101
- end
102
- end
103
-
104
- def info
105
- unless AzureKeyVault.azure_cli_authenticated?
106
- puts " Azure CLI is not authenticated. Run 'az login' first"
107
- return
108
- end
109
-
110
- cmd = [
111
- "az keyvault secret list",
112
- "--vault-name '#{@keyvault_name}'",
113
- "--query '[].name'",
114
- "-o tsv",
115
- "2>&1"
116
- ].join(" ")
117
-
118
- output = `#{cmd}`.strip
119
- exit_code = $?.exitstatus
120
-
121
- if exit_code != 0
122
- # Check if it's a permission error
123
- if output.include?("Forbidden") || output.include?("ForbiddenByRbac")
124
- puts " Error: Insufficient permissions to list secrets from Azure Key Vault"
125
- puts " The authenticated identity does not have the required RBAC permissions."
126
- puts " Required permission: 'Microsoft.KeyVault/vaults/secrets/readMetadata/action'"
127
- puts " Required role: 'Key Vault Secrets User' or 'Key Vault Secrets Officer'"
128
- puts " Vault: #{@keyvault_name}"
129
- puts ""
130
- puts " To fix this, ask your Azure administrator to grant you one of these roles:"
131
- puts " - Key Vault Secrets User (read-only access to secret names and values)"
132
- puts " - Key Vault Secrets Officer (full access to secrets)"
133
- else
134
- puts " Error: Failed to list secrets from Azure Key Vault"
135
- puts " #{output}"
136
- end
137
- return
138
- end
139
-
140
- secret_names = output.split("\n").map(&:strip).reject(&:empty?)
141
-
142
- if @secret_prefix
143
- # Filter secrets that match the prefix and remove the prefix
144
- filtered_secrets = secret_names.select { |name| name.start_with?("#{@secret_prefix}-") }
145
- .map { |name| name.sub(/^#{Regexp.escape(@secret_prefix)}-/, "") }
146
- else
147
- filtered_secrets = secret_names
148
- end
149
-
150
- if filtered_secrets.empty?
151
- puts " No secrets found"
152
- else
153
- puts " Available secrets (#{filtered_secrets.count}):"
154
- filtered_secrets.sort.each do |key|
155
- puts " - #{key}"
156
- end
157
- end
158
- end
159
-
160
- private
161
-
162
- # Builds a valid Azure Key Vault secret name from a key
163
- # Azure Key Vault secret names must be 1-127 characters, alphanumeric and hyphens only,
164
- # cannot start or end with hyphen, and cannot have consecutive hyphens
165
- def build_secret_name(key)
166
- # Sanitize the key to make it valid for Azure Key Vault
167
- sanitized_key = sanitize_secret_name(key.to_s)
168
-
169
- if @secret_prefix
170
- "#{@secret_prefix}-#{sanitized_key}"
171
- else
172
- sanitized_key
173
- end
174
- end
175
-
176
- # Sanitizes a secret name to be valid for Azure Key Vault
177
- # Rules: 1-127 characters, alphanumeric and hyphens only,
178
- # cannot start or end with hyphen, cannot have consecutive hyphens
179
- def sanitize_secret_name(name)
180
- # Replace invalid characters with hyphens
181
- name = name.gsub(/[^a-zA-Z0-9\-]/, "-")
182
-
183
- # Remove consecutive hyphens
184
- name = name.gsub(/-+/, "-")
185
-
186
- # Remove leading/trailing hyphens
187
- name = name.gsub(/^-+|-+$/, "")
188
-
189
- # Ensure it starts with a letter or number (Azure requirement)
190
- name = "secret-#{name}" if name.empty? || name.match(/^[^a-zA-Z0-9]/)
191
-
192
- # Truncate to 127 characters (Azure Key Vault limit)
193
- name = name[0, 127]
194
-
195
- # Remove trailing hyphen if truncation created one
196
- name = name.gsub(/-+$/, "")
197
-
198
- # Ensure it's not empty
199
- name = "secret" if name.empty?
200
-
201
- name
202
- end
203
-
204
- def secret_exists?(secret_name)
205
- unless AzureKeyVault.azure_cli_authenticated?
206
- return false
207
- end
208
-
209
- cmd = [
210
- "az keyvault secret show",
211
- "--vault-name '#{@keyvault_name}'",
212
- "--name '#{secret_name}'",
213
- "2>&1"
214
- ].join(" ")
215
-
216
- system("#{cmd} > /dev/null 2>&1")
217
- end
218
- end
219
- end
220
- end
221
-
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "azure_key_vault"
4
+
5
+ module Makit
6
+ module Secrets
7
+ # Azure Key Vault adapter that implements the LocalSecrets interface
8
+ # Uses Azure CLI to store and retrieve individual secrets
9
+ class AzureSecrets
10
+ def initialize(keyvault_name: nil, secret_prefix: nil)
11
+ @keyvault_name = keyvault_name || AzureKeyVault.keyvault_name
12
+ @secret_prefix = secret_prefix || AzureKeyVault.secret_prefix
13
+ raise "Azure Key Vault name is required" if @keyvault_name.nil? || @keyvault_name.empty?
14
+ end
15
+
16
+ def add(key, value)
17
+ set(key, value)
18
+ end
19
+
20
+ def remove(key)
21
+ secret_name = build_secret_name(key)
22
+ return true unless secret_exists?(secret_name)
23
+
24
+ unless AzureKeyVault.azure_cli_authenticated?
25
+ raise "Azure CLI is not authenticated. Run 'az login' first"
26
+ end
27
+
28
+ cmd = [
29
+ "az keyvault secret delete",
30
+ "--vault-name '#{@keyvault_name}'",
31
+ "--name '#{secret_name}'",
32
+ "2>&1"
33
+ ].join(" ")
34
+
35
+ output = `#{cmd}`
36
+ exit_code = $?.exitstatus
37
+
38
+ if exit_code != 0
39
+ raise "Failed to delete secret '#{secret_name}': #{output}"
40
+ end
41
+
42
+ true
43
+ end
44
+
45
+ def has_key?(key)
46
+ secret_name = build_secret_name(key)
47
+ secret_exists?(secret_name)
48
+ end
49
+
50
+ def get(key)
51
+ secret_name = build_secret_name(key)
52
+ return nil unless secret_exists?(secret_name)
53
+
54
+ unless AzureKeyVault.azure_cli_authenticated?
55
+ raise "Azure CLI is not authenticated. Run 'az login' first"
56
+ end
57
+
58
+ cmd = [
59
+ "az keyvault secret show",
60
+ "--vault-name '#{@keyvault_name}'",
61
+ "--name '#{secret_name}'",
62
+ "--query value",
63
+ "-o tsv",
64
+ "2>&1"
65
+ ].join(" ")
66
+
67
+ output = `#{cmd}`.strip
68
+ exit_code = $?.exitstatus
69
+
70
+ if exit_code != 0
71
+ nil
72
+ else
73
+ output
74
+ end
75
+ end
76
+
77
+ def set(key, value)
78
+ secret_name = build_secret_name(key)
79
+ success = AzureKeyVault.set(secret_name, value.to_s, keyvault_name: @keyvault_name)
80
+ unless success
81
+ raise "Failed to set secret '#{secret_name}' in Azure Key Vault '#{@keyvault_name}'"
82
+ end
83
+ true
84
+ end
85
+
86
+ def get_secrets_filename
87
+ "#{@keyvault_name}/secrets"
88
+ end
89
+
90
+ def get_secrets_hash
91
+ # Load all secrets from Azure Key Vault
92
+ # This is a simplified version - in practice, you might want to list all secrets
93
+ # For now, we'll return an empty hash and let individual get() calls retrieve secrets
94
+ {}
95
+ end
96
+
97
+ def save_secrets_hash(hash)
98
+ # Save all secrets from hash to Azure Key Vault
99
+ hash.each do |key, value|
100
+ set(key, value)
101
+ end
102
+ end
103
+
104
+ def info
105
+ unless AzureKeyVault.azure_cli_authenticated?
106
+ puts " Azure CLI is not authenticated. Run 'az login' first"
107
+ return
108
+ end
109
+
110
+ cmd = [
111
+ "az keyvault secret list",
112
+ "--vault-name '#{@keyvault_name}'",
113
+ "--query '[].name'",
114
+ "-o tsv",
115
+ "2>&1"
116
+ ].join(" ")
117
+
118
+ output = `#{cmd}`.strip
119
+ exit_code = $?.exitstatus
120
+
121
+ if exit_code != 0
122
+ # Check if it's a permission error
123
+ if output.include?("Forbidden") || output.include?("ForbiddenByRbac")
124
+ puts " Error: Insufficient permissions to list secrets from Azure Key Vault"
125
+ puts " The authenticated identity does not have the required RBAC permissions."
126
+ puts " Required permission: 'Microsoft.KeyVault/vaults/secrets/readMetadata/action'"
127
+ puts " Required role: 'Key Vault Secrets User' or 'Key Vault Secrets Officer'"
128
+ puts " Vault: #{@keyvault_name}"
129
+ puts ""
130
+ puts " To fix this, ask your Azure administrator to grant you one of these roles:"
131
+ puts " - Key Vault Secrets User (read-only access to secret names and values)"
132
+ puts " - Key Vault Secrets Officer (full access to secrets)"
133
+ else
134
+ puts " Error: Failed to list secrets from Azure Key Vault"
135
+ puts " #{output}"
136
+ end
137
+ return
138
+ end
139
+
140
+ secret_names = output.split("\n").map(&:strip).reject(&:empty?)
141
+
142
+ if @secret_prefix
143
+ # Filter secrets that match the prefix and remove the prefix
144
+ filtered_secrets = secret_names.select { |name| name.start_with?("#{@secret_prefix}-") }
145
+ .map { |name| name.sub(/^#{Regexp.escape(@secret_prefix)}-/, "") }
146
+ else
147
+ filtered_secrets = secret_names
148
+ end
149
+
150
+ if filtered_secrets.empty?
151
+ puts " No secrets found"
152
+ else
153
+ puts " Available secrets (#{filtered_secrets.count}):"
154
+ filtered_secrets.sort.each do |key|
155
+ puts " - #{key}"
156
+ end
157
+ end
158
+ end
159
+
160
+ private
161
+
162
+ # Builds a valid Azure Key Vault secret name from a key
163
+ # Azure Key Vault secret names must be 1-127 characters, alphanumeric and hyphens only,
164
+ # cannot start or end with hyphen, and cannot have consecutive hyphens
165
+ def build_secret_name(key)
166
+ # Sanitize the key to make it valid for Azure Key Vault
167
+ sanitized_key = sanitize_secret_name(key.to_s)
168
+
169
+ if @secret_prefix
170
+ "#{@secret_prefix}-#{sanitized_key}"
171
+ else
172
+ sanitized_key
173
+ end
174
+ end
175
+
176
+ # Sanitizes a secret name to be valid for Azure Key Vault
177
+ # Rules: 1-127 characters, alphanumeric and hyphens only,
178
+ # cannot start or end with hyphen, cannot have consecutive hyphens
179
+ def sanitize_secret_name(name)
180
+ # Replace invalid characters with hyphens
181
+ name = name.gsub(/[^a-zA-Z0-9\-]/, "-")
182
+
183
+ # Remove consecutive hyphens
184
+ name = name.gsub(/-+/, "-")
185
+
186
+ # Remove leading/trailing hyphens
187
+ name = name.gsub(/^-+|-+$/, "")
188
+
189
+ # Ensure it starts with a letter or number (Azure requirement)
190
+ name = "secret-#{name}" if name.empty? || name.match(/^[^a-zA-Z0-9]/)
191
+
192
+ # Truncate to 127 characters (Azure Key Vault limit)
193
+ name = name[0, 127]
194
+
195
+ # Remove trailing hyphen if truncation created one
196
+ name = name.gsub(/-+$/, "")
197
+
198
+ # Ensure it's not empty
199
+ name = "secret" if name.empty?
200
+
201
+ name
202
+ end
203
+
204
+ def secret_exists?(secret_name)
205
+ unless AzureKeyVault.azure_cli_authenticated?
206
+ return false
207
+ end
208
+
209
+ cmd = [
210
+ "az keyvault secret show",
211
+ "--vault-name '#{@keyvault_name}'",
212
+ "--name '#{secret_name}'",
213
+ "2>&1"
214
+ ].join(" ")
215
+
216
+ system("#{cmd} > /dev/null 2>&1")
217
+ end
218
+ end
219
+ end
220
+ end
221
+
@@ -1,72 +1,72 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require_relative "../directories" unless defined?(Makit::Directories)
5
-
6
- module Makit
7
- module Secrets
8
- class LocalSecrets
9
- def add(key, value)
10
- secrets_hash = get_secrets_hash
11
- secrets_hash[key] = value
12
- save_secrets_hash(secrets_hash)
13
- end
14
-
15
- def remove(key)
16
- secrets_hash = get_secrets_hash
17
- secrets_hash.delete(key)
18
- save_secrets_hash(secrets_hash)
19
- end
20
-
21
- def has_key?(key)
22
- secrets_hash = get_secrets_hash
23
- secrets_hash.key?(key)
24
- end
25
-
26
- def get(key)
27
- secrets_hash = get_secrets_hash
28
- secrets_hash[key]
29
- end
30
-
31
- def set(key, value)
32
- secrets_hash = get_secrets_hash
33
- secrets_hash[key] = value
34
- save_secrets_hash(secrets_hash)
35
- end
36
-
37
- def get_secrets_filename
38
- "#{Makit::Directories::ROOT}/secrets.json"
39
- end
40
-
41
- def get_secrets_hash
42
- secrets_file = get_secrets_filename
43
- return {} unless File.exist?(secrets_file)
44
-
45
- text = File.read(secrets_file).strip
46
- return {} if text.empty?
47
-
48
- JSON.parse(text)
49
- rescue JSON::ParserError
50
- {}
51
- end
52
-
53
- def save_secrets_hash(hash)
54
- secrets_file = get_secrets_filename
55
- # pretty print the hash
56
- File.open(secrets_file, "w") { |f| f.puts JSON.pretty_generate(hash) }
57
- end
58
-
59
- def info
60
- secrets_hash = get_secrets_hash
61
- if secrets_hash.empty?
62
- puts " No secrets found"
63
- else
64
- puts " Available secrets (#{secrets_hash.keys.count}):"
65
- secrets_hash.keys.sort.each do |key|
66
- puts " - #{key}"
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require_relative "../directories" unless defined?(Makit::Directories)
5
+
6
+ module Makit
7
+ module Secrets
8
+ class LocalSecrets
9
+ def add(key, value)
10
+ secrets_hash = get_secrets_hash
11
+ secrets_hash[key] = value
12
+ save_secrets_hash(secrets_hash)
13
+ end
14
+
15
+ def remove(key)
16
+ secrets_hash = get_secrets_hash
17
+ secrets_hash.delete(key)
18
+ save_secrets_hash(secrets_hash)
19
+ end
20
+
21
+ def has_key?(key)
22
+ secrets_hash = get_secrets_hash
23
+ secrets_hash.key?(key)
24
+ end
25
+
26
+ def get(key)
27
+ secrets_hash = get_secrets_hash
28
+ secrets_hash[key]
29
+ end
30
+
31
+ def set(key, value)
32
+ secrets_hash = get_secrets_hash
33
+ secrets_hash[key] = value
34
+ save_secrets_hash(secrets_hash)
35
+ end
36
+
37
+ def get_secrets_filename
38
+ "#{Makit::Directories::ROOT}/secrets.json"
39
+ end
40
+
41
+ def get_secrets_hash
42
+ secrets_file = get_secrets_filename
43
+ return {} unless File.exist?(secrets_file)
44
+
45
+ text = File.read(secrets_file).strip
46
+ return {} if text.empty?
47
+
48
+ JSON.parse(text)
49
+ rescue JSON::ParserError
50
+ {}
51
+ end
52
+
53
+ def save_secrets_hash(hash)
54
+ secrets_file = get_secrets_filename
55
+ # pretty print the hash
56
+ File.open(secrets_file, "w") { |f| f.puts JSON.pretty_generate(hash) }
57
+ end
58
+
59
+ def info
60
+ secrets_hash = get_secrets_hash
61
+ if secrets_hash.empty?
62
+ puts " No secrets found"
63
+ else
64
+ puts " Available secrets (#{secrets_hash.keys.count}):"
65
+ secrets_hash.keys.sort.each do |key|
66
+ puts " - #{key}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end