Skip to content

Commit 7ef5f68

Browse files
authored
Support Apple Diff timestamps (#65)
Apple's diff (at least the one shipping with macOS Venture) does not include the fractional seconds or Timezone in it's output. This adds support for that so diffutils does not need to be installed. I first encountered this problem using golangci-lint on macOS after upgrading to macOS Ventura.
1 parent 9d1f353 commit 7ef5f68

5 files changed

+81
-6
lines changed

diff/diff.go

+4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ const onlyInMessage = "Only in %s: %s\n"
120120
// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html.
121121
const diffTimeParseLayout = "2006-01-02 15:04:05 -0700"
122122

123+
// Apple's diff is based on freebsd diff, which uses a timestamp format that does
124+
// not include the timezone offset.
125+
const diffTimeParseWithoutTZLayout = "2006-01-02 15:04:05"
126+
123127
// diffTimeFormatLayout is the layout used to format (i.e., print) the time in unified diff file
124128
// header timestamps.
125129
// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html.

diff/diff_test.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,14 @@ func TestParseFileDiffAndPrintFileDiff(t *testing.T) {
850850

851851
func TestParseMultiFileDiffAndPrintMultiFileDiff(t *testing.T) {
852852
tests := []struct {
853-
filename string
854-
wantParseErr error
855-
wantFileDiffs int // How many instances of diff.FileDiff are expected.
853+
filename string
854+
wantParseErr error
855+
wantFileDiffs int // How many instances of diff.FileDiff are expected.
856+
wantOutFileName string // If non-empty, the name of the file containing the expected output.
856857
}{
857858
{filename: "sample_multi_file.diff", wantFileDiffs: 2},
858859
{filename: "sample_multi_file_single.diff", wantFileDiffs: 1},
860+
{filename: "sample_multi_file_single_apple_in.diff", wantFileDiffs: 1, wantOutFileName: "sample_multi_file_single_apple_out.diff"},
859861
{filename: "sample_multi_file_new.diff", wantFileDiffs: 3},
860862
{filename: "sample_multi_file_deleted.diff", wantFileDiffs: 3},
861863
{filename: "sample_multi_file_rename.diff", wantFileDiffs: 3},
@@ -892,6 +894,12 @@ func TestParseMultiFileDiffAndPrintMultiFileDiff(t *testing.T) {
892894
if err != nil {
893895
t.Errorf("%s: PrintMultiFileDiff: %s", test.filename, err)
894896
}
897+
if test.wantOutFileName != "" {
898+
diffData, err = ioutil.ReadFile(filepath.Join("testdata", test.wantOutFileName))
899+
if err != nil {
900+
t.Fatal(err)
901+
}
902+
}
895903
if !bytes.Equal(printed, diffData) {
896904
t.Errorf("%s: printed multi-file diff != original multi-file diff\n\n# PrintMultiFileDiff output - Original:\n%s", test.filename, cmp.Diff(diffData, printed))
897905
}

diff/parse.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ func (r *FileDiffReader) ReadFileHeaders() (origName, newName string, origTimest
254254
"", nil, nil, nil
255255
}
256256
}
257-
258257
origName, origTimestamp, err = r.readOneFileHeader([]byte("--- "))
259258
if err != nil {
260259
return "", "", nil, nil, err
@@ -307,10 +306,16 @@ func (r *FileDiffReader) readOneFileHeader(prefix []byte) (filename string, time
307306
parts := strings.SplitN(trimmedLine, "\t", 2)
308307
filename = parts[0]
309308
if len(parts) == 2 {
309+
var ts time.Time
310310
// Timestamp is optional, but this header has it.
311-
ts, err := time.Parse(diffTimeParseLayout, parts[1])
311+
ts, err = time.Parse(diffTimeParseLayout, parts[1])
312312
if err != nil {
313-
return "", nil, err
313+
var err1 error
314+
ts, err1 = time.Parse(diffTimeParseWithoutTZLayout, parts[1])
315+
if err1 != nil {
316+
return "", nil, err
317+
}
318+
err = nil
314319
}
315320
timestamp = &ts
316321
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
diff -u a/oldname1 b/newname1
2+
--- oldname1 2009-10-11 15:12:20
3+
+++ newname1 2009-10-11 15:12:30
4+
@@ -1,3 +1,9 @@
5+
+This is an important
6+
+notice! It should
7+
+therefore be located at
8+
+the beginning of this
9+
+document!
10+
+
11+
This part of the
12+
document has stayed the
13+
same from version to
14+
@@ -5,16 +11,10 @@
15+
be shown if it doesn't
16+
change. Otherwise, that
17+
would not be helping to
18+
-compress the size of the
19+
-changes.
20+
-
21+
-This paragraph contains
22+
-text that is outdated.
23+
-It will be deleted in the
24+
-near future.
25+
+compress anything.
26+
27+
It is important to spell
28+
-check this dokument. On
29+
+check this document. On
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
diff -u a/oldname1 b/newname1
2+
--- oldname1 2009-10-11 15:12:20.000000000 +0000
3+
+++ newname1 2009-10-11 15:12:30.000000000 +0000
4+
@@ -1,3 +1,9 @@
5+
+This is an important
6+
+notice! It should
7+
+therefore be located at
8+
+the beginning of this
9+
+document!
10+
+
11+
This part of the
12+
document has stayed the
13+
same from version to
14+
@@ -5,16 +11,10 @@
15+
be shown if it doesn't
16+
change. Otherwise, that
17+
would not be helping to
18+
-compress the size of the
19+
-changes.
20+
-
21+
-This paragraph contains
22+
-text that is outdated.
23+
-It will be deleted in the
24+
-near future.
25+
+compress anything.
26+
27+
It is important to spell
28+
-check this dokument. On
29+
+check this document. On

0 commit comments

Comments
 (0)