Class: Committer::CommitGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/committer/commit_generator.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(diff, commit_context = nil) ⇒ CommitGenerator

Returns a new instance of CommitGenerator.



14
15
16
17
# File 'lib/committer/commit_generator.rb', line 14

def initialize(diff, commit_context = nil)
  @diff = diff
  @commit_context = commit_context
end

Instance Attribute Details

#commit_contextObject (readonly)

Returns the value of attribute commit_context.



12
13
14
# File 'lib/committer/commit_generator.rb', line 12

def commit_context
  @commit_context
end

#diffObject (readonly)

Returns the value of attribute diff.



12
13
14
# File 'lib/committer/commit_generator.rb', line 12

def diff
  @diff
end

Class Method Details

.check_git_statusObject



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/committer/commit_generator.rb', line 42

def self.check_git_status
  stdout, stderr, status = Open3.capture3('git diff --staged')

  unless status.success?
    puts 'Error executing git diff --staged:'
    puts stderr
    exit 1
  end

  stdout
end

Instance Method Details

#build_commit_promptObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/committer/commit_generator.rb', line 19

def build_commit_prompt
  scopes = Committer::Config.load
  scope_section = scopes.empty? ? '' : "\nScopes:\n#{scopes.map { |s| "- #{s}" }.join("\n")}"
  scope_instruction = if scopes.empty?
                        '- DO NOT include a scope in your commit message'
                      else
                        '- Choose an appropriate scope from the list above if relevant to the change'
                      end
  format(template,
         diff: @diff,
         scopes_section: scope_section,
         scope_instruction: scope_instruction,
         commit_context: @commit_context)
end

#parse_response(response) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/committer/commit_generator.rb', line 54

def parse_response(response)
  text = response.dig('content', 0, 'text')

  # If user didn't provide context, response should only be a summary line
  if @commit_context.nil? || @commit_context.empty?
    { summary: text.strip, body: nil }
  else
    # Split the response into summary and body
    message_parts = text.split("\n\n", 2)
    summary = message_parts[0].strip
    body = message_parts[1]&.strip

    # Wrap body text at 80 characters
    body = body.gsub(/(.{1,80})(\s+|$)/, "\\1\n").strip if body

    { summary: summary, body: body }
  end
end

#prepare_commit_messageObject



73
74
75
76
77
78
79
# File 'lib/committer/commit_generator.rb', line 73

def prepare_commit_message
  client = Clients::ClaudeClient.new

  prompt = build_commit_prompt
  response = client.post(prompt)
  parse_response(response)
end

#templateObject



34
35
36
37
38
39
40
# File 'lib/committer/commit_generator.rb', line 34

def template
  if @commit_context.nil? || @commit_context.empty?
    Committer::PromptTemplates::SUMMARY_ONLY
  else
    Committer::PromptTemplates::SUMMARY_AND_BODY
  end
end