Files
polaris/vendor/github.com/rogpeppe/go-internal/internal/textutil/diff.go
Bobby Brennan 54a4f92695 Pack static assets into packr box for portability
copy config.yaml to docker image

enable external usage of dashboard package

gofmt

fix comment

use packr for assets

add gobuffalo/packr dependency

add dependencies

fix pointer issues

add output-file option
2019-04-18 18:25:16 +00:00

79 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package textutil
import (
"fmt"
"strings"
)
// Diff returns a formatted diff of the two texts,
// showing the entire text and the minimum line-level
// additions and removals to turn text1 into text2.
// (That is, lines only in text1 appear with a leading -,
// and lines only in text2 appear with a leading +.)
func Diff(text1, text2 string) string {
if text1 != "" && !strings.HasSuffix(text1, "\n") {
text1 += "(missing final newline)"
}
lines1 := strings.Split(text1, "\n")
lines1 = lines1[:len(lines1)-1] // remove empty string after final line
if text2 != "" && !strings.HasSuffix(text2, "\n") {
text2 += "(missing final newline)"
}
lines2 := strings.Split(text2, "\n")
lines2 = lines2[:len(lines2)-1] // remove empty string after final line
// Naive dynamic programming algorithm for edit distance.
// https://en.wikipedia.org/wiki/WagnerFischer_algorithm
// dist[i][j] = edit distance between lines1[:len(lines1)-i] and lines2[:len(lines2)-j]
// (The reversed indices make following the minimum cost path
// visit lines in the same order as in the text.)
dist := make([][]int, len(lines1)+1)
for i := range dist {
dist[i] = make([]int, len(lines2)+1)
if i == 0 {
for j := range dist[0] {
dist[0][j] = j
}
continue
}
for j := range dist[i] {
if j == 0 {
dist[i][0] = i
continue
}
cost := dist[i][j-1] + 1
if cost > dist[i-1][j]+1 {
cost = dist[i-1][j] + 1
}
if lines1[len(lines1)-i] == lines2[len(lines2)-j] {
if cost > dist[i-1][j-1] {
cost = dist[i-1][j-1]
}
}
dist[i][j] = cost
}
}
var buf strings.Builder
i, j := len(lines1), len(lines2)
for i > 0 || j > 0 {
cost := dist[i][j]
if i > 0 && j > 0 && cost == dist[i-1][j-1] && lines1[len(lines1)-i] == lines2[len(lines2)-j] {
fmt.Fprintf(&buf, " %s\n", lines1[len(lines1)-i])
i--
j--
} else if i > 0 && cost == dist[i-1][j]+1 {
fmt.Fprintf(&buf, "-%s\n", lines1[len(lines1)-i])
i--
} else {
fmt.Fprintf(&buf, "+%s\n", lines2[len(lines2)-j])
j--
}
}
return buf.String()
}