Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions cmd/promptctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"path/filepath"
"regexp"
"slices"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -136,17 +137,16 @@ func runDiff(r *git.Repository, ref string, w io.Writer) []fileVerdict {

var out []fileVerdict
for _, p := range promptUnion(tree) {
old := blobContent(tree, p)
neu := diskContent(p)
if old == neu {
a, b, differs := changedLines(blobContent(tree, p), diskContent(p))
if !differs {
continue
}
if _, err := tree.File(p); err != nil { // added since ref: nothing to diff against
fmt.Fprintf(w, "## %s\nnew prompt (not in %s)\n => new\n\n", p, ref)
out = append(out, fileVerdict{p, "new"})
continue
}
res, err := semdiff.Analyze(emb, splitLines(old), splitLines(neu))
res, err := semdiff.Analyze(emb, a, b)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -549,3 +549,11 @@ func firstLine(s string) string {
func splitLines(s string) []string {
return strings.Split(strings.ReplaceAll(s, "\r\n", "\n"), "\n")
}

// changedLines splits both versions into lines and reports whether they differ.
// The comparison runs after splitLines normalises line endings, so a CRLF-only
// difference (core.autocrlf on Windows) is not a change.
func changedLines(old, neu string) (a, b []string, changed bool) {
a, b = splitLines(old), splitLines(neu)
return a, b, !slices.Equal(a, b)
}
23 changes: 23 additions & 0 deletions cmd/promptctl/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ func TestPathToURI(t *testing.T) {
}
}

func TestChangedLines(t *testing.T) {
cases := []struct {
name, old, neu string
want bool
}{
{"identical", "a\nb\n", "a\nb\n", false},
{"crlf vs lf", "a\r\nb\r\n", "a\nb\n", false},
{"lf vs crlf", "a\nb\n", "a\r\nb\r\n", false},
{"mixed endings", "a\r\nb\n", "a\nb\r\n", false},
{"text change", "a\r\nb\r\n", "a\nc\n", true},
{"trailing newline added", "a\nb", "a\r\nb\r\n", true},
}
for _, c := range cases {
a, b, changed := changedLines(c.old, c.neu)
if changed != c.want {
t.Errorf("%s: changed = %v, want %v", c.name, changed, c.want)
}
if !reflect.DeepEqual(a, splitLines(c.old)) || !reflect.DeepEqual(b, splitLines(c.neu)) {
t.Errorf("%s: lines = %q, %q, want normalised split of inputs", c.name, a, b)
}
}
}

func TestDeriveSlots(t *testing.T) {
got := deriveSlots("Hi {name}, welcome to {org}. Bye {name}.")
if want := []string{"name", "org"}; !reflect.DeepEqual(got, want) { // deduped, in order
Expand Down
Loading