Class: Svnx::Diff::Parser

Inherits:
Object
  • Object
show all
Includes:
Logue::Loggable
Defined in:
lib/svnx/diff/parser.rb

Instance Method Summary collapse

Instance Method Details

#parse_all_output(lines) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/svnx/diff/parser.rb', line 95

def parse_all_output lines
  Array.new.tap do |diffs|
    until lines.empty?
      if filediff = parse_file_diff(lines)
        diffs << filediff
      else
        break
      end
    end
  end
end

#parse_file_diff(lines) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/svnx/diff/parser.rb', line 79

def parse_file_diff lines
  if header = parse_header_section(lines)
    SvnFileDiff.new(header).tap do |diff|
      if header.from && header.to
        while !lines.empty?
          if hunk = parse_hunk(lines)
            diff.hunks << hunk
          else
            break
          end
        end
      end
    end
  end
end

#parse_header_file(lines) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/svnx/diff/parser.rb', line 11

def parse_header_file lines
  re = Regexp.new '^[\-\+]{3} (.*)\t\((?:nonexistent|working copy|revision (\d+))\)'
  if md = re.match(lines.first)
    lines.shift
    File.new filename: md[1], revision: md[2] && md[2].to_i
  end
end

#parse_header_section(lines) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/svnx/diff/parser.rb', line 19

def parse_header_section lines
  re = Regexp.new '^Index: (.*)'
  if md = re.match(lines.first)
    filename = md[1]      
    lines.shift
    
    # discard the ==== line:
    lines.shift

    from = parse_header_file lines
    to = parse_header_file lines
    
    Header.new filename: filename, from: from, to: to
  end
end

#parse_hunk(lines) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/svnx/diff/parser.rb', line 48

def parse_hunk lines
  if ranges = parse_ranges(lines)
    Hunk.new(ranges, Array.new).tap do |hunk|
      char_to_type = { ' ' => :context, '+' => :added,  '-' => :deleted }
      
      while !lines.empty?
        if lines.first == "\\ No newline at end of file"
          hunk.lines << [ :context, :no_newline ]
          lines.shift
        elsif type = char_to_type[lines.first[0]]
          hunk.lines << [ type, lines.shift[1 .. -1] ]
        else
          break
        end
      end
    end
  end
end

#parse_hunks(lines) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/svnx/diff/parser.rb', line 67

def parse_hunks lines
  Array.new.tap do |hunks|
    while !lines.empty?
      if hunk = parse_hunk(lines)
        hunks << hunk
      else
        break
      end
    end
  end
end

#parse_ranges(lines) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/svnx/diff/parser.rb', line 35

def parse_ranges lines
  range_re = Regexp.new '@@ \-(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@'
  if md = range_re.match(lines.first)
    lines.shift
    
    from, to = [ 1, 3 ].collect do |idx|
      HunkRange.new md[idx].to_i, (md[idx + 1] || 1).to_i
    end
    
    HunkRanges.new from, to
  end
end