class Leg::Diff

Constants

GIT_DIFF_OPTIONS

Attributes

files[R]
html[R]

Public Class Methods

new(step_a, step_b) click to toggle source
# File lib/leg/diff.rb, line 6
def initialize(step_a, step_b)
  git_diff = `git diff #{GIT_DIFF_OPTIONS} #{step_a} #{step_b}`
  parse_git_diff(git_diff)
  @files.values.each(&:omit_adjacent_removals!)

  @html = {}
  @files.each do |filename, file|
    @html[filename] = file.to_html
  end
end

Private Instance Methods

parse_git_diff(git_diff) click to toggle source
# File lib/leg/diff.rb, line 150
def parse_git_diff(git_diff)
  diff_file = nil
  section_stack = nil
  line_idx = nil
  in_diff = false
  @files = {}

  git_diff.lines.each do |line|
    if !in_diff && line =~ /^diff --git (\S+) (\S+)$/
      diff_file = DiffFile.new(File.basename($2))
      @files[diff_file.filename] = diff_file
      section_stack = [diff_file]
      line_idx = -1
    elsif !in_diff && line.start_with?('new file')
      diff_file.new_file!
    elsif line.start_with? '@@'
      in_diff = true
    elsif in_diff && [' ', '+', '-'].include?(line[0])
      type = {' ' => :nochange, '+' => :add, '-' => :remove }[line[0]]
      diff_file.append_line(line[1..-1])
      line_idx += 1

      section_stack.each(&:dirty!) if type != :nochange

      if line[1..-1] =~ /^\/\*\*\* (.+) \*\*\*\/$/
        section = DiffSection.new(:comment, line_idx)
        diff_file << section
        section_stack = [diff_file, section]
      elsif line[1] =~ /\S/ && line.chomp[-1] == "{"
        section = DiffSection.new(:braces, line_idx)
        section_stack.pop if section_stack.last.type == :braces
        section_stack.last << section
        section_stack.push(section)
      end

      diff_line = DiffLine.new(type, line_idx)
      diff_line.empty! if line[1..-1].strip.empty?
      section_stack.last << diff_line

      if line[1..-1] =~ /^}( \w+)?;?$/ && section_stack.last.type == :braces
        section = section_stack.pop
        section.lines << line_idx
      end

      section_stack.each(&:dirty!) if type != :nochange
    else
      in_diff = false
    end
  end
end