shiba 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/shiba/diff.rb DELETED
@@ -1,129 +0,0 @@
1
- module Shiba
2
- class Diff
3
- # +++ b/config/environments/test.rb
4
- FILE_PATTERN = /\A\+\+\+ b\/(.*?)\Z/
5
-
6
- # @@ -177,0 +178 @@ ...
7
- # @@ -177,0 +178,5 @@ ...
8
- # @@ -21 +24 @@ ...
9
- LINE_PATTERN = /\A@@ \-\d+,?\d+? \+(\d+),?(\d+)? @@/
10
-
11
- # via https://developer.github.com/v3/pulls/comments/#create-a-comment
12
- # The position value equals the number of lines down from the first "@@" hunk header
13
- # in the file you want to add a comment.
14
-
15
- attr_reader :status
16
-
17
- def initialize(file)
18
- # Fixme. seems like enumerables should work in general.
19
- if !file.respond_to?(:pos)
20
- raise StandardError.new("Diff file does not appear to be a seekable IO object.")
21
- end
22
- @diff = file
23
- @status = :new
24
- end
25
-
26
- # Returns the file and line numbers that contain inserts. Deletions are ignored.
27
- # For simplicity, the default output of git diff is not supported.
28
- # The expected format is from 'git diff unified=0'
29
- #
30
- # Example:
31
- # diff = `git diff --unified=0`
32
- # Diff.new(StringIO.new(diff))
33
- # => [ [ "hello.rb", 1..3 ]
34
- # => [ "hello.rb", 7..7 ]
35
- # => [ "test.rb", 23..23 ]
36
- # => ]
37
- def updated_lines
38
- io = @diff.each_line
39
- path = nil
40
-
41
- found = []
42
-
43
- while true
44
- line = io.next
45
- if line =~ FILE_PATTERN
46
- path = $1
47
- end
48
-
49
- if hunk_header?(line)
50
- line_numbers = line_numbers_for_destination(line)
51
- found << [ path, line_numbers ]
52
- end
53
- end
54
- rescue StopIteration
55
- return found
56
- end
57
-
58
- # Returns the position in the diff, after the relevant file header,
59
- # that contains the specified file/lineno modification.
60
- # Only supports finding the position in the destination / newest version of the file.
61
- #
62
- # Example:
63
- # diff = Diff.new(`git diff`)
64
- # diff.find_position("test.rb", 3)
65
- # => 5
66
- def find_position(path, line_number)
67
- io = @diff.each_line # maybe redundant?
68
-
69
- file_header = "+++ b/#{path}\n" # fixme
70
- if !io.find_index(file_header)
71
- @status = :file_not_found
72
- return
73
- end
74
-
75
- line = io.peek
76
- if !hunk_header?(line)
77
- raise StandardError.new("Expected hunk header to be after file header, but got '#{line}'")
78
- end
79
-
80
- pos = 0
81
-
82
- while true
83
- line = io.next
84
- pos += 1
85
-
86
- if file_header?(line)
87
- @status = :line_not_found
88
- return
89
- end
90
-
91
- if !hunk_header?(line)
92
- next
93
- end
94
-
95
- line_numbers = line_numbers_for_destination(line)
96
-
97
- if destination_position = line_numbers.find_index(line_number)
98
- @status = :found_position
99
- return pos + find_hunk_index(io, destination_position)
100
- end
101
- end
102
- rescue StopIteration
103
- @status = :line_not_found
104
- end
105
-
106
- protected
107
-
108
- def find_hunk_index(hunk, pos)
109
- line, idx = hunk.with_index.select { |l,idx| !l.start_with?('-') }.take(pos+1).last
110
- idx
111
- end
112
-
113
- def file_header?(line)
114
- line =~ FILE_PATTERN
115
- end
116
-
117
- def hunk_header?(line)
118
- LINE_PATTERN =~ line
119
- end
120
-
121
- def line_numbers_for_destination(diff_line)
122
- diff_line =~ LINE_PATTERN
123
- line = $1.to_i
124
- line_count = ($2 && $2.to_i) || 0
125
- line..line+line_count
126
- end
127
-
128
- end
129
- end