Class: Ace::GitCommit::Molecules::DiffAnalyzer

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git_commit/molecules/diff_analyzer.rb

Overview

DiffAnalyzer analyzes git diffs and extracts information for commit message generation

Instance Method Summary collapse

Constructor Details

#initialize(git_executor) ⇒ DiffAnalyzer



8
9
10
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 8

def initialize(git_executor)
  @git = git_executor
end

Instance Method Details

#analyze_diff(diff) ⇒ Hash

Analyze diff to extract summary information



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 60

def analyze_diff(diff)
  files = []
  insertions = 0
  deletions = 0

  diff.lines.each do |line|
    if line.start_with?("+++")
      # Extract file path from +++ line
      file = line.sub(/^\+\+\+ b\//, "").strip
      files << file unless file == "/dev/null"
    elsif line.start_with?("+") && !line.start_with?("+++")
      insertions += 1
    elsif line.start_with?("-") && !line.start_with?("---")
      deletions += 1
    end
  end

  {
    files_changed: files.uniq,
    insertions: insertions,
    deletions: deletions
  }
end

#changed_files(staged_only: false) ⇒ Array<String>

Get list of changed files



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 45

def changed_files(staged_only: false)
  if staged_only
    @git.execute("diff", "--cached", "--name-only").strip.split("\n")
  else
    # Get all changed files (staged, unstaged, and untracked)
    staged = @git.execute("diff", "--cached", "--name-only").strip.split("\n")
    unstaged = @git.execute("diff", "--name-only").strip.split("\n")
    untracked = @git.execute("ls-files", "--others", "--exclude-standard").strip.split("\n")
    (staged + unstaged + untracked).uniq
  end
end

#detect_scope(files) ⇒ String?

Detect the scope from changed files



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 87

def detect_scope(files)
  return nil if files.empty?

  # Check if all files are in a specific directory/component
  if files.all? { |f| f.start_with?("ace-") }
    # All files in a specific ace gem
    gem = files.first.split("/").first
    return gem
  end

  # Check common patterns
  if files.all? { |f| f.match?(%r{(^|/)test/}) || f.match?(%r{(^|/)spec/}) }
    return "test"
  elsif files.all? { |f| f.end_with?(".md") }
    return "docs"
  elsif files.all? { |f| f.include?("config") }
    return "config"
  end

  nil
end

#get_all_diff(files = nil) ⇒ String

Get the diff for all changes (staged and unstaged)



24
25
26
27
28
29
30
31
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 24

def get_all_diff(files = nil)
  args = ["diff", "HEAD"]
  args += ["--"] + files if files && !files.empty?
  @git.execute(*args)
rescue GitError
  # If HEAD doesn't exist (new repo), get all changes
  get_unstaged_diff(files)
end

#get_staged_diff(files = nil) ⇒ String

Get the diff for staged changes



15
16
17
18
19
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 15

def get_staged_diff(files = nil)
  args = ["diff", "--cached"]
  args += ["--"] + files if files && !files.empty?
  @git.execute(*args)
end

#get_unstaged_diff(files = nil) ⇒ String

Get the diff for unstaged changes



36
37
38
39
40
# File 'lib/ace/git_commit/molecules/diff_analyzer.rb', line 36

def get_unstaged_diff(files = nil)
  args = ["diff"]
  args += ["--"] + files if files && !files.empty?
  @git.execute(*args)
end