-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathdiff.go
More file actions
107 lines (97 loc) · 2.25 KB
/
diff.go
File metadata and controls
107 lines (97 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package api
import (
"bufio"
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"runtime/trace"
"sort"
"github.com/cubicdaiya/gonp"
)
func writeFiles(ctx context.Context, files map[string]string, stderr io.Writer) error {
defer trace.StartRegion(ctx, "writefiles").End()
for filename, source := range files {
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
fmt.Fprintf(stderr, "%s: %s\n", filename, err)
return err
}
if err := os.WriteFile(filename, []byte(source), 0644); err != nil {
fmt.Fprintf(stderr, "%s: %s\n", filename, err)
return err
}
}
return nil
}
func diffFiles(ctx context.Context, files map[string]string, stderr io.Writer) error {
defer trace.StartRegion(ctx, "checkfiles").End()
var errored bool
wd, _ := os.Getwd()
keys := make([]string, 0, len(files))
for k := range files {
keys = append(keys, k)
}
sort.Strings(keys)
for _, filename := range keys {
source := files[filename]
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
errored = true
continue
}
existing, err := os.ReadFile(filename)
if err != nil {
errored = true
fmt.Fprintf(stderr, "%s: %s\n", filename, err)
continue
}
d := gonp.New(getLines(existing), getLines([]byte(source)))
d.Compose()
uniHunks := filterHunks(d.UnifiedHunks())
if len(uniHunks) > 0 {
errored = true
label := filename
if wd != "" {
if rel, err := filepath.Rel(wd, filename); err == nil {
label = "/" + rel
}
}
fmt.Fprintf(stderr, "--- a%s\n", label)
fmt.Fprintf(stderr, "+++ b%s\n", label)
d.FprintUniHunks(stderr, uniHunks)
}
}
if errored {
return errors.New("diff found")
}
return nil
}
func getLines(f []byte) []string {
fp := bytes.NewReader(f)
scanner := bufio.NewScanner(fp)
lines := make([]string, 0)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines
}
func filterHunks[T gonp.Elem](uniHunks []gonp.UniHunk[T]) []gonp.UniHunk[T] {
var out []gonp.UniHunk[T]
for i, uniHunk := range uniHunks {
var changed bool
for _, e := range uniHunk.GetChanges() {
switch e.GetType() {
case gonp.SesDelete:
changed = true
case gonp.SesAdd:
changed = true
}
}
if changed {
out = append(out, uniHunks[i])
}
}
return out
}