module Gitlab class DiffParser include Enumerable attr_reader :lines, :new_path def initialize(lines, new_path = '') @lines = lines @new_path = new_path end def each line_old = 1 line_new = 1 type = nil lines_arr = ::Gitlab::InlineDiff.processing lines lines_arr.each do |line| raw_line = line.dup next if filename?(line) full_line = html_escape(line.gsub(/\n/, '')) full_line = ::Gitlab::InlineDiff.replace_markers full_line if line.match(/^@@ -/) type = "match" line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0 line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0 next if line_old == 1 && line_new == 1 #top of file yield(full_line, type, nil, line_new, line_old) next else type = identification_type(line) line_code = generate_line_code(new_path, line_new, line_old) yield(full_line, type, line_code, line_new, line_old, raw_line) end if line[0] == "+" line_new += 1 elsif line[0] == "-" line_old += 1 else line_new += 1 line_old += 1 end end end def empty? @lines.empty? end private def filename?(line) line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b', '--- /tmp/diffy', '+++ /tmp/diffy') end def identification_type(line) if line[0] == "+" "new" elsif line[0] == "-" "old" else nil end end def generate_line_code(path, line_new, line_old) "#{Digest::SHA1.hexdigest(path)}_#{line_old}_#{line_new}" end def html_escape str replacements = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } str.gsub(/[&"'><]/, replacements) end end end