Skip to content

Commit 3d94e7d

Browse files
committed
MultiFileDiffReader returns trailing content
Along with EOF. This is useful for handling mixed diff and non-diff output. Note that "stray" content between diff files was already included in the extended headers for the next diff. To avoid breaking the existing API, this trailing content is only available in a new method.
1 parent 82e3467 commit 3d94e7d

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

diff/diff_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package diff
22

33
import (
44
"bytes"
5+
"io"
56
"io/ioutil"
67
"path/filepath"
78
"reflect"
@@ -818,6 +819,40 @@ func TestParseMultiFileDiffAndPrintMultiFileDiff(t *testing.T) {
818819
}
819820
}
820821

822+
func TestParseMultiFileDiffAndPrintMultiFileDiffIncludingTrailingContent(t *testing.T) {
823+
diffData, err := ioutil.ReadFile(filepath.Join("testdata", "sample_multi_file_minuses_pluses_trailing_content.diff"))
824+
if err != nil {
825+
t.Fatal(err)
826+
}
827+
828+
diffReader := NewMultiFileDiffReader(bytes.NewReader(diffData))
829+
var diffs []*FileDiff
830+
trailingContent := ""
831+
for {
832+
var fd *FileDiff
833+
var err error
834+
fd, trailingContent, err = diffReader.ReadFileWithTrailingContent()
835+
if fd != nil {
836+
diffs = append(diffs, fd)
837+
}
838+
if err == io.EOF {
839+
break
840+
}
841+
if err != nil {
842+
t.Error(err)
843+
}
844+
}
845+
846+
if len(diffs) != 2 {
847+
t.Errorf("expected 2 diffs, got %d", len(diffs))
848+
}
849+
850+
expectedTrailingContent := "some trailing content"
851+
if trailingContent != expectedTrailingContent {
852+
t.Errorf("expected trailing content %s, got %s", expectedTrailingContent, trailingContent)
853+
}
854+
}
855+
821856
func TestNoNewlineAtEnd(t *testing.T) {
822857
diffs := map[string]struct {
823858
diff string

diff/parse.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ type MultiFileDiffReader struct {
4646
// all hunks) from r. If there are no more files in the diff, it
4747
// returns error io.EOF.
4848
func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
49+
fd, _, err := r.ReadFileWithTrailingContent()
50+
return fd, err
51+
}
52+
53+
// ReadFileWithTrailingContent reads the next file unified diff (including
54+
// headers and all hunks) from r, also returning any trailing content. If there
55+
// are no more files in the diff, it returns error io.EOF.
56+
func (r *MultiFileDiffReader) ReadFileWithTrailingContent() (*FileDiff, string, error) {
4957
fr := &FileDiffReader{
5058
line: r.line,
5159
offset: r.offset,
@@ -59,23 +67,27 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
5967
switch e := err.(type) {
6068
case *ParseError:
6169
if e.Err == ErrNoFileHeader || e.Err == ErrExtendedHeadersEOF {
62-
return nil, io.EOF
70+
trailing := ""
71+
if fd != nil {
72+
trailing = strings.Join(fd.Extended, "\n")
73+
}
74+
return nil, trailing, io.EOF
6375
}
64-
return nil, err
76+
return nil, "", err
6577

6678
case OverflowError:
6779
r.nextFileFirstLine = []byte(e)
68-
return fd, nil
80+
return fd, "", nil
6981

7082
default:
71-
return nil, err
83+
return nil, "", err
7284
}
7385
}
7486

7587
// FileDiff is added/deleted file
7688
// No further collection of hunks needed
7789
if fd.NewName == "" {
78-
return fd, nil
90+
return fd, "", nil
7991
}
8092

8193
// Before reading hunks, check to see if there are any. If there
@@ -87,7 +99,7 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
8799
hr := fr.HunksReader()
88100
line, err := r.reader.readLine()
89101
if err != nil && err != io.EOF {
90-
return fd, err
102+
return fd, "", err
91103
}
92104
line = bytes.TrimSuffix(line, []byte{'\n'})
93105
if bytes.HasPrefix(line, hunkPrefix) {
@@ -101,18 +113,18 @@ func (r *MultiFileDiffReader) ReadFile() (*FileDiff, error) {
101113
// This just means we finished reading the hunks for the
102114
// current file. See the ErrBadHunkLine doc for more info.
103115
r.nextFileFirstLine = e.Line
104-
return fd, nil
116+
return fd, "", nil
105117
}
106118
}
107-
return nil, err
119+
return nil, "", err
108120
}
109121
} else {
110122
// There weren't any hunks, so that line we peeked ahead at
111123
// actually belongs to the next file. Put it back.
112124
r.nextFileFirstLine = line
113125
}
114126

115-
return fd, nil
127+
return fd, "", nil
116128
}
117129

118130
// ReadAllFiles reads all file unified diffs (including headers and all
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
diff --git a/comment-last-line.sql b/comment-last-line.sql
2+
index 04a1655..97bd115 100644
3+
--- a/comment-last-line.sql
4+
+++ b/comment-last-line.sql
5+
@@ -1,4 +1,4 @@
6+
select 1;
7+
+++ invalid SQL comment
8+
select 2;
9+
select 3;
10+
--- end of three queries
11+
diff --git a/query.sql b/query.sql
12+
index 9537d7b..234ef35 100644
13+
--- a/query.sql
14+
+++ b/query.sql
15+
@@ -1,5 +1,4 @@
16+
select 1;
17+
--- this is my query
18+
select 2;
19+
select 3;
20+
--- this is the last line
21+
+++ invalid sql comment
22+
some trailing content

0 commit comments

Comments
 (0)