Move GetDefaultBranch and GetDefaultBranchShort to gitserver client (#35804)

* Move GetDefaultBranch to gitserver client

fix mocks

* fix unit test
This commit is contained in:
Molly Weitzel 2022-05-23 17:40:04 +02:00 committed by GitHub
parent d7b228c66b
commit 404d5ed10d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 191 additions and 216 deletions

View File

@ -12,10 +12,10 @@ import (
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/errcode"
"github.com/sourcegraph/sourcegraph/internal/extsvc"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/repoupdater/protocol"
"github.com/sourcegraph/sourcegraph/internal/trace/ot"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/vcs/git"
)
// Repository returns the external links for a repository.
@ -43,7 +43,7 @@ func FileOrDir(ctx context.Context, db database.DB, repo *types.Repo, rev, path
phabRepo, link, serviceType := linksForRepository(ctx, db, repo)
if phabRepo != nil {
// We need a branch name to construct the Phabricator URL.
branchName, _, err := git.GetDefaultBranchShort(ctx, db, repo.Name)
branchName, _, err := gitserver.NewClient(db).GetDefaultBranchShort(ctx, repo.Name)
if err == nil && branchName != "" {
links = append(links, NewResolver(
fmt.Sprintf("%s/source/%s/browse/%s/%s;%s", strings.TrimSuffix(phabRepo.URL, "/"), phabRepo.Callsign, url.PathEscape(branchName), path, rev),

View File

@ -12,6 +12,7 @@ import (
"github.com/sourcegraph/sourcegraph/internal/extsvc"
"github.com/sourcegraph/sourcegraph/internal/extsvc/github"
"github.com/sourcegraph/sourcegraph/internal/extsvc/gitlab"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/vcs/git"
"github.com/sourcegraph/sourcegraph/lib/errors"
@ -164,7 +165,7 @@ func TestFileOrDir(t *testing.T) {
db := database.NewMockDB()
db.PhabricatorFunc.SetDefaultReturn(phabricator)
git.Mocks.GetDefaultBranchShort = func(repo api.RepoName) (refName string, commit api.CommitID, err error) {
gitserver.Mocks.GetDefaultBranchShort = func(repo api.RepoName) (refName string, commit api.CommitID, err error) {
return "mybranch", "", nil
}
defer git.ResetMocks()

View File

@ -23,7 +23,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/search/result"
"github.com/sourcegraph/sourcegraph/internal/trace/ot"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/vcs/git"
"github.com/sourcegraph/sourcegraph/lib/errors"
"github.com/sourcegraph/sourcegraph/schema"
)
@ -195,7 +194,7 @@ func (r *RepositoryResolver) CommitFromID(ctx context.Context, args *RepositoryC
func (r *RepositoryResolver) DefaultBranch(ctx context.Context) (*GitRefResolver, error) {
do := func() (*GitRefResolver, error) {
refName, _, err := git.GetDefaultBranch(ctx, r.db, r.RepoName())
refName, _, err := gitserver.NewClient(r.db).GetDefaultBranch(ctx, r.RepoName())
if err != nil {
return nil, err
}

View File

@ -18,7 +18,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/search/result"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/vcs/git"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -206,11 +205,11 @@ func TestRepository_DefaultBranch(t *testing.T) {
}
for _, tt := range ts {
t.Run(tt.name, func(t *testing.T) {
git.Mocks.ExecSafe = func(params []string) (stdout []byte, stderr []byte, exitCode int, err error) {
gitserver.Mocks.ExecSafe = func(params []string) (stdout []byte, stderr []byte, exitCode int, err error) {
return []byte(tt.symbolicRef), nil, tt.symbolicRefExitCode, tt.symbolicRefErr
}
t.Cleanup(func() {
git.Mocks.ExecSafe = nil
gitserver.Mocks.ExecSafe = nil
})
gitserver.Mocks.ResolveRevision = func(spec string, opt gitserver.ResolveRevisionOptions) (api.CommitID, error) {

View File

@ -46,7 +46,7 @@ func TestRetrievingAndDeduplicatingIndexedRefs(t *testing.T) {
}
return api.CommitID("deadbeef"), nil
}
git.Mocks.ExecSafe = func(params []string) (stdout, stderr []byte, exitCode int, err error) {
gitserver.Mocks.ExecSafe = func(params []string) (stdout, stderr []byte, exitCode int, err error) {
// Mock default branch lookup in (*RepsitoryResolver).DefaultBranch.
return []byte(defaultBranchRef), nil, 0, nil
}

View File

@ -10,6 +10,7 @@ import (
"github.com/sourcegraph/sourcegraph/cmd/frontend/backend"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
"github.com/sourcegraph/sourcegraph/internal/inventory"
"github.com/sourcegraph/sourcegraph/internal/search/job/jobutil"
@ -17,7 +18,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/search/result"
"github.com/sourcegraph/sourcegraph/internal/search/streaming"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/internal/vcs/git"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -131,7 +131,7 @@ func searchResultsStatsLanguages(ctx context.Context, db database.DB, matches []
defer run.Release()
repoName := repoMatch.RepoName()
_, oid, err := git.GetDefaultBranch(ctx, db, repoName.Name)
_, oid, err := gitserver.NewClient(db).GetDefaultBranch(ctx, repoName.Name)
if err != nil {
run.Error(err)
return

View File

@ -40,7 +40,7 @@ func TestSearchResultsStatsLanguages(t *testing.T) {
return io.NopCloser(bytes.NewReader(data)), nil
}
const wantDefaultBranchRef = "refs/heads/foo"
git.Mocks.ExecSafe = func(params []string) (stdout, stderr []byte, exitCode int, err error) {
gitserver.Mocks.ExecSafe = func(params []string) (stdout, stderr []byte, exitCode int, err error) {
// Mock default branch lookup in (*RepositoryResolver).DefaultBranch.
return []byte(wantDefaultBranchRef), nil, 0, nil
}

View File

@ -428,7 +428,7 @@ func repoToRepoRevisionWithDefaultBranch(ctx context.Context, db database.DB, re
tr.Finish()
}()
branch, commit, err := git.GetDefaultBranch(ctx, db, repo.Name)
branch, commit, err := gitserver.NewClient(db).GetDefaultBranch(ctx, repo.Name)
if err != nil {
return nil, err
}

View File

@ -451,13 +451,13 @@ type defaultBranch struct {
}
func mockDefaultBranches(t *testing.T, defaultBranches map[api.RepoName]defaultBranch) {
git.Mocks.GetDefaultBranch = func(repo api.RepoName) (refName string, commit api.CommitID, err error) {
gitserver.Mocks.GetDefaultBranch = func(repo api.RepoName) (refName string, commit api.CommitID, err error) {
if res, ok := defaultBranches[repo]; ok {
return res.branch, res.commit, nil
}
return "", "", &gitdomain.RepoNotExistError{Repo: repo}
}
t.Cleanup(func() { git.Mocks.GetDefaultBranch = nil })
t.Cleanup(func() { gitserver.Mocks.GetDefaultBranch = nil })
}
func mockBatchIgnores(t *testing.T, m map[api.CommitID]bool) {

View File

@ -1124,3 +1124,91 @@ func parseTags(in []byte) ([]*gitdomain.Tag, error) {
}
return tags, nil
}
// GetDefaultBranch returns the name of the default branch and the commit it's
// currently at from the given repository.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func (c *ClientImplementor) GetDefaultBranch(ctx context.Context, repo api.RepoName) (refName string, commit api.CommitID, err error) {
if Mocks.GetDefaultBranch != nil {
return Mocks.GetDefaultBranch(repo)
}
return c.getDefaultBranch(ctx, repo, false)
}
// GetDefaultBranchShort returns the short name of the default branch for the
// given repository and the commit it's currently at. A short name would return
// something like `main` instead of `refs/heads/main`.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func (c *ClientImplementor) GetDefaultBranchShort(ctx context.Context, repo api.RepoName) (refName string, commit api.CommitID, err error) {
if Mocks.GetDefaultBranchShort != nil {
return Mocks.GetDefaultBranchShort(repo)
}
return c.getDefaultBranch(ctx, repo, true)
}
// GetDefaultBranch returns the name of the default branch and the commit it's
// currently at from the given repository.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func (c *ClientImplementor) getDefaultBranch(ctx context.Context, repo api.RepoName, short bool) (refName string, commit api.CommitID, err error) {
args := []string{"symbolic-ref", "HEAD"}
if short {
args = append(args, "--short")
}
refBytes, _, exitCode, err := c.execSafe(ctx, repo, args)
refName = string(bytes.TrimSpace(refBytes))
if err == nil && exitCode == 0 {
// Check that our repo is not empty
commit, err = c.ResolveRevision(ctx, repo, "HEAD", ResolveRevisionOptions{NoEnsureRevision: true})
}
// If we fail to get the default branch due to cloning or being empty, we return nothing.
if err != nil {
if gitdomain.IsCloneInProgress(err) || errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
return "", "", nil
}
return "", "", err
}
return refName, commit, nil
}
// execSafe executes a Git subcommand iff it is allowed according to a allowlist.
//
// An error is only returned when there is a failure unrelated to the actual
// command being executed. If the executed command exits with a nonzero exit
// code, err == nil. This is similar to how http.Get returns a nil error for HTTP
// non-2xx responses.
//
// execSafe should NOT be exported. We want to limit direct git calls to this
// package.
func (c *ClientImplementor) execSafe(ctx context.Context, repo api.RepoName, params []string) (stdout, stderr []byte, exitCode int, err error) {
if Mocks.ExecSafe != nil {
return Mocks.ExecSafe(params)
}
span, ctx := ot.StartSpanFromContext(ctx, "Git: execSafe")
defer span.Finish()
if len(params) == 0 {
return nil, nil, 0, errors.New("at least one argument required")
}
if !gitdomain.IsAllowedGitCmd(params) {
return nil, nil, 0, errors.Errorf("command failed: %q is not a allowed git command", params)
}
cmd := c.GitCommand(repo, params...)
stdout, stderr, err = cmd.DividedOutput(ctx)
exitCode = cmd.ExitStatus()
if exitCode != 0 && err != nil {
err = nil // the error must just indicate that the exit code was nonzero
}
return stdout, stderr, exitCode, err
}

View File

@ -2,6 +2,7 @@ package gitserver
import (
"context"
"fmt"
"io"
"os"
"reflect"
@ -817,3 +818,77 @@ func TestParseTags_WithoutCreatorDate(t *testing.T) {
t.Fatal(diff)
}
}
func TestExecSafe(t *testing.T) {
ClientMocks.LocalGitserver = true
defer ResetClientMocks()
tests := []struct {
args []string
wantStdout, wantStderr string
wantExitCode int
wantError bool
}{
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?"},
wantStdout: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8 -\nauthor a\nauthor-date 2006-01-02 15:04:05 +0000\nparents \nsummary foo\n\nfilename ?\n",
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?", "-m", "-i", "-n200", "--author=a@a.com"},
wantStdout: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8 -\nauthor a\nauthor-date 2006-01-02 15:04:05 +0000\nparents \nsummary foo\n\nfilename ?\n",
},
{
args: []string{"show"},
wantStdout: "commit ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8\nAuthor: a <a@a.com>\nDate: Mon Jan 2 15:04:05 2006 +0000\n\n foo\n",
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?", ";show"},
wantStderr: "fatal: ambiguous argument ';show': unknown revision or path not in the working tree.\nUse '--' to separate paths from revisions, like this:\n'git <command> [<revision>...] -- [<file>...]'\n",
wantExitCode: 128,
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?;", "show"},
wantStderr: "fatal: ambiguous argument 'show': unknown revision or path not in the working tree.\nUse '--' to separate paths from revisions, like this:\n'git <command> [<revision>...] -- [<file>...]'\n",
wantExitCode: 128,
},
{
args: []string{"rm"},
wantError: true,
},
{
args: []string{"checkout"},
wantError: true,
},
{
args: []string{"show;", "echo", "hello"},
wantError: true,
},
}
repo := MakeGitRepository(t, "GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit --allow-empty -m foo --author='a <a@a.com>' --date 2006-01-02T15:04:05Z")
client := NewClient(database.NewMockDB())
for _, test := range tests {
t.Run(fmt.Sprint(test.args), func(t *testing.T) {
stdout, stderr, exitCode, err := client.execSafe(context.Background(), repo, test.args)
if err == nil && test.wantError {
t.Errorf("got error %v, want error %v", err, test.wantError)
}
if test.wantError {
return
}
if err != nil {
t.Fatal(err)
}
if string(stdout) != test.wantStdout {
t.Errorf("got stdout %q, want %q", stdout, test.wantStdout)
}
if string(stderr) != test.wantStderr {
t.Errorf("got stderr %q, want %q", stderr, test.wantStderr)
}
if exitCode != test.wantExitCode {
t.Errorf("got exitCode %d, want %d", exitCode, test.wantExitCode)
}
})
}
}

View File

@ -17,10 +17,13 @@ import (
// that's done, we should take advantage of the generated mock client in this
// package instead.
var Mocks, emptyMocks struct {
ExecReader func(args []string) (reader io.ReadCloser, err error)
ReadDir func(commit api.CommitID, name string, recurse bool) ([]fs.FileInfo, error)
ResolveRevision func(spec string, opt ResolveRevisionOptions) (api.CommitID, error)
LsFiles func(repo api.RepoName, commit api.CommitID) ([]string, error)
ExecReader func(args []string) (reader io.ReadCloser, err error)
ExecSafe func(params []string) (stdout, stderr []byte, exitCode int, err error)
ReadDir func(commit api.CommitID, name string, recurse bool) ([]fs.FileInfo, error)
ResolveRevision func(spec string, opt ResolveRevisionOptions) (api.CommitID, error)
LsFiles func(repo api.RepoName, commit api.CommitID) ([]string, error)
GetDefaultBranch func(repo api.RepoName) (refName string, commit api.CommitID, err error)
GetDefaultBranchShort func(repo api.RepoName) (refName string, commit api.CommitID, err error)
}
// ResetMocks clears the mock functions set on Mocks (so that subsequent tests don't inadvertently

View File

@ -1,66 +0,0 @@
package git
import (
"bytes"
"context"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
// GetDefaultBranch returns the name of the default branch and the commit it's
// currently at from the given repository.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func GetDefaultBranch(ctx context.Context, db database.DB, repo api.RepoName) (refName string, commit api.CommitID, err error) {
if Mocks.GetDefaultBranch != nil {
return Mocks.GetDefaultBranch(repo)
}
return getDefaultBranch(ctx, db, repo, false)
}
// GetDefaultBranchShort returns the short name of the default branch for the
// given repository and the commit it's currently at. A short name would return
// something like `main` instead of `refs/heads/main`.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func GetDefaultBranchShort(ctx context.Context, db database.DB, repo api.RepoName) (refName string, commit api.CommitID, err error) {
if Mocks.GetDefaultBranchShort != nil {
return Mocks.GetDefaultBranchShort(repo)
}
return getDefaultBranch(ctx, db, repo, true)
}
// GetDefaultBranch returns the name of the default branch and the commit it's
// currently at from the given repository.
//
// If the repository is empty or currently being cloned, empty values and no
// error are returned.
func getDefaultBranch(ctx context.Context, db database.DB, repo api.RepoName, short bool) (refName string, commit api.CommitID, err error) {
args := []string{"symbolic-ref", "HEAD"}
if short {
args = append(args, "--short")
}
refBytes, _, exitCode, err := execSafe(ctx, db, repo, args)
refName = string(bytes.TrimSpace(refBytes))
if err == nil && exitCode == 0 {
// Check that our repo is not empty
commit, err = gitserver.NewClient(db).ResolveRevision(ctx, repo, "HEAD", gitserver.ResolveRevisionOptions{NoEnsureRevision: true})
}
// If we fail to get the default branch due to cloning or being empty, we return nothing.
if err != nil {
if gitdomain.IsCloneInProgress(err) || errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
return "", "", nil
}
return "", "", err
}
return refName, commit, nil
}

View File

@ -1,51 +1,11 @@
package git
import (
"context"
"strings"
"github.com/sourcegraph/sourcegraph/internal/api"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain"
"github.com/sourcegraph/sourcegraph/internal/trace/ot"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
// execSafe executes a Git subcommand iff it is allowed according to a allowlist.
//
// An error is only returned when there is a failure unrelated to the actual
// command being executed. If the executed command exits with a nonzero exit
// code, err == nil. This is similar to how http.Get returns a nil error for HTTP
// non-2xx responses.
//
// execSafe should NOT be exported. We want to limit direct git calls to this
// package.
func execSafe(ctx context.Context, db database.DB, repo api.RepoName, params []string) (stdout, stderr []byte, exitCode int, err error) {
if Mocks.ExecSafe != nil {
return Mocks.ExecSafe(params)
}
span, ctx := ot.StartSpanFromContext(ctx, "Git: execSafe")
defer span.Finish()
if len(params) == 0 {
return nil, nil, 0, errors.New("at least one argument required")
}
if !gitdomain.IsAllowedGitCmd(params) {
return nil, nil, 0, errors.Errorf("command failed: %q is not a allowed git command", params)
}
cmd := gitserver.NewClient(db).GitCommand(repo, params...)
stdout, stderr, err = cmd.DividedOutput(ctx)
exitCode = cmd.ExitStatus()
if exitCode != 0 && err != nil {
err = nil // the error must just indicate that the exit code was nonzero
}
return stdout, stderr, exitCode, err
}
// checkSpecArgSafety returns a non-nil err if spec begins with a "-", which
// could cause it to be interpreted as a git command line argument.
func checkSpecArgSafety(spec string) error {

View File

@ -1,81 +0,0 @@
package git
import (
"context"
"fmt"
"testing"
"github.com/sourcegraph/sourcegraph/internal/database"
)
func TestExecSafe(t *testing.T) {
t.Parallel()
tests := []struct {
args []string
wantStdout, wantStderr string
wantExitCode int
wantError bool
}{
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?"},
wantStdout: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8 -\nauthor a\nauthor-date 2006-01-02 15:04:05 +0000\nparents \nsummary foo\n\nfilename ?\n",
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?", "-m", "-i", "-n200", "--author=a@a.com"},
wantStdout: "ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8 -\nauthor a\nauthor-date 2006-01-02 15:04:05 +0000\nparents \nsummary foo\n\nfilename ?\n",
},
{
args: []string{"show"},
wantStdout: "commit ea167fe3d76b1e5fd3ed8ca44cbd2fe3897684f8\nAuthor: a <a@a.com>\nDate: Mon Jan 2 15:04:05 2006 +0000\n\n foo\n",
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?", ";show"},
wantStderr: "fatal: ambiguous argument ';show': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'",
wantExitCode: 128,
},
{
args: []string{"log", "--name-status", "--full-history", "-M", "--date=iso8601", "--format=%H -%nauthor %an%nauthor-date %ai%nparents %P%nsummary %B%nfilename ?;", "show"},
wantStderr: "fatal: ambiguous argument 'show': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'",
wantExitCode: 128,
},
{
args: []string{"rm"},
wantError: true,
},
{
args: []string{"checkout"},
wantError: true,
},
{
args: []string{"show;", "echo", "hello"},
wantError: true,
},
}
repo := MakeGitRepository(t, "GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit --allow-empty -m foo --author='a <a@a.com>' --date 2006-01-02T15:04:05Z")
for _, test := range tests {
t.Run(fmt.Sprint(test.args), func(t *testing.T) {
stdout, stderr, exitCode, err := execSafe(context.Background(), database.NewMockDB(), repo, test.args)
if err == nil && test.wantError {
t.Errorf("got error %v, want error %v", err, test.wantError)
}
if test.wantError {
return
}
if err != nil {
t.Fatal(err)
}
if string(stdout) != test.wantStdout {
t.Errorf("got stdout %q, want %q", stdout, test.wantStdout)
}
if string(stderr) != test.wantStderr {
t.Errorf("got stderr %q, want %q", stderr, test.wantStderr)
}
if exitCode != test.wantExitCode {
t.Errorf("got exitCode %d, want %d", exitCode, test.wantExitCode)
}
})
}
}

View File

@ -13,16 +13,13 @@ import (
//
// (The emptyMocks is used by ResetMocks to zero out Mocks without needing to use a named type.)
var Mocks, emptyMocks struct {
GetCommit func(api.CommitID) (*gitdomain.Commit, error)
ExecSafe func(params []string) (stdout, stderr []byte, exitCode int, err error)
ExecReader func(args []string) (reader io.ReadCloser, err error)
NewFileReader func(commit api.CommitID, name string) (io.ReadCloser, error)
ReadFile func(commit api.CommitID, name string) ([]byte, error)
Stat func(commit api.CommitID, name string) (fs.FileInfo, error)
Commits func(repo api.RepoName, opt CommitsOptions) ([]*gitdomain.Commit, error)
MergeBase func(repo api.RepoName, a, b api.CommitID) (api.CommitID, error)
GetDefaultBranch func(repo api.RepoName) (refName string, commit api.CommitID, err error)
GetDefaultBranchShort func(repo api.RepoName) (refName string, commit api.CommitID, err error)
GetCommit func(api.CommitID) (*gitdomain.Commit, error)
ExecReader func(args []string) (reader io.ReadCloser, err error)
NewFileReader func(commit api.CommitID, name string) (io.ReadCloser, error)
ReadFile func(commit api.CommitID, name string) ([]byte, error)
Stat func(commit api.CommitID, name string) (fs.FileInfo, error)
Commits func(repo api.RepoName, opt CommitsOptions) ([]*gitdomain.Commit, error)
MergeBase func(repo api.RepoName, a, b api.CommitID) (api.CommitID, error)
}
// ResetMocks clears the mock functions set on Mocks (so that subsequent tests don't inadvertently