git_auto 0.1.1 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75fb5c81e9b1d07b927497d979188dc2e936711395a8b9aa6919065d6ed0903b
4
- data.tar.gz: 612044fb323c934e36209942ef16004e7acdb7e441641da6b4e016a976a4cd37
3
+ metadata.gz: 22c8ad3c04eb8a867d883b2691754ad36929589071ecad9c2fb7e064405ccc3b
4
+ data.tar.gz: 820042feceec36279aa4a1de8fb396d9c30d58257ded1ba0976b8d1c843ce2d6
5
5
  SHA512:
6
- metadata.gz: 578fd8cf70256433e05bb75ea58df3f216170e5f5f20f8b54547c8f23fd17758637eb2c5aa0fc895cf5c69c8ec32f1db23cb6c1da67773d93747917e722ea2fe
7
- data.tar.gz: dd583910a1e13dcc2deb729e4a2d78ed60efde03617e6521370f11a2efcf094718ff1257e203660eb243e61ea250934f6a6a1f2d14a8cf06e014226159ede5aa
6
+ metadata.gz: 3cc3d42b26dad5d0425201c8e9dfd674fe4ffef4fd89ba26671a2d0bbfb4c2f053ae31a92afdd8279015c3688f9c62c0fb846ad2a8464737b8c5fa6f4f0dd38d
7
+ data.tar.gz: 853b80adf98ed8b3be60f2bf6a84f4c861d564c01bd67981adec30091cfd85136a8f3ab7b3479a0159c5aec797016ea37eef20f872446f163e5256423a454417
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.1] - 2024-03-21
9
+
10
+ ### Fixed
11
+ - Fixed error when displaying repository status with no staged files
12
+ - Improved error handling in repository status display
13
+ - Simplified status output when no changes are staged
14
+
15
+ ## [0.2.0] - 2024-03-20
16
+
17
+ ### Added
18
+ - Support for multiple AI providers (OpenAI and Anthropic)
19
+ - New commit message styles (minimal, conventional, simple)
20
+ - Commit history analysis
21
+ - Pattern detection for commit types and scopes
22
+ - Secure API key storage with encryption
23
+
24
+ ### Changed
25
+ - Improved error messages and validation
26
+ - Enhanced diff formatting and preview
27
+ - Better handling of commit message generation
28
+
29
+ ### Fixed
30
+ - Various bug fixes and performance improvements
31
+
1
32
  ## [0.1.1] - 2024-12-13
2
33
 
3
34
  - Remove debug logging output from API requests for cleaner user experience
@@ -51,8 +51,7 @@ module GitAuto
51
51
  return if status[:has_staged_changes]
52
52
 
53
53
  puts "ℹ️ Status:".blue
54
- puts " Branch: #{status[:branch]}"
55
- puts " Staged files: #{status[:staged_files].join(", ")}"
54
+ puts " No changes staged for commit"
56
55
  puts "\n❌ No changes staged for commit. Use 'git add' to stage changes.".red
57
56
  exit 1
58
57
  end
@@ -131,7 +130,11 @@ module GitAuto
131
130
  end
132
131
 
133
132
  def display_message_and_validation(formatted_message, validation)
134
- puts "\n📝 Generated commit message:".blue
133
+ provider = @settings.get(:ai_provider)
134
+ model = @settings.get(:ai_model)
135
+ model_info = "(#{provider}/#{model})".light_black
136
+
137
+ puts "\n📝 Generated commit message #{model_info}:".blue
135
138
  puts formatted_message
136
139
 
137
140
  display_validation_errors(validation[:errors]) if validation[:errors].any?
@@ -151,23 +151,24 @@ module GitAuto
151
151
 
152
152
  def configure_commit_style
153
153
  style = @prompt.select("Choose commit message style:", {
154
+ "Minimal (type: description)" => "minimal",
154
155
  "Conventional (type(scope): description)" => "conventional",
155
156
  "Simple (description only)" => "simple"
156
157
  })
157
158
 
158
- @settings.set(:commit_style, style)
159
+ @settings.save(commit_style: style)
159
160
  puts "✓ Commit style updated to #{style}".green
160
161
  end
161
162
 
162
163
  def configure_preferences
163
164
  show_diff = @prompt.yes?("Show diff before committing?")
164
- @settings.set(:show_diff, show_diff)
165
+ @settings.save(show_diff: show_diff)
165
166
  puts "✓ Show diff preference updated".green
166
167
  end
167
168
 
168
169
  def configure_history_settings
169
170
  save_history = @prompt.yes?("Save commit history for analysis?")
170
- @settings.set(:save_history, save_history)
171
+ @settings.save(save_history: save_history)
171
172
  puts "✓ History settings updated".green
172
173
  end
173
174
  end
@@ -87,6 +87,7 @@ module GitAuto
87
87
  @prompt.select(
88
88
  "Select default commit message style:",
89
89
  [
90
+ { name: "Minimal (type: subject)", value: "minimal" },
90
91
  { name: "Conventional (type(scope): description)", value: "conventional" },
91
92
  { name: "Simple (verb + description)", value: "simple" },
92
93
  { name: "Detailed (summary + bullet points)", value: "detailed" }
@@ -67,7 +67,7 @@ module GitAuto
67
67
  private
68
68
 
69
69
  def ensure_config_dir
70
- FileUtils.mkdir_p(CONFIG_DIR) unless Dir.exist?(CONFIG_DIR)
70
+ FileUtils.mkdir_p(CONFIG_DIR)
71
71
  end
72
72
 
73
73
  def load_settings
@@ -83,13 +83,13 @@ module GitAuto
83
83
  raise Error, "Unsupported AI provider: #{options[:ai_provider]}"
84
84
  end
85
85
 
86
- if options[:ai_model]
87
- provider = options[:ai_provider] || @settings[:ai_provider]
88
- valid_models = SUPPORTED_PROVIDERS[provider][:models].values
89
- unless valid_models.include?(options[:ai_model])
90
- raise Error, "Unsupported AI model: #{options[:ai_model]}"
91
- end
92
- end
86
+ return unless options[:ai_model]
87
+
88
+ provider = options[:ai_provider] || @settings[:ai_provider]
89
+ valid_models = SUPPORTED_PROVIDERS[provider][:models].values
90
+ return if valid_models.include?(options[:ai_model])
91
+
92
+ raise Error, "Unsupported AI model: #{options[:ai_model]}"
93
93
  end
94
94
  end
95
95
  end
@@ -66,17 +66,27 @@ module GitAuto
66
66
  end
67
67
 
68
68
  def get_system_prompt(style, retry_attempt = 0)
69
- base_prompt = case style
70
- when "conventional"
71
- "You are an expert in writing conventional commit messages..."
72
- else
73
- "You are an expert in writing clear and concise git commit messages..."
74
- end
69
+ base_prompt = case style.to_s
70
+ when "minimal"
71
+ "You are an expert in writing minimal commit messages that follow the format: <type>: <description>\n" \
72
+ "Rules:\n" \
73
+ "1. ALWAYS start with a type from the list above\n" \
74
+ "2. NEVER include a scope\n" \
75
+ "3. Keep the message under 72 characters\n" \
76
+ "4. Use lowercase\n" \
77
+ "5. Use present tense\n" \
78
+ "6. Be descriptive but concise\n" \
79
+ "7. Do not include a period at the end"
80
+ when "conventional"
81
+ "You are an expert in writing conventional commit messages..."
82
+ else
83
+ "You are an expert in writing clear and concise git commit messages..."
84
+ end
75
85
 
76
86
  # Add variation for retries
77
- if retry_attempt > 0
87
+ if retry_attempt.positive?
78
88
  base_prompt += "\nPlease provide a different perspective or approach than previous attempts."
79
- base_prompt += "\nBe more #{%w[specific detailed creative concise].sample} in this attempt."
89
+ base_prompt += "\nBe more #{["specific", "detailed", "creative", "concise"].sample} in this attempt."
80
90
  end
81
91
 
82
92
  base_prompt
@@ -110,14 +120,30 @@ module GitAuto
110
120
  # If diff is too large, use the summarized version
111
121
  diff = @diff_summarizer.summarize(diff) if diff.length > MAX_DIFF_SIZE
112
122
 
113
- if style == "conventional" && scope.nil?
123
+ if style.to_s == "minimal"
124
+ message = case @settings.get(:ai_provider)
125
+ when "openai"
126
+ generate_openai_commit_message(diff, style)
127
+ when "claude"
128
+ generate_claude_commit_message(diff, style)
129
+ end
130
+
131
+ # Extract type and description from the message
132
+ if message =~ /^(\w+):\s*(.+)$/
133
+ type = ::Regexp.last_match(1)
134
+ description = ::Regexp.last_match(2)
135
+ return "#{type}: #{description}"
136
+ end
137
+
138
+ return message
139
+ elsif style.to_s == "conventional" && scope.nil?
114
140
  # Generate both scope and message in one call
115
141
  message = case @settings.get(:ai_provider)
116
- when "openai"
117
- generate_openai_commit_message(diff, style)
118
- when "claude"
119
- generate_claude_commit_message(diff, style)
120
- end
142
+ when "openai"
143
+ generate_openai_commit_message(diff, style)
144
+ when "claude"
145
+ generate_claude_commit_message(diff, style)
146
+ end
121
147
 
122
148
  # Extract type and scope from the message
123
149
  if message =~ /^(\w+)(?:\(([\w-]+)\))?:\s*(.+)$/
@@ -174,24 +200,42 @@ module GitAuto
174
200
 
175
201
  # Only use temperature variations for retries
176
202
  temperature = retry_attempt ? get_temperature(retry_attempt) : TEMPERATURE_VARIATIONS[0][:openai]
177
- commit_types = %w[feat fix docs style refactor test chore perf ci build revert].join('|')
178
-
179
- system_message = "You are a commit message generator that MUST follow the conventional commit format: <type>(<scope>): <description>\n" \
180
- "Valid types are: #{commit_types}\n" \
181
- "Rules:\n" \
182
- "1. ALWAYS start with a type from the list above\n" \
183
- "2. ALWAYS use the exact format <type>(<scope>): <description>\n" \
184
- "3. Keep the message under 72 characters\n" \
185
- "4. Use lowercase\n" \
186
- "5. Use present tense\n" \
187
- "6. Be descriptive but concise\n" \
188
- "7. Do not include a period at the end"
203
+ commit_types = ["feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "ci", "build",
204
+ "revert"].join("|")
205
+
206
+ system_message = case style.to_s
207
+ when "minimal"
208
+ "You are a commit message generator that MUST follow the minimal commit format: <type>: <description>\n" \
209
+ "Valid types are: #{commit_types}\n" \
210
+ "Rules:\n" \
211
+ "1. ALWAYS start with a type from the list above\n" \
212
+ "2. NEVER include a scope\n" \
213
+ "3. Keep the message under 72 characters\n" \
214
+ "4. Use lowercase\n" \
215
+ "5. Use present tense\n" \
216
+ "6. Be descriptive but concise\n" \
217
+ "7. Do not include a period at the end"
218
+ when "conventional"
219
+ "You are a commit message generator that MUST follow these rules EXACTLY:\n" \
220
+ "1. ONLY output a single line containing the commit message\n" \
221
+ "2. Use format: <type>(<scope>): <description>\n" \
222
+ "3. Valid types are: #{commit_types}\n" \
223
+ "4. Keep under 72 characters\n" \
224
+ "5. Use lowercase\n" \
225
+ "6. Use present tense\n" \
226
+ "7. Be descriptive but concise\n" \
227
+ "8. No period at the end\n" \
228
+ "9. NO explanations or additional text\n" \
229
+ "10. NO markdown formatting"
230
+ else
231
+ "You are an expert in writing clear and concise git commit messages..."
232
+ end
189
233
 
190
234
  user_message = if scope
191
- "Generate a conventional commit message with scope '#{scope}' for this diff:\n\n#{diff}"
192
- else
193
- "Generate a conventional commit message for this diff:\n\n#{diff}"
194
- end
235
+ "Generate a conventional commit message with scope '#{scope}' for this diff:\n\n#{diff}"
236
+ else
237
+ "Generate a #{style} commit message for this diff:\n\n#{diff}"
238
+ end
195
239
 
196
240
  payload = {
197
241
  model: @settings.get(:ai_model),
@@ -206,8 +250,8 @@ module GitAuto
206
250
  # log_api_request("openai", payload, temperature) if ENV["DEBUG"]
207
251
 
208
252
  response = HTTP.auth("Bearer #{api_key}")
209
- .headers(accept: "application/json")
210
- .post(OPENAI_API_URL, json: payload)
253
+ .headers(accept: "application/json")
254
+ .post(OPENAI_API_URL, json: payload)
211
255
 
212
256
  handle_response(response)
213
257
  end
@@ -218,33 +262,41 @@ module GitAuto
218
262
 
219
263
  # Only use temperature variations for retries
220
264
  temperature = retry_attempt ? get_temperature(retry_attempt) : TEMPERATURE_VARIATIONS[0][:claude]
221
- prompt = retry_attempt ? get_system_prompt(style, retry_attempt) : get_system_prompt(style)
265
+ commit_types = ["feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "ci", "build",
266
+ "revert"].join("|")
267
+
268
+ system_message = case style.to_s
269
+ when "minimal"
270
+ "You are a commit message generator that MUST follow the minimal commit format: <type>: <description>\n" \
271
+ "Valid types are: #{commit_types}\n" \
272
+ "Rules:\n" \
273
+ "1. ALWAYS start with a type from the list above\n" \
274
+ "2. NEVER include a scope\n" \
275
+ "3. Keep the message under 72 characters\n" \
276
+ "4. Use lowercase\n" \
277
+ "5. Use present tense\n" \
278
+ "6. Be descriptive but concise\n" \
279
+ "7. Do not include a period at the end"
280
+ when "conventional"
281
+ "You are a commit message generator that MUST follow these rules EXACTLY:\n" \
282
+ "1. ONLY output a single line containing the commit message\n" \
283
+ "2. Use format: <type>(<scope>): <description>\n" \
284
+ "3. Valid types are: #{commit_types}\n" \
285
+ "4. Keep under 72 characters\n" \
286
+ "5. Use lowercase\n" \
287
+ "6. Use present tense\n" \
288
+ "7. Be descriptive but concise\n" \
289
+ "8. No period at the end\n" \
290
+ "9. NO explanations or additional text\n" \
291
+ "10. NO markdown formatting"
292
+ else
293
+ "You are an expert in writing clear and concise git commit messages..."
294
+ end
222
295
 
223
- commit_types = %w[feat fix docs style refactor test chore perf ci build revert].join('|')
224
296
  user_message = if scope
225
- "Generate ONLY a conventional commit message for this diff. The message MUST start with one of these types: #{commit_types}\n\n" \
226
- "Format: <type>: <description>\n" \
227
- "Example: feat: add user authentication\n\n" \
228
- "Rules:\n" \
229
- "1. Keep the commit message under 72 characters\n" \
230
- "2. Use lowercase\n" \
231
- "3. Use present tense\n" \
232
- "4. Make it unique and different from previous suggestions\n" \
233
- "5. MUST start with one of the valid types followed by a colon\n\n" \
234
- "Here's the diff:\n#{diff}" +
235
- previous_suggestions_prompt
297
+ "Generate a conventional commit message with scope '#{scope}' for this diff:\n\n#{diff}"
236
298
  else
237
- "Generate ONLY a conventional commit message for this diff. The message MUST start with one of these types: #{commit_types}\n\n" \
238
- "Format: <type>: <description>\n" \
239
- "Example: feat: add user authentication\n\n" \
240
- "Rules:\n" \
241
- "1. Keep the commit message under 72 characters\n" \
242
- "2. Use lowercase\n" \
243
- "3. Use present tense\n" \
244
- "4. Make it unique and different from previous suggestions\n" \
245
- "5. MUST start with one of the valid types followed by a colon\n\n" \
246
- "Here's the diff:\n#{diff}" +
247
- previous_suggestions_prompt
299
+ "Generate a #{style} commit message for this diff:\n\n#{diff}"
248
300
  end
249
301
 
250
302
  payload = {
@@ -253,7 +305,7 @@ module GitAuto
253
305
  temperature: temperature,
254
306
  top_k: 50,
255
307
  top_p: 0.9,
256
- system: prompt,
308
+ system: system_message,
257
309
  messages: [
258
310
  {
259
311
  role: "user",
@@ -272,10 +324,10 @@ module GitAuto
272
324
  # log_api_response(response.body)
273
325
 
274
326
  response = HTTP.headers({
275
- "Content-Type" => "application/json",
276
- "x-api-key" => api_key,
277
- "anthropic-version" => "2023-06-01"
278
- }).post(CLAUDE_API_URL, json: payload)
327
+ "Content-Type" => "application/json",
328
+ "x-api-key" => api_key,
329
+ "anthropic-version" => "2023-06-01"
330
+ }).post(CLAUDE_API_URL, json: payload)
279
331
 
280
332
  message = handle_response(response)
281
333
  message = message.downcase.strip
@@ -292,6 +344,8 @@ module GitAuto
292
344
  "simple commit message"
293
345
  when :scope, "scope"
294
346
  "commit scope suggestion"
347
+ when :minimal, "minimal"
348
+ "minimal commit message"
295
349
  else
296
350
  "commit message"
297
351
  end
@@ -301,34 +355,38 @@ module GitAuto
301
355
  case response.code
302
356
  when 200
303
357
  json = JSON.parse(response.body.to_s)
304
- # puts "Debug - API Response: #{json.inspect}"
358
+ puts "\nDebug - API Response: #{json.inspect}"
359
+
305
360
  case @settings.get(:ai_provider)
306
361
  when "openai"
307
362
  message = json.dig("choices", 0, "message", "content")
308
363
  if message.nil? || message.empty?
309
- # puts "Debug - No content in response: #{json}"
364
+ puts "Debug - No content in response: #{json}"
310
365
  raise Error, "No message content in response"
311
366
  end
367
+
368
+ puts "Debug - OpenAI message: #{message}"
312
369
  message.split("\n").first.strip
370
+
313
371
  when "claude"
314
372
  content = json.dig("content", 0, "text")
315
- # puts "Debug - Claude content: #{content.inspect}"
373
+ puts "Debug - Claude content: #{content.inspect}"
316
374
 
317
375
  if content.nil? || content.empty?
318
- # puts "Debug - No content in response: #{json}"
376
+ puts "Debug - No content in response: #{json}"
319
377
  raise Error, "No message content in response"
320
378
  end
321
379
 
322
- lines = content.split("\n").map(&:strip).reject(&:empty?)
323
- # puts "Debug - Lines: #{lines.inspect}"
324
-
325
- message = lines.first
380
+ # Extract the first actual commit message from the response
381
+ commit_message = content.scan(/(?:feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(?:\([^)]+\))?:.*/)&.first
326
382
 
327
- if message.nil? || !message.match?(/^[a-z]+:/)
383
+ if commit_message.nil?
384
+ puts "Debug - No valid commit message pattern found in content"
328
385
  raise Error, "No valid commit message found in response"
329
386
  end
330
387
 
331
- message
388
+ puts "Debug - Extracted commit message: #{commit_message}"
389
+ commit_message.strip
332
390
  end
333
391
  when 401
334
392
  raise APIKeyError, "Invalid API key" unless ENV["RACK_ENV"] == "test"
@@ -348,18 +406,18 @@ module GitAuto
348
406
  end
349
407
 
350
408
  def infer_scope_from_diff(diff)
351
- files = diff.scan(/^diff --git.*?b\/(.+)$/).flatten
409
+ files = diff.scan(%r{^diff --git.*?b/(.+)$}).flatten
352
410
  return nil if files.empty?
353
411
 
354
412
  scopes = files.map do |file|
355
- parts = file.split('/')
413
+ parts = file.split("/")
356
414
  if parts.length > 1
357
415
  parts.first
358
416
  else
359
- basename = File.basename(file, '.*')
417
+ basename = File.basename(file, ".*")
360
418
 
361
419
  if basename =~ /^(.*?)\d*$/
362
- $1
420
+ ::Regexp.last_match(1)
363
421
  else
364
422
  basename
365
423
  end
@@ -367,19 +425,19 @@ module GitAuto
367
425
  end.compact
368
426
 
369
427
  # Filter out overly generic scopes
370
- scopes.reject! { |s| %w[rb js py ts css html md].include?(s) }
428
+ scopes.reject! { |s| ["rb", "js", "py", "ts", "css", "html", "md"].include?(s) }
371
429
  return nil if scopes.empty?
372
430
 
373
431
  # Return the most common scope
374
432
  scope = scopes.group_by(&:itself)
375
- .max_by { |_, group| group.length }
376
- &.first
433
+ .max_by { |_, group| group.length }
434
+ &.first
377
435
 
378
436
  # Convert to snake_case if needed
379
437
  scope&.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
380
- &.gsub(/([a-z\d])([A-Z])/, '\1_\2')
381
- &.tr('-', '_')
382
- &.downcase
438
+ &.gsub(/([a-z\d])([A-Z])/, '\1_\2')
439
+ &.tr("-", "_")
440
+ &.downcase
383
441
  end
384
442
  end
385
443
  end
@@ -26,7 +26,7 @@ module GitAuto
26
26
 
27
27
  def get_commit_history(limit = nil)
28
28
  validate_git_repository!
29
- format = '%H%n%s%n%an%n%aI'
29
+ format = "%H%n%s%n%an%n%aI"
30
30
  command = ["log", "--pretty=format:#{format}", "--no-merges"]
31
31
  command << "-#{limit}" if limit
32
32
 
@@ -55,20 +55,23 @@ module GitAuto
55
55
  private
56
56
 
57
57
  def validate_git_repository!
58
- unless File.directory?(".git")
59
- raise Error, "Not a git repository (or any of the parent directories)"
60
- end
58
+ return if File.directory?(".git")
59
+
60
+ raise Error, "Not a git repository (or any of the parent directories)"
61
61
  end
62
62
 
63
63
  def validate_staged_changes!
64
- unless has_staged_changes?
65
- raise Error, "No changes staged for commit"
66
- end
64
+ return if has_staged_changes?
65
+
66
+ raise Error, "No changes staged for commit"
67
67
  end
68
68
 
69
69
  def has_staged_changes?
70
- !execute_git_command("diff", "--cached", "--quiet")
71
- $CHILD_STATUS.exitstatus == 1
70
+ # git diff --cached --quiet returns:
71
+ # - exit status 0 (success) if there are no changes
72
+ # - exit status 1 (failure) if there are changes
73
+ system("git diff --cached --quiet")
74
+ !$CHILD_STATUS.success?
72
75
  end
73
76
 
74
77
  def is_clean?
@@ -85,9 +88,7 @@ module GitAuto
85
88
  def execute_git_command(*args)
86
89
  output = IO.popen(["git", *args], err: [:child, :out], &:read)
87
90
 
88
- unless $CHILD_STATUS.success?
89
- raise Error, "Git command failed: git #{args.join(' ')}\n#{output}"
90
- end
91
+ raise Error, "Git command failed: git #{args.join(" ")}\n#{output}" unless $CHILD_STATUS.success?
91
92
 
92
93
  output
93
94
  end
@@ -20,6 +20,12 @@ module GitAuto
20
20
  "revert" => "Reverts a previous commit"
21
21
  }.freeze
22
22
 
23
+ MINIMAL_COMMIT_PATTERN = /
24
+ ^(?<type>#{TYPES.keys.join("|")}) # Commit type
25
+ :\s # Colon and space separator
26
+ (?<description>.+) # Commit description
27
+ /x
28
+
23
29
  CONVENTIONAL_COMMIT_PATTERN = %r{
24
30
  ^(?<type>#{TYPES.keys.join("|")}) # Commit type
25
31
  (\((?<scope>[a-z0-9/_-]+)\))? # Optional scope in parentheses
@@ -71,12 +77,12 @@ module GitAuto
71
77
 
72
78
  errors << "Header exceeds #{HEADER_MAX_LENGTH} characters" if header.length > HEADER_MAX_LENGTH
73
79
 
74
- # Validate header format for conventional commits
75
- valid_types = TYPES.keys.join('|')
76
- pattern = %r{^(?:#{valid_types})\([a-z0-9/_-]+\)?: .+$}
80
+ # Validate header format for conventional and minimal commits
81
+ minimal_pattern = MINIMAL_COMMIT_PATTERN
82
+ conventional_pattern = CONVENTIONAL_COMMIT_PATTERN
77
83
 
78
- unless pattern.match?(header)
79
- errors << "Header must follow conventional commit format: <type>(<scope>): <description>"
84
+ unless minimal_pattern.match?(header) || conventional_pattern.match?(header)
85
+ errors << "Header must follow either minimal format: <type>: <description> or conventional format: <type>(<scope>): <description>"
80
86
  end
81
87
 
82
88
  # Suggest using lowercase for consistency
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GitAuto
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_auto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guillermo Diaz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-12-15 00:00:00.000000000 Z
11
+ date: 2024-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor