Allow diff.ForEach to enumerate files, hunks, and lines with single call. Support use of closures for enumeration.
This commit is contained in:
parent
aea899e877
commit
f85c38ce22
92
diff.go
92
diff.go
|
@ -151,22 +151,34 @@ func (diff *Diff) Free() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiffForEachFileCallback func(*DiffDelta) error
|
type diffForEachData struct {
|
||||||
|
FileCallback DiffForEachFileCallback
|
||||||
type diffForEachFileData struct {
|
HunkCallback DiffForEachHunkCallback
|
||||||
Callback DiffForEachFileCallback
|
LineCallback DiffForEachLineCallback
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (diff *Diff) ForEachFile(cb DiffForEachFileCallback) error {
|
type DiffForEachFileCallback func(*DiffDelta, float64) (DiffForEachHunkCallback, error)
|
||||||
|
|
||||||
|
func (diff *Diff) ForEach(cbFile DiffForEachFileCallback, diffHunks bool, diffLines bool) error {
|
||||||
if diff.ptr == nil {
|
if diff.ptr == nil {
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &diffForEachFileData{
|
intHunks := C.int(0)
|
||||||
Callback: cb,
|
if diffHunks {
|
||||||
|
intHunks = C.int(1)
|
||||||
}
|
}
|
||||||
ecode := C._go_git_diff_foreach(diff.ptr, 1, 0, 0, unsafe.Pointer(data))
|
|
||||||
|
intLines := C.int(0)
|
||||||
|
if diffLines {
|
||||||
|
intLines = C.int(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := &diffForEachData{
|
||||||
|
FileCallback: cbFile,
|
||||||
|
}
|
||||||
|
ecode := C._go_git_diff_foreach(diff.ptr, 1, intHunks, intLines, unsafe.Pointer(data))
|
||||||
if ecode < 0 {
|
if ecode < 0 {
|
||||||
return data.Error
|
return data.Error
|
||||||
}
|
}
|
||||||
|
@ -175,32 +187,37 @@ func (diff *Diff) ForEachFile(cb DiffForEachFileCallback) error {
|
||||||
|
|
||||||
//export diffForEachFileCb
|
//export diffForEachFileCb
|
||||||
func diffForEachFileCb(delta *C.git_diff_delta, progress C.float, payload unsafe.Pointer) int {
|
func diffForEachFileCb(delta *C.git_diff_delta, progress C.float, payload unsafe.Pointer) int {
|
||||||
data := (*diffForEachFileData)(payload)
|
data := (*diffForEachData)(payload)
|
||||||
|
|
||||||
err := data.Callback(newDiffDeltaFromC(delta))
|
data.HunkCallback = nil
|
||||||
if err != nil {
|
if data.FileCallback != nil {
|
||||||
data.Error = err
|
cb, err := data.FileCallback(newDiffDeltaFromC(delta), float64(progress))
|
||||||
return -1
|
if err != nil {
|
||||||
|
data.Error = err
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
data.HunkCallback = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type diffForEachHunkData struct {
|
type DiffForEachHunkCallback func(*DiffHunk) (DiffForEachLineCallback, error)
|
||||||
Callback DiffForEachHunkCallback
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
type DiffForEachHunkCallback func(*DiffHunk) error
|
func (diff *Diff) ForEachHunk(cb DiffForEachHunkCallback, diffLines bool) error {
|
||||||
|
|
||||||
func (diff *Diff) ForEachHunk(cb DiffForEachHunkCallback) error {
|
|
||||||
if diff.ptr == nil {
|
if diff.ptr == nil {
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
data := &diffForEachHunkData{
|
data := &diffForEachData{
|
||||||
Callback: cb,
|
HunkCallback: cb,
|
||||||
}
|
}
|
||||||
ecode := C._go_git_diff_foreach(diff.ptr, 0, 1, 0, unsafe.Pointer(data))
|
|
||||||
|
intLines := C.int(0)
|
||||||
|
if diffLines {
|
||||||
|
intLines = C.int(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
ecode := C._go_git_diff_foreach(diff.ptr, 0, 1, intLines, unsafe.Pointer(data))
|
||||||
if ecode < 0 {
|
if ecode < 0 {
|
||||||
return data.Error
|
return data.Error
|
||||||
}
|
}
|
||||||
|
@ -209,22 +226,21 @@ func (diff *Diff) ForEachHunk(cb DiffForEachHunkCallback) error {
|
||||||
|
|
||||||
//export diffForEachHunkCb
|
//export diffForEachHunkCb
|
||||||
func diffForEachHunkCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, payload unsafe.Pointer) int {
|
func diffForEachHunkCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, payload unsafe.Pointer) int {
|
||||||
data := (*diffForEachHunkData)(payload)
|
data := (*diffForEachData)(payload)
|
||||||
|
|
||||||
err := data.Callback(newDiffHunkFromC(delta, hunk))
|
data.LineCallback = nil
|
||||||
if err != nil {
|
if data.HunkCallback != nil {
|
||||||
data.Error = err
|
cb, err := data.HunkCallback(newDiffHunkFromC(delta, hunk))
|
||||||
return -1
|
if err != nil {
|
||||||
|
data.Error = err
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
data.LineCallback = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
type diffForEachLineData struct {
|
|
||||||
Callback DiffForEachLineCallback
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
type DiffForEachLineCallback func(*DiffLine) error
|
type DiffForEachLineCallback func(*DiffLine) error
|
||||||
|
|
||||||
func (diff *Diff) ForEachLine(cb DiffForEachLineCallback) error {
|
func (diff *Diff) ForEachLine(cb DiffForEachLineCallback) error {
|
||||||
|
@ -232,8 +248,8 @@ func (diff *Diff) ForEachLine(cb DiffForEachLineCallback) error {
|
||||||
return ErrInvalid
|
return ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &diffForEachLineData{
|
data := &diffForEachData{
|
||||||
Callback: cb,
|
LineCallback: cb,
|
||||||
}
|
}
|
||||||
|
|
||||||
ecode := C._go_git_diff_foreach(diff.ptr, 0, 0, 1, unsafe.Pointer(data))
|
ecode := C._go_git_diff_foreach(diff.ptr, 0, 0, 1, unsafe.Pointer(data))
|
||||||
|
@ -246,9 +262,9 @@ func (diff *Diff) ForEachLine(cb DiffForEachLineCallback) error {
|
||||||
//export diffForEachLineCb
|
//export diffForEachLineCb
|
||||||
func diffForEachLineCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line, payload unsafe.Pointer) int {
|
func diffForEachLineCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line, payload unsafe.Pointer) int {
|
||||||
|
|
||||||
data := (*diffForEachLineData)(payload)
|
data := (*diffForEachData)(payload)
|
||||||
|
|
||||||
err := data.Callback(newDiffLineFromC(delta, hunk, line))
|
err := data.LineCallback(newDiffLineFromC(delta, hunk, line))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
data.Error = err
|
data.Error = err
|
||||||
return -1
|
return -1
|
||||||
|
|
41
diff_test.go
41
diff_test.go
|
@ -28,11 +28,18 @@ func TestDiffTreeToTree(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
files := make([]string, 0)
|
files := make([]string, 0)
|
||||||
|
hunks := make([]*DiffHunk, 0)
|
||||||
err = diff.ForEachFile(func(file *DiffDelta) error {
|
lines := make([]*DiffLine, 0)
|
||||||
|
err = diff.ForEach(func(file *DiffDelta, progress float64) (DiffForEachHunkCallback, error) {
|
||||||
files = append(files, file.OldFile.Path)
|
files = append(files, file.OldFile.Path)
|
||||||
return nil
|
return func(hunk *DiffHunk) (DiffForEachLineCallback, error) {
|
||||||
})
|
hunks = append(hunks, hunk)
|
||||||
|
return func(line *DiffLine) error {
|
||||||
|
lines = append(lines, line)
|
||||||
|
return nil
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}, true, true)
|
||||||
|
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
|
@ -44,11 +51,31 @@ func TestDiffTreeToTree(t *testing.T) {
|
||||||
t.Fatal("File in diff was expected to be README")
|
t.Fatal("File in diff was expected to be README")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(hunks) != 1 {
|
||||||
|
t.Fatal("Incorrect number of hunks in diff")
|
||||||
|
}
|
||||||
|
|
||||||
|
if hunks[0].OldStart != 1 || hunks[0].NewStart != 1 {
|
||||||
|
t.Fatal("Incorrect hunk")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lines) != 2 {
|
||||||
|
t.Fatal("Incorrect number of lines in diff")
|
||||||
|
}
|
||||||
|
|
||||||
|
if lines[0].Content != "foo\n" {
|
||||||
|
t.Fatal("Incorrect lines in diff")
|
||||||
|
}
|
||||||
|
|
||||||
|
if lines[1].Content != "file changed\n" {
|
||||||
|
t.Fatal("Incorrect lines in diff")
|
||||||
|
}
|
||||||
|
|
||||||
errTest := errors.New("test error")
|
errTest := errors.New("test error")
|
||||||
|
|
||||||
err = diff.ForEachFile(func(file *DiffDelta) error {
|
err = diff.ForEach(func(file *DiffDelta, progress float64) (DiffForEachHunkCallback, error) {
|
||||||
return errTest
|
return nil, errTest
|
||||||
})
|
}, false, false)
|
||||||
|
|
||||||
if err != errTest {
|
if err != errTest {
|
||||||
t.Fatal("Expected custom error to be returned")
|
t.Fatal("Expected custom error to be returned")
|
||||||
|
|
Loading…
Reference in New Issue