openSUSE/open-build-service

View on GitHub
src/api/app/services/diff_parser.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
92%
class DiffParser
  attr_reader :lines

  def initialize(content:)
    @content = content || ''
    @original_index = 0
    @changed_index = 0
    @last_original_index = 0
    @last_changed_index = 0
    @lines = []
  end

  def call
    @content.each_line.with_index do |line, line_index|
      @state = parse_line(line)

      @lines << create_line(line, line_index)

      @last_original_index = @original_index
      @last_changed_index = @changed_index
    end

    self
  end

  def max_digits
    [@last_original_index, @last_changed_index].max.digits.length
  end

  private

  def parse_line(line)
    case line
    when /^ /
      @original_index += 1
      @changed_index += 1
      'unchanged'
    when /^@@ -(?<original_index>\d+).+\+(?<changed_index>\d+),/
      @original_index = Regexp.last_match[:original_index].to_i - 1
      @changed_index = Regexp.last_match[:changed_index].to_i - 1
      'range'
    when /^-/
      @original_index += 1
      'removed'
    when /^[+]/
      @changed_index += 1
      'added'
    else
      'comment'
    end
  end

  def create_line(line, line_index)
    DiffParser::Line.new(content: line, state: @state, index: line_index + 1, original_index: final_original_index, changed_index: final_changed_index)
  end

  def final_original_index
    return if %w[comment range].include?(@state)

    @original_index unless @last_original_index == @original_index
  end

  def final_changed_index
    return if %w[comment range].include?(@state)

    @changed_index unless @last_changed_index == @changed_index
  end
end