class FileDiff

Constants

BINARY_REGEX
DELETE_OP_REGEX
DELETE_REGEX
DELETION_REGEX
DIFF_REGEX
DIFF_STAT_REGEX
FILE_INDEX_REGEX
INSERTION_REGEX

Attributes

a_file_id[RW]
a_file_name[RW]
b_file_id[RW]
b_file_name[RW]
changes_total[RW]
deletions_total[RW]
diffs[RW]
insertions_total[RW]
operation[RW]

Public Class Methods

from_git(file_diff_lines) click to toggle source
# File lib/file_diff.rb, line 31
def from_git(file_diff_lines)
  FileDiff.new(parse_file_diff(file_diff_lines))
end
new(attrs={}) click to toggle source
# File lib/file_diff.rb, line 24
def initialize(attrs={})
  attrs.each do |key, val|
    instance_variable_set("@#{key}".to_sym, val)
  end
end
parse_file_diff(file_diff_lines) click to toggle source

TODO: Handle different file modes like new, move, and delete.

# File lib/file_diff.rb, line 36
def parse_file_diff(file_diff_lines)
  file_names = file_diff_lines
    .first
    .sub("diff --git a/", "")
    .split(" b/")

  a_file_name = file_names.first.strip()
  b_file_name = file_names.last.strip()

  file_index = file_diff_lines
    .each_index
    .detect { |i| file_diff_lines[i].match(FILE_INDEX_REGEX) }

  if file_index.nil?
    a_file_id = nil
    b_file_id = nil
  else
    a_file_id, b_file_id = file_diff_lines[file_index]
      .sub("index ", "")
      .split(" ")
      .first
      .split("..")
  end

  if file_diff_lines.last.match(BINARY_REGEX)
    operation = :binary
  elsif (a_file_name != b_file_name)
    operation = :move
  elsif (file_diff_lines[1].match(DELETE_OP_REGEX))
    operation = :delete
  else
    operation = :change
  end

  diff_index = file_diff_lines
    .each_index
    .detect { |i| file_diff_lines[i].match(DIFF_REGEX) }

  if diff_index.nil?
    diffs = []
  else
    diffs = file_diff_lines[diff_index..-1]
      .reduce([], &fold_reducer(DIFF_REGEX))
      .flat_map { |diff_lines| Diff.from_git(diff_lines) }
  end

  insertions = diffs.map { |diff| diff.insert_count }.reduce(0, :+)
  deletions = diffs.map { |diff| diff.delete_count }.reduce(0, :+)

  {
    operation: operation,
    a_file_name: a_file_name,
    b_file_name: b_file_name,
    a_file_id: a_file_id,
    b_file_id: b_file_id,
    diffs: diffs,
    insertions_total: insertions,
    deletions_total: deletions,
    changes_total: insertions + deletions
  }
end