Consolidate DiffPath and Diff methods (#61600)

Diff already has an option for scoping to a specific path, so merging these two together, to simplify the API surface we need to create for the new gRPC APIs around diffs.

## Test plan

Adjusted a few tests, hoping that integration and E2E tests cover this. Also ran some git commands locally to check if they produce roughly equivalent output.
Code reviews will help as well.
This commit is contained in:
Erik Seliger 2024-04-16 13:23:07 +02:00 committed by GitHub
parent d921fb6e1c
commit e7d212b0ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 59 additions and 415 deletions

View File

@ -121,7 +121,6 @@ go_test(
"@com_github_grafana_regexp//:regexp",
"@com_github_inconshreveable_log15//:log15",
"@com_github_masterminds_semver//:semver",
"@com_github_sourcegraph_go_diff//diff",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//mock",
"@com_github_stretchr_testify//require",

View File

@ -14,7 +14,6 @@ import (
"sync"
"time"
diff "github.com/sourcegraph/go-diff/diff"
api "github.com/sourcegraph/sourcegraph/internal/api"
store "github.com/sourcegraph/sourcegraph/internal/batches/store"
types1 "github.com/sourcegraph/sourcegraph/internal/batches/types"
@ -11014,9 +11013,6 @@ type MockGitserverClient struct {
// DiffFunc is an instance of a mock function object controlling the
// behavior of the method Diff.
DiffFunc *GitserverClientDiffFunc
// DiffPathFunc is an instance of a mock function object controlling the
// behavior of the method DiffPath.
DiffPathFunc *GitserverClientDiffPathFunc
// DiffSymbolsFunc is an instance of a mock function object controlling
// the behavior of the method DiffSymbols.
DiffSymbolsFunc *GitserverClientDiffSymbolsFunc
@ -11192,11 +11188,6 @@ func NewMockGitserverClient() *MockGitserverClient {
return
},
},
DiffPathFunc: &GitserverClientDiffPathFunc{
defaultHook: func(context.Context, api.RepoName, string, string, string) (r0 []*diff.Hunk, r1 error) {
return
},
},
DiffSymbolsFunc: &GitserverClientDiffSymbolsFunc{
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 []byte, r1 error) {
return
@ -11449,11 +11440,6 @@ func NewStrictMockGitserverClient() *MockGitserverClient {
panic("unexpected invocation of MockGitserverClient.Diff")
},
},
DiffPathFunc: &GitserverClientDiffPathFunc{
defaultHook: func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
panic("unexpected invocation of MockGitserverClient.DiffPath")
},
},
DiffSymbolsFunc: &GitserverClientDiffSymbolsFunc{
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) ([]byte, error) {
panic("unexpected invocation of MockGitserverClient.DiffSymbols")
@ -11685,9 +11671,6 @@ func NewMockGitserverClientFrom(i gitserver.Client) *MockGitserverClient {
DiffFunc: &GitserverClientDiffFunc{
defaultHook: i.Diff,
},
DiffPathFunc: &GitserverClientDiffPathFunc{
defaultHook: i.DiffPath,
},
DiffSymbolsFunc: &GitserverClientDiffSymbolsFunc{
defaultHook: i.DiffSymbols,
},
@ -13033,123 +13016,6 @@ func (c GitserverClientDiffFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
// GitserverClientDiffPathFunc describes the behavior when the DiffPath
// method of the parent MockGitserverClient instance is invoked.
type GitserverClientDiffPathFunc struct {
defaultHook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)
hooks []func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)
history []GitserverClientDiffPathFuncCall
mutex sync.Mutex
}
// DiffPath delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockGitserverClient) DiffPath(v0 context.Context, v1 api.RepoName, v2 string, v3 string, v4 string) ([]*diff.Hunk, error) {
r0, r1 := m.DiffPathFunc.nextHook()(v0, v1, v2, v3, v4)
m.DiffPathFunc.appendCall(GitserverClientDiffPathFuncCall{v0, v1, v2, v3, v4, r0, r1})
return r0, r1
}
// SetDefaultHook sets function that is called when the DiffPath method of
// the parent MockGitserverClient instance is invoked and the hook queue is
// empty.
func (f *GitserverClientDiffPathFunc) SetDefaultHook(hook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)) {
f.defaultHook = hook
}
// PushHook adds a function to the end of hook queue. Each invocation of the
// DiffPath method of the parent MockGitserverClient instance invokes the
// hook at the front of the queue and discards it. After the queue is empty,
// the default hook function is invoked for any future action.
func (f *GitserverClientDiffPathFunc) PushHook(hook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
}
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *GitserverClientDiffPathFunc) SetDefaultReturn(r0 []*diff.Hunk, r1 error) {
f.SetDefaultHook(func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
return r0, r1
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *GitserverClientDiffPathFunc) PushReturn(r0 []*diff.Hunk, r1 error) {
f.PushHook(func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
return r0, r1
})
}
func (f *GitserverClientDiffPathFunc) nextHook() func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
f.mutex.Lock()
defer f.mutex.Unlock()
if len(f.hooks) == 0 {
return f.defaultHook
}
hook := f.hooks[0]
f.hooks = f.hooks[1:]
return hook
}
func (f *GitserverClientDiffPathFunc) appendCall(r0 GitserverClientDiffPathFuncCall) {
f.mutex.Lock()
f.history = append(f.history, r0)
f.mutex.Unlock()
}
// History returns a sequence of GitserverClientDiffPathFuncCall objects
// describing the invocations of this function.
func (f *GitserverClientDiffPathFunc) History() []GitserverClientDiffPathFuncCall {
f.mutex.Lock()
history := make([]GitserverClientDiffPathFuncCall, len(f.history))
copy(history, f.history)
f.mutex.Unlock()
return history
}
// GitserverClientDiffPathFuncCall is an object that describes an invocation
// of method DiffPath on an instance of MockGitserverClient.
type GitserverClientDiffPathFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 api.RepoName
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 string
// Arg3 is the value of the 4th argument passed to this method
// invocation.
Arg3 string
// Arg4 is the value of the 5th argument passed to this method
// invocation.
Arg4 string
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 []*diff.Hunk
// Result1 is the value of the 2nd result returned from this method
// invocation.
Result1 error
}
// Args returns an interface slice containing the arguments of this
// invocation.
func (c GitserverClientDiffPathFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3, c.Arg4}
}
// Results returns an interface slice containing the results of this
// invocation.
func (c GitserverClientDiffPathFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
// GitserverClientDiffSymbolsFunc describes the behavior when the
// DiffSymbols method of the parent MockGitserverClient instance is invoked.
type GitserverClientDiffSymbolsFunc struct {

View File

@ -2,6 +2,7 @@ package codenav
import (
"context"
"io"
"strconv"
"strings"
@ -11,6 +12,7 @@ import (
"github.com/sourcegraph/sourcegraph/internal/codeintel/codenav/shared"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
sgtypes "github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
// GitTreeTranslator translates a position within a git tree at a source commit into the
@ -154,8 +156,33 @@ func (g *gitTreeTranslator) readCachedHunks(ctx context.Context, repo *sgtypes.R
// readHunks returns a position-ordered slice of changes (additions or deletions) of
// the given path between the given source and target commits.
func (g *gitTreeTranslator) readHunks(ctx context.Context, repo *sgtypes.Repo, sourceCommit, targetCommit, path string) ([]*diff.Hunk, error) {
return g.client.DiffPath(ctx, repo.Name, sourceCommit, targetCommit, path)
func (g *gitTreeTranslator) readHunks(ctx context.Context, repo *sgtypes.Repo, sourceCommit, targetCommit, path string) (_ []*diff.Hunk, err error) {
r, err := g.client.Diff(ctx, gitserver.DiffOptions{
Repo: repo.Name,
Base: sourceCommit,
Head: targetCommit,
Paths: []string{path},
RangeType: "..",
})
if err != nil {
return nil, err
}
defer func() {
closeErr := r.Close()
if err == nil {
err = closeErr
}
}()
fd, err := r.Next()
if err != nil {
if errors.Is(err, io.EOF) {
return nil, nil
}
return nil, err
}
return fd.Hunks, nil
}
// findHunk returns the last thunk that does not begin after the given line.

View File

@ -41,7 +41,7 @@ func TestGetTargetCommitPathFromSourcePath(t *testing.T) {
func TestGetTargetCommitPositionFromSourcePosition(t *testing.T) {
client := gitserver.NewMockClientWithExecReader(nil, func(_ context.Context, _ api.RepoName, args []string) (reader io.ReadCloser, err error) {
expectedArgs := []string{"diff", "deadbeef1", "deadbeef2", "--", "/foo/bar.go"}
expectedArgs := []string{"diff", "--find-renames", "--full-index", "--inter-hunk-context=3", "--no-prefix", "deadbeef1..deadbeef2", "--", "/foo/bar.go"}
if diff := cmp.Diff(expectedArgs, args); diff != "" {
t.Errorf("unexpected exec reader args (-want +got):\n%s", diff)
}
@ -106,7 +106,7 @@ func TestGetTargetCommitPositionFromSourcePositionEmptyDiff(t *testing.T) {
func TestGetTargetCommitPositionFromSourcePositionReverse(t *testing.T) {
client := gitserver.NewMockClientWithExecReader(nil, func(_ context.Context, _ api.RepoName, args []string) (reader io.ReadCloser, err error) {
expectedArgs := []string{"diff", "deadbeef2", "deadbeef1", "--", "/foo/bar.go"}
expectedArgs := []string{"diff", "--find-renames", "--full-index", "--inter-hunk-context=3", "--no-prefix", "deadbeef2..deadbeef1", "--", "/foo/bar.go"}
if diff := cmp.Diff(expectedArgs, args); diff != "" {
t.Errorf("unexpected exec reader args (-want +got):\n%s", diff)
}
@ -142,7 +142,7 @@ func TestGetTargetCommitPositionFromSourcePositionReverse(t *testing.T) {
func TestGetTargetCommitRangeFromSourceRange(t *testing.T) {
client := gitserver.NewMockClientWithExecReader(nil, func(_ context.Context, _ api.RepoName, args []string) (reader io.ReadCloser, err error) {
expectedArgs := []string{"diff", "deadbeef1", "deadbeef2", "--", "/foo/bar.go"}
expectedArgs := []string{"diff", "--find-renames", "--full-index", "--inter-hunk-context=3", "--no-prefix", "deadbeef1..deadbeef2", "--", "/foo/bar.go"}
if diff := cmp.Diff(expectedArgs, args); diff != "" {
t.Errorf("unexpected exec reader args (-want +got):\n%s", diff)
}
@ -216,7 +216,7 @@ func TestGetTargetCommitRangeFromSourceRangeEmptyDiff(t *testing.T) {
func TestGetTargetCommitRangeFromSourceRangeReverse(t *testing.T) {
client := gitserver.NewMockClientWithExecReader(nil, func(_ context.Context, _ api.RepoName, args []string) (reader io.ReadCloser, err error) {
expectedArgs := []string{"diff", "deadbeef2", "deadbeef1", "--", "/foo/bar.go"}
expectedArgs := []string{"diff", "--find-renames", "--full-index", "--inter-hunk-context=3", "--no-prefix", "deadbeef2..deadbeef1", "--", "/foo/bar.go"}
if diff := cmp.Diff(expectedArgs, args); diff != "" {
t.Errorf("unexpected exec reader args (-want +got):\n%s", diff)
}

View File

@ -1,14 +1,14 @@
package codenav
import (
"bytes"
"context"
"io"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
godiff "github.com/sourcegraph/go-diff/diff"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/codeintel/codenav/shared"
uploadsshared "github.com/sourcegraph/sourcegraph/internal/codeintel/uploads/shared"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
@ -38,15 +38,11 @@ func TestRanges(t *testing.T) {
mockLsifStore := NewMockLsifStore()
mockUploadSvc := NewMockUploadService()
mockGitserverClient := gitserver.NewMockClient()
mockGitserverClient.DiffPathFunc.SetDefaultHook(func(ctx context.Context, repo api.RepoName, sourceCommit, targetCommit, path string) ([]*godiff.Hunk, error) {
if path == "sub3/changed.go" {
fileDiff, err := godiff.ParseFileDiff([]byte(rangesDiff))
if err != nil {
return nil, err
}
return fileDiff.Hunks, nil
mockGitserverClient.DiffFunc.SetDefaultHook(func(ctx context.Context, opt gitserver.DiffOptions) (*gitserver.DiffFileIterator, error) {
if len(opt.Paths) > 0 && opt.Paths[0] == "sub3/changed.go" {
return gitserver.NewDiffFileIterator(io.NopCloser(strings.NewReader(rangesDiff))), nil
}
return nil, nil
return gitserver.NewDiffFileIterator(io.NopCloser(bytes.NewReader([]byte{}))), nil
})
hunkCache, _ := NewHunkCache(50)

View File

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"io"
"strings"
"testing"
"github.com/sourcegraph/scip/bindings/go/scip"
@ -24,6 +25,7 @@ func TestSnapshotForDocument(t *testing.T) {
mockLsifStore := NewMockLsifStore()
mockUploadSvc := NewMockUploadService()
mockGitserverClient := gitserver.NewMockClient()
mockGitserverClient.DiffFunc.SetDefaultReturn(gitserver.NewDiffFileIterator(io.NopCloser(strings.NewReader(""))), nil)
// Init service
svc := newService(observation.TestContextTB(t), mockRepoStore, mockLsifStore, mockUploadSvc, mockGitserverClient)

View File

@ -1,12 +1,10 @@
package gitserver
import (
"bytes"
"context"
"fmt"
"io"
"io/fs"
"os"
"strings"
"testing"
"time"
@ -19,7 +17,6 @@ import (
sglog "github.com/sourcegraph/log"
"github.com/sourcegraph/log/logtest"
"github.com/sourcegraph/sourcegraph/internal/actor"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/authz"
"github.com/sourcegraph/sourcegraph/internal/extsvc/gitolite"
@ -144,36 +141,6 @@ func NewMockClientWithExecReader(checker authz.SubRepoPermissionChecker, execRea
}, nil
})
// NOTE: This hook is the same as DiffPath, but with `execReader` used above
client.DiffPathFunc.SetDefaultHook(func(ctx context.Context, repo api.RepoName, sourceCommit, targetCommit, path string) ([]*diff.Hunk, error) {
a := actor.FromContext(ctx)
if hasAccess, err := authz.FilterActorPath(ctx, checker, a, repo, path); err != nil {
return nil, err
} else if !hasAccess {
return nil, os.ErrNotExist
}
// Here is where all the mocking happens!
reader, err := execReader(ctx, repo, []string{"diff", sourceCommit, targetCommit, "--", path})
if err != nil {
return nil, err
}
defer reader.Close()
output, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
if len(output) == 0 {
return nil, nil
}
d, err := diff.NewFileDiffReader(bytes.NewReader(output)).Read()
if err != nil {
return nil, err
}
return d.Hunks, nil
})
return client
}
@ -384,10 +351,6 @@ type Client interface {
// Stat returns a FileInfo describing the named file at commit.
Stat(ctx context.Context, repo api.RepoName, commit api.CommitID, path string) (fs.FileInfo, error)
// DiffPath returns a position-ordered slice of changes (additions or deletions)
// of the given path between the given source and target commits.
DiffPath(ctx context.Context, repo api.RepoName, sourceCommit, targetCommit, path string) ([]*diff.Hunk, error)
// ReadDir reads the contents of the named directory at commit.
ReadDir(ctx context.Context, repo api.RepoName, commit api.CommitID, path string, recurse bool) ([]fs.FileInfo, error)

View File

@ -386,43 +386,6 @@ func parseTimestamp(timestamp string) (time.Time, error) {
// the root commit.
const DevNullSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
func (c *clientImplementor) DiffPath(ctx context.Context, repo api.RepoName, sourceCommit, targetCommit, path string) (_ []*diff.Hunk, err error) {
ctx, _, endObservation := c.operations.diffPath.With(ctx, &err, observation.Args{
MetricLabelValues: []string{c.scope},
Attrs: []attribute.KeyValue{
repo.Attr(),
},
})
defer endObservation(1, observation.Args{})
a := actor.FromContext(ctx)
if hasAccess, err := authz.FilterActorPath(ctx, c.subRepoPermsChecker, a, repo, path); err != nil {
return nil, err
} else if !hasAccess {
return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
}
args := []string{"diff", sourceCommit, targetCommit, "--", path}
reader, err := c.gitCommand(repo, args...).StdoutReader(ctx)
if err != nil {
return nil, err
}
defer reader.Close()
output, err := io.ReadAll(reader)
if err != nil {
return nil, err
}
if len(output) == 0 {
return nil, nil
}
d, err := diff.NewFileDiffReader(bytes.NewReader(output)).Read()
if err != nil {
return nil, err
}
return d.Hunks, nil
}
// DiffSymbols performs a diff command which is expected to be parsed by our symbols package
func (c *clientImplementor) DiffSymbols(ctx context.Context, repo api.RepoName, commitA, commitB api.CommitID) (_ []byte, err error) {
ctx, _, endObservation := c.operations.diffSymbols.With(ctx, &err, observation.Args{

View File

@ -356,62 +356,25 @@ index 9bd8209..d2acfa9 100644
if count != testDiffFiles {
t.Errorf("unexpected diff count: have %d; want %d", count, testDiffFiles)
}
})
}
func TestDiffPath(t *testing.T) {
testDiff := `
diff --git a/foo.md b/foo.md
index 51a59ef1c..493090958 100644
--- a/foo.md
+++ b/foo.md
@@ -1 +1 @@
-this is my file content
+this is my file contnent
`
t.Run("basic", func(t *testing.T) {
checker := authz.NewMockSubRepoPermissionChecker()
c := NewMockClientWithExecReader(checker, func(_ context.Context, _ api.RepoName, args []string) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader(testDiff)), nil
t.Run("early close", func(t *testing.T) {
routinesBefore := runtime.NumGoroutine()
i, err := c.Diff(ctx, DiffOptions{Base: "foo", Head: "bar"})
require.NoError(t, err)
hunk, err := i.Next()
require.NoError(t, err)
require.Equal(t, "INSTALL.md", hunk.OrigName)
// We did not receive io.EOF above, but are closing the diff reader,
// this should not error.
require.NoError(t, i.Close())
// Expect no leaked routines.
routinesAfter := runtime.NumGoroutine()
require.Equal(t, routinesBefore, routinesAfter)
})
ctx := actor.WithActor(context.Background(), &actor.Actor{
UID: 1,
})
hunks, err := c.DiffPath(ctx, "", "sourceCommit", "", "file")
if err != nil {
t.Errorf("unexpected error: %s", err)
}
if len(hunks) != 1 {
t.Errorf("unexpected hunks returned: %d", len(hunks))
}
})
t.Run("with sub-repo permissions enabled", func(t *testing.T) {
checker := authz.NewMockSubRepoPermissionChecker()
ctx := actor.WithActor(context.Background(), &actor.Actor{
UID: 1,
})
fileName := "foo"
checker.EnabledFunc.SetDefaultHook(func() bool {
return true
})
// User doesn't have access to this file
checker.PermissionsFunc.SetDefaultHook(func(ctx context.Context, i int32, content authz.RepoContent) (authz.Perms, error) {
if content.Path == fileName {
return authz.None, nil
}
return authz.Read, nil
})
usePermissionsForFilePermissionsFunc(checker)
c := NewMockClientWithExecReader(checker, func(_ context.Context, _ api.RepoName, args []string) (io.ReadCloser, error) {
return io.NopCloser(strings.NewReader(testDiff)), nil
})
hunks, err := c.DiffPath(ctx, "", "sourceCommit", "", fileName)
if !os.IsNotExist(err) {
t.Errorf("unexpected error: %s", err)
}
if hunks != nil {
t.Errorf("expected DiffPath to return no results, got %v", hunks)
}
})
}

View File

@ -13,7 +13,6 @@ import (
"sync"
"time"
diff "github.com/sourcegraph/go-diff/diff"
api "github.com/sourcegraph/sourcegraph/internal/api"
gitolite "github.com/sourcegraph/sourcegraph/internal/extsvc/gitolite"
gitdomain "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
@ -58,9 +57,6 @@ type MockClient struct {
// DiffFunc is an instance of a mock function object controlling the
// behavior of the method Diff.
DiffFunc *ClientDiffFunc
// DiffPathFunc is an instance of a mock function object controlling the
// behavior of the method DiffPath.
DiffPathFunc *ClientDiffPathFunc
// DiffSymbolsFunc is an instance of a mock function object controlling
// the behavior of the method DiffSymbols.
DiffSymbolsFunc *ClientDiffSymbolsFunc
@ -236,11 +232,6 @@ func NewMockClient() *MockClient {
return
},
},
DiffPathFunc: &ClientDiffPathFunc{
defaultHook: func(context.Context, api.RepoName, string, string, string) (r0 []*diff.Hunk, r1 error) {
return
},
},
DiffSymbolsFunc: &ClientDiffSymbolsFunc{
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) (r0 []byte, r1 error) {
return
@ -493,11 +484,6 @@ func NewStrictMockClient() *MockClient {
panic("unexpected invocation of MockClient.Diff")
},
},
DiffPathFunc: &ClientDiffPathFunc{
defaultHook: func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
panic("unexpected invocation of MockClient.DiffPath")
},
},
DiffSymbolsFunc: &ClientDiffSymbolsFunc{
defaultHook: func(context.Context, api.RepoName, api.CommitID, api.CommitID) ([]byte, error) {
panic("unexpected invocation of MockClient.DiffSymbols")
@ -728,9 +714,6 @@ func NewMockClientFrom(i Client) *MockClient {
DiffFunc: &ClientDiffFunc{
defaultHook: i.Diff,
},
DiffPathFunc: &ClientDiffPathFunc{
defaultHook: i.DiffPath,
},
DiffSymbolsFunc: &ClientDiffSymbolsFunc{
defaultHook: i.DiffSymbols,
},
@ -2055,122 +2038,6 @@ func (c ClientDiffFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
// ClientDiffPathFunc describes the behavior when the DiffPath method of the
// parent MockClient instance is invoked.
type ClientDiffPathFunc struct {
defaultHook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)
hooks []func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)
history []ClientDiffPathFuncCall
mutex sync.Mutex
}
// DiffPath delegates to the next hook function in the queue and stores the
// parameter and result values of this invocation.
func (m *MockClient) DiffPath(v0 context.Context, v1 api.RepoName, v2 string, v3 string, v4 string) ([]*diff.Hunk, error) {
r0, r1 := m.DiffPathFunc.nextHook()(v0, v1, v2, v3, v4)
m.DiffPathFunc.appendCall(ClientDiffPathFuncCall{v0, v1, v2, v3, v4, r0, r1})
return r0, r1
}
// SetDefaultHook sets function that is called when the DiffPath method of
// the parent MockClient instance is invoked and the hook queue is empty.
func (f *ClientDiffPathFunc) SetDefaultHook(hook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)) {
f.defaultHook = hook
}
// PushHook adds a function to the end of hook queue. Each invocation of the
// DiffPath method of the parent MockClient instance invokes the hook at the
// front of the queue and discards it. After the queue is empty, the default
// hook function is invoked for any future action.
func (f *ClientDiffPathFunc) PushHook(hook func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error)) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
}
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *ClientDiffPathFunc) SetDefaultReturn(r0 []*diff.Hunk, r1 error) {
f.SetDefaultHook(func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
return r0, r1
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *ClientDiffPathFunc) PushReturn(r0 []*diff.Hunk, r1 error) {
f.PushHook(func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
return r0, r1
})
}
func (f *ClientDiffPathFunc) nextHook() func(context.Context, api.RepoName, string, string, string) ([]*diff.Hunk, error) {
f.mutex.Lock()
defer f.mutex.Unlock()
if len(f.hooks) == 0 {
return f.defaultHook
}
hook := f.hooks[0]
f.hooks = f.hooks[1:]
return hook
}
func (f *ClientDiffPathFunc) appendCall(r0 ClientDiffPathFuncCall) {
f.mutex.Lock()
f.history = append(f.history, r0)
f.mutex.Unlock()
}
// History returns a sequence of ClientDiffPathFuncCall objects describing
// the invocations of this function.
func (f *ClientDiffPathFunc) History() []ClientDiffPathFuncCall {
f.mutex.Lock()
history := make([]ClientDiffPathFuncCall, len(f.history))
copy(history, f.history)
f.mutex.Unlock()
return history
}
// ClientDiffPathFuncCall is an object that describes an invocation of
// method DiffPath on an instance of MockClient.
type ClientDiffPathFuncCall struct {
// Arg0 is the value of the 1st argument passed to this method
// invocation.
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 api.RepoName
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 string
// Arg3 is the value of the 4th argument passed to this method
// invocation.
Arg3 string
// Arg4 is the value of the 5th argument passed to this method
// invocation.
Arg4 string
// Result0 is the value of the 1st result returned from this method
// invocation.
Result0 []*diff.Hunk
// Result1 is the value of the 2nd result returned from this method
// invocation.
Result1 error
}
// Args returns an interface slice containing the arguments of this
// invocation.
func (c ClientDiffPathFuncCall) Args() []interface{} {
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3, c.Arg4}
}
// Results returns an interface slice containing the results of this
// invocation.
func (c ClientDiffPathFuncCall) Results() []interface{} {
return []interface{}{c.Result0, c.Result1}
}
// ClientDiffSymbolsFunc describes the behavior when the DiffSymbols method
// of the parent MockClient instance is invoked.
type ClientDiffSymbolsFunc struct {

View File

@ -59,7 +59,6 @@ type operations struct {
lsFiles *observation.Operation
logReverseEach *observation.Operation
diffSymbols *observation.Operation
diffPath *observation.Operation
commitLog *observation.Operation
diff *observation.Operation
}
@ -156,7 +155,6 @@ func newOperations(observationCtx *observation.Context) *operations {
lsFiles: op("LsFiles"),
logReverseEach: op("LogReverseEach"),
diffSymbols: op("DiffSymbols"),
diffPath: op("DiffPath"),
commitLog: op("CommitLog"),
diff: op("Diff"),
}