Skip to content

Instantly share code, notes, and snippets.

@njam
Created February 16, 2018 17:25
Show Gist options
  • Save njam/5885e45f2a0590542f5a96a6391b8e56 to your computer and use it in GitHub Desktop.
Save njam/5885e45f2a0590542f5a96a6391b8e56 to your computer and use it in GitHub Desktop.
package main
func printDiff(suppressedKinds []string, kind string, context int, before, after string, to io.Writer) {
diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n"))
for _, ckind := range suppressedKinds {
if ckind == kind {
str := fmt.Sprintf("+ Changes suppressed on sensitive content of type %s\n", kind)
fmt.Fprintf(to, ansi.Color(str, "yellow"))
return
}
}
chunks := chunkDiffs(diffs, context)
for i, chunk := range chunks {
if chunk.MissingBefore {
fmt.Fprintln(to, " ...")
}
for _, diff := range chunk.Diffs {
text := diff.Payload
switch diff.Delta {
case difflib.RightOnly:
fmt.Fprintf(to, "%s\n", ansi.Color("+ "+text, "green"))
case difflib.LeftOnly:
fmt.Fprintf(to, "%s\n", ansi.Color("- "+text, "red"))
case difflib.Common:
fmt.Fprintf(to, "%s\n", " "+text)
}
}
if chunk.MissingAfter && i == len(chunks)-1 {
fmt.Fprintln(to, " ...")
}
}
}
type Chunk struct {
Diffs []difflib.DiffRecord
MissingBefore bool
MissingAfter bool
}
func chunkDiffs(diffs []difflib.DiffRecord, context int) []Chunk {
var changedLines []int
for i, diff := range diffs {
if diff.Delta != difflib.Common {
changedLines = append(changedLines, i)
}
}
var chunks []Chunk
var chunkStart int
var chunkOngoing bool
for i, line := range changedLines {
if !chunkOngoing {
chunkStart = max(line-context, 0)
chunkOngoing = true
}
if i < len(changedLines)-1 {
nextChangedLine := changedLines[i+1]
linesBetween := nextChangedLine - line - 1
if linesBetween <= 2*context {
continue
}
}
chunkEnd := min(line+context, len(diffs))
chunk := Chunk{
Diffs: diffs[chunkStart:chunkEnd+1],
MissingBefore: chunkStart > 0,
MissingAfter: chunkEnd < len(diffs),
}
chunks = append(chunks, chunk)
chunkOngoing = false
}
return chunks
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment