Chore: clean up RepositoryResolver, part II (#59405)

This does a few things to further clean up RepositoryResolver:

- It splits NewMinimalRepositoryResolver out of NewRepositoryResolver to make it more obvious when we're creating a fully-resolved RepositoryResolver and a lazy RepositoryResolver. It's pretty error prone to pass in a *types.Repo with only the Name and ID fields set.
- It moves the always-available fields ID and Name directly onto the struct to make it more clear that those are safe to use directly
- It refactors the lazy hydration to the more standard sync.Once pattern
- It changes a bunch of call sites to use api.RepoName instead of *types.Repo when a fully-resolved repo is not actually needed (removing a few DB calls in the process)
This commit is contained in:
Camden Cheek 2024-01-09 10:17:06 -07:00 committed by GitHub
parent b4e59e55b0
commit 341998d874
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 209 additions and 203 deletions

View File

@ -632,7 +632,7 @@ func NewMockReposService() *MockReposService {
},
},
GetInventoryFunc: &ReposServiceGetInventoryFunc{
defaultHook: func(context.Context, *types.Repo, api.CommitID, bool) (r0 *inventory.Inventory, r1 error) {
defaultHook: func(context.Context, api.RepoName, api.CommitID, bool) (r0 *inventory.Inventory, r1 error) {
return
},
},
@ -652,7 +652,7 @@ func NewMockReposService() *MockReposService {
},
},
ResolveRevFunc: &ReposServiceResolveRevFunc{
defaultHook: func(context.Context, *types.Repo, string) (r0 api.CommitID, r1 error) {
defaultHook: func(context.Context, api.RepoName, string) (r0 api.CommitID, r1 error) {
return
},
},
@ -679,7 +679,7 @@ func NewStrictMockReposService() *MockReposService {
},
},
GetInventoryFunc: &ReposServiceGetInventoryFunc{
defaultHook: func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error) {
defaultHook: func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error) {
panic("unexpected invocation of MockReposService.GetInventory")
},
},
@ -699,7 +699,7 @@ func NewStrictMockReposService() *MockReposService {
},
},
ResolveRevFunc: &ReposServiceResolveRevFunc{
defaultHook: func(context.Context, *types.Repo, string) (api.CommitID, error) {
defaultHook: func(context.Context, api.RepoName, string) (api.CommitID, error) {
panic("unexpected invocation of MockReposService.ResolveRev")
},
},
@ -1065,15 +1065,15 @@ func (c ReposServiceGetByNameFuncCall) Results() []interface{} {
// ReposServiceGetInventoryFunc describes the behavior when the GetInventory
// method of the parent MockReposService instance is invoked.
type ReposServiceGetInventoryFunc struct {
defaultHook func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error)
hooks []func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error)
defaultHook func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error)
hooks []func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error)
history []ReposServiceGetInventoryFuncCall
mutex sync.Mutex
}
// GetInventory delegates to the next hook function in the queue and stores
// the parameter and result values of this invocation.
func (m *MockReposService) GetInventory(v0 context.Context, v1 *types.Repo, v2 api.CommitID, v3 bool) (*inventory.Inventory, error) {
func (m *MockReposService) GetInventory(v0 context.Context, v1 api.RepoName, v2 api.CommitID, v3 bool) (*inventory.Inventory, error) {
r0, r1 := m.GetInventoryFunc.nextHook()(v0, v1, v2, v3)
m.GetInventoryFunc.appendCall(ReposServiceGetInventoryFuncCall{v0, v1, v2, v3, r0, r1})
return r0, r1
@ -1082,7 +1082,7 @@ func (m *MockReposService) GetInventory(v0 context.Context, v1 *types.Repo, v2 a
// SetDefaultHook sets function that is called when the GetInventory method
// of the parent MockReposService instance is invoked and the hook queue is
// empty.
func (f *ReposServiceGetInventoryFunc) SetDefaultHook(hook func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error)) {
func (f *ReposServiceGetInventoryFunc) SetDefaultHook(hook func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error)) {
f.defaultHook = hook
}
@ -1090,7 +1090,7 @@ func (f *ReposServiceGetInventoryFunc) SetDefaultHook(hook func(context.Context,
// GetInventory method of the parent MockReposService 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 *ReposServiceGetInventoryFunc) PushHook(hook func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error)) {
func (f *ReposServiceGetInventoryFunc) PushHook(hook func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error)) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -1099,19 +1099,19 @@ func (f *ReposServiceGetInventoryFunc) PushHook(hook func(context.Context, *type
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *ReposServiceGetInventoryFunc) SetDefaultReturn(r0 *inventory.Inventory, r1 error) {
f.SetDefaultHook(func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error) {
f.SetDefaultHook(func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error) {
return r0, r1
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *ReposServiceGetInventoryFunc) PushReturn(r0 *inventory.Inventory, r1 error) {
f.PushHook(func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error) {
f.PushHook(func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error) {
return r0, r1
})
}
func (f *ReposServiceGetInventoryFunc) nextHook() func(context.Context, *types.Repo, api.CommitID, bool) (*inventory.Inventory, error) {
func (f *ReposServiceGetInventoryFunc) nextHook() func(context.Context, api.RepoName, api.CommitID, bool) (*inventory.Inventory, error) {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -1149,7 +1149,7 @@ type ReposServiceGetInventoryFuncCall struct {
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 *types.Repo
Arg1 api.RepoName
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 api.CommitID
@ -1499,15 +1499,15 @@ func (c ReposServiceRequestRepositoryCloneFuncCall) Results() []interface{} {
// ReposServiceResolveRevFunc describes the behavior when the ResolveRev
// method of the parent MockReposService instance is invoked.
type ReposServiceResolveRevFunc struct {
defaultHook func(context.Context, *types.Repo, string) (api.CommitID, error)
hooks []func(context.Context, *types.Repo, string) (api.CommitID, error)
defaultHook func(context.Context, api.RepoName, string) (api.CommitID, error)
hooks []func(context.Context, api.RepoName, string) (api.CommitID, error)
history []ReposServiceResolveRevFuncCall
mutex sync.Mutex
}
// ResolveRev delegates to the next hook function in the queue and stores
// the parameter and result values of this invocation.
func (m *MockReposService) ResolveRev(v0 context.Context, v1 *types.Repo, v2 string) (api.CommitID, error) {
func (m *MockReposService) ResolveRev(v0 context.Context, v1 api.RepoName, v2 string) (api.CommitID, error) {
r0, r1 := m.ResolveRevFunc.nextHook()(v0, v1, v2)
m.ResolveRevFunc.appendCall(ReposServiceResolveRevFuncCall{v0, v1, v2, r0, r1})
return r0, r1
@ -1516,7 +1516,7 @@ func (m *MockReposService) ResolveRev(v0 context.Context, v1 *types.Repo, v2 str
// SetDefaultHook sets function that is called when the ResolveRev method of
// the parent MockReposService instance is invoked and the hook queue is
// empty.
func (f *ReposServiceResolveRevFunc) SetDefaultHook(hook func(context.Context, *types.Repo, string) (api.CommitID, error)) {
func (f *ReposServiceResolveRevFunc) SetDefaultHook(hook func(context.Context, api.RepoName, string) (api.CommitID, error)) {
f.defaultHook = hook
}
@ -1524,7 +1524,7 @@ func (f *ReposServiceResolveRevFunc) SetDefaultHook(hook func(context.Context, *
// ResolveRev method of the parent MockReposService 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 *ReposServiceResolveRevFunc) PushHook(hook func(context.Context, *types.Repo, string) (api.CommitID, error)) {
func (f *ReposServiceResolveRevFunc) PushHook(hook func(context.Context, api.RepoName, string) (api.CommitID, error)) {
f.mutex.Lock()
f.hooks = append(f.hooks, hook)
f.mutex.Unlock()
@ -1533,19 +1533,19 @@ func (f *ReposServiceResolveRevFunc) PushHook(hook func(context.Context, *types.
// SetDefaultReturn calls SetDefaultHook with a function that returns the
// given values.
func (f *ReposServiceResolveRevFunc) SetDefaultReturn(r0 api.CommitID, r1 error) {
f.SetDefaultHook(func(context.Context, *types.Repo, string) (api.CommitID, error) {
f.SetDefaultHook(func(context.Context, api.RepoName, string) (api.CommitID, error) {
return r0, r1
})
}
// PushReturn calls PushHook with a function that returns the given values.
func (f *ReposServiceResolveRevFunc) PushReturn(r0 api.CommitID, r1 error) {
f.PushHook(func(context.Context, *types.Repo, string) (api.CommitID, error) {
f.PushHook(func(context.Context, api.RepoName, string) (api.CommitID, error) {
return r0, r1
})
}
func (f *ReposServiceResolveRevFunc) nextHook() func(context.Context, *types.Repo, string) (api.CommitID, error) {
func (f *ReposServiceResolveRevFunc) nextHook() func(context.Context, api.RepoName, string) (api.CommitID, error) {
f.mutex.Lock()
defer f.mutex.Unlock()
@ -1583,7 +1583,7 @@ type ReposServiceResolveRevFuncCall struct {
Arg0 context.Context
// Arg1 is the value of the 2nd argument passed to this method
// invocation.
Arg1 *types.Repo
Arg1 api.RepoName
// Arg2 is the value of the 3rd argument passed to this method
// invocation.
Arg2 string

View File

@ -33,10 +33,10 @@ type ReposService interface {
GetByName(ctx context.Context, name api.RepoName) (*types.Repo, error)
List(ctx context.Context, opt database.ReposListOptions) ([]*types.Repo, error)
ListIndexable(ctx context.Context) ([]types.MinimalRepo, error)
GetInventory(ctx context.Context, repo *types.Repo, commitID api.CommitID, forceEnhancedLanguageDetection bool) (*inventory.Inventory, error)
GetInventory(ctx context.Context, repoName api.RepoName, commitID api.CommitID, forceEnhancedLanguageDetection bool) (*inventory.Inventory, error)
DeleteRepositoryFromDisk(ctx context.Context, repoID api.RepoID) error
RequestRepositoryClone(ctx context.Context, repoID api.RepoID) error
ResolveRev(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error)
ResolveRev(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error)
}
// NewRepos uses the provided `database.DB` to initialize a new RepoService.
@ -250,24 +250,24 @@ func (s *repos) ListIndexable(ctx context.Context) (repos []types.MinimalRepo, e
})
}
func (s *repos) GetInventory(ctx context.Context, repo *types.Repo, commitID api.CommitID, forceEnhancedLanguageDetection bool) (res *inventory.Inventory, err error) {
func (s *repos) GetInventory(ctx context.Context, repo api.RepoName, commitID api.CommitID, forceEnhancedLanguageDetection bool) (res *inventory.Inventory, err error) {
if Mocks.Repos.GetInventory != nil {
return Mocks.Repos.GetInventory(ctx, repo, commitID)
}
ctx, done := startTrace(ctx, "GetInventory", map[string]any{"repo": repo.Name, "commitID": commitID}, &err)
ctx, done := startTrace(ctx, "GetInventory", map[string]any{"repo": repo, "commitID": commitID}, &err)
defer done()
// Cap GetInventory operation to some reasonable time.
ctx, cancel := context.WithTimeout(ctx, 3*time.Minute)
defer cancel()
invCtx, err := InventoryContext(s.logger, repo.Name, s.gitserverClient, commitID, forceEnhancedLanguageDetection)
invCtx, err := InventoryContext(s.logger, repo, s.gitserverClient, commitID, forceEnhancedLanguageDetection)
if err != nil {
return nil, err
}
root, err := s.gitserverClient.Stat(ctx, repo.Name, commitID, "")
root, err := s.gitserverClient.Stat(ctx, repo, commitID, "")
if err != nil {
return nil, err
}
@ -328,15 +328,15 @@ func (s *repos) RequestRepositoryClone(ctx context.Context, repoID api.RepoID) (
// * Empty repository: gitdomain.RevisionNotFoundError
// * The user does not have permission: errcode.IsNotFound
// * Other unexpected errors.
func (s *repos) ResolveRev(ctx context.Context, repo *types.Repo, rev string) (commitID api.CommitID, err error) {
func (s *repos) ResolveRev(ctx context.Context, repo api.RepoName, rev string) (commitID api.CommitID, err error) {
if Mocks.Repos.ResolveRev != nil {
return Mocks.Repos.ResolveRev(ctx, repo, rev)
}
ctx, done := startTrace(ctx, "ResolveRev", map[string]any{"repo": repo.Name, "rev": rev}, &err)
ctx, done := startTrace(ctx, "ResolveRev", map[string]any{"repo": repo, "rev": rev}, &err)
defer done()
return s.gitserverClient.ResolveRevision(ctx, repo.Name, rev, gitserver.ResolveRevisionOptions{})
return s.gitserverClient.ResolveRevision(ctx, repo, rev, gitserver.ResolveRevisionOptions{})
}
// ErrRepoSeeOther indicates that the repo does not exist on this server but might exist on an external Sourcegraph

View File

@ -17,8 +17,8 @@ type MockRepos struct {
Get func(v0 context.Context, id api.RepoID) (*types.Repo, error)
GetByName func(v0 context.Context, name api.RepoName) (*types.Repo, error)
List func(v0 context.Context, v1 database.ReposListOptions) ([]*types.Repo, error)
ResolveRev func(v0 context.Context, repo *types.Repo, rev string) (api.CommitID, error)
GetInventory func(v0 context.Context, repo *types.Repo, commitID api.CommitID) (*inventory.Inventory, error)
ResolveRev func(v0 context.Context, repo api.RepoName, rev string) (api.CommitID, error)
GetInventory func(v0 context.Context, repo api.RepoName, commitID api.CommitID) (*inventory.Inventory, error)
DeleteRepositoryFromDisk func(v0 context.Context, name api.RepoID) error
}
@ -91,7 +91,7 @@ func (s *MockRepos) MockDeleteRepositoryFromDisk(t *testing.T, wantRepo api.Repo
func (s *MockRepos) MockResolveRev_NoCheck(t *testing.T, commitID api.CommitID) (called *bool) {
var once sync.Once
called = new(bool)
s.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
s.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
once.Do(func() {
*called = true
})
@ -100,17 +100,17 @@ func (s *MockRepos) MockResolveRev_NoCheck(t *testing.T, commitID api.CommitID)
return
}
func (s *MockRepos) MockResolveRev_NotFound(t *testing.T, wantRepo api.RepoID, wantRev string) (called *bool) {
func (s *MockRepos) MockResolveRev_NotFound(t *testing.T, wantRepo api.RepoName, wantRev string) (called *bool) {
called = new(bool)
s.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
s.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
*called = true
if repo.ID != wantRepo {
t.Errorf("got repo %v, want %v", repo.ID, wantRepo)
if repo != wantRepo {
t.Errorf("got repo %v, want %v", repo, wantRepo)
}
if rev != wantRev {
t.Errorf("got rev %v, want %v", rev, wantRev)
}
return "", &gitdomain.RevisionNotFoundError{Repo: repo.Name, Spec: rev}
return "", &gitdomain.RevisionNotFoundError{Repo: repo, Spec: rev}
}
return
}

View File

@ -155,16 +155,16 @@ func TestReposGetInventory(t *testing.T) {
ctx := testContext()
const (
wantRepo = "a"
wantRepoName = "a"
wantCommitID = "cccccccccccccccccccccccccccccccccccccccc"
wantRootOID = "oid-root"
)
gitserverClient := gitserver.NewMockClient()
repoupdater.MockRepoLookup = func(args protocol.RepoLookupArgs) (*protocol.RepoLookupResult, error) {
if args.Repo != wantRepo {
t.Errorf("got %q, want %q", args.Repo, wantRepo)
if args.Repo != wantRepoName {
t.Errorf("got %q, want %q", args.Repo, wantRepoName)
}
return &protocol.RepoLookupResult{Repo: &protocol.RepoInfo{Name: wantRepo}}, nil
return &protocol.RepoLookupResult{Repo: &protocol.RepoInfo{Name: wantRepoName}}, nil
}
defer func() { repoupdater.MockRepoLookup = nil }()
gitserverClient.StatFunc.SetDefaultHook(func(_ context.Context, _ api.RepoName, commit api.CommitID, path string) (fs.FileInfo, error) {
@ -239,7 +239,7 @@ func TestReposGetInventory(t *testing.T) {
useEnhancedLanguageDetection = test.useEnhancedLanguageDetection
defer func() { useEnhancedLanguageDetection = orig }() // reset
inv, err := s.GetInventory(ctx, &types.Repo{Name: wantRepo}, wantCommitID, false)
inv, err := s.GetInventory(ctx, wantRepoName, wantCommitID, false)
if err != nil {
t.Fatal(err)
}

View File

@ -12,7 +12,6 @@ import (
"github.com/sourcegraph/sourcegraph/internal/gitserver"
"github.com/sourcegraph/sourcegraph/internal/repoupdater"
"github.com/sourcegraph/sourcegraph/internal/repoupdater/protocol"
"github.com/sourcegraph/sourcegraph/internal/types"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -42,7 +41,7 @@ func TestRepos_ResolveRev_noRevSpecified_getsDefaultBranch(t *testing.T) {
})
// (no rev/branch specified)
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, &types.Repo{Name: "a"}, "")
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, "a", "")
if err != nil {
t.Fatal(err)
}
@ -82,7 +81,7 @@ func TestRepos_ResolveRev_noCommitIDSpecified_resolvesRev(t *testing.T) {
return api.CommitID(want), nil
})
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, &types.Repo{Name: "a"}, "b")
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, "a", "b")
if err != nil {
t.Fatal(err)
}
@ -122,7 +121,7 @@ func TestRepos_ResolveRev_commitIDSpecified_resolvesCommitID(t *testing.T) {
return api.CommitID(want), nil
})
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, &types.Repo{Name: "a"}, strings.Repeat("a", 40))
commitID, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, "a", strings.Repeat("a", 40))
if err != nil {
t.Fatal(err)
}
@ -162,7 +161,7 @@ func TestRepos_ResolveRev_commitIDSpecified_failsToResolve(t *testing.T) {
return "", errors.New("x")
})
_, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, &types.Repo{Name: "a"}, strings.Repeat("a", 40))
_, err := NewRepos(logger, dbmocks.NewMockDB(), client).ResolveRev(ctx, "a", strings.Repeat("a", 40))
if !errors.Is(err, want) {
t.Fatalf("got err %v, want %v", err, want)
}

View File

@ -26,7 +26,7 @@ func (r *CommitSearchResultResolver) Commit() *GitCommitResolver {
return
}
gitserverClient := gitserver.NewClient("graphql.search.commitresult")
repoResolver := NewRepositoryResolver(r.db, gitserverClient, r.Repo.ToRepo())
repoResolver := NewMinimalRepositoryResolver(r.db, gitserverClient, r.Repo.ID, r.Repo.Name)
r.gitCommitResolver = NewGitCommitResolver(r.db, gitserverClient, repoResolver, r.CommitMatch.Commit.ID, &r.CommitMatch.Commit)
})
return r.gitCommitResolver

View File

@ -215,7 +215,7 @@ func (r *GitCommitResolver) CanonicalURL() string {
}
func (r *GitCommitResolver) ExternalURLs(ctx context.Context) ([]*externallink.Resolver, error) {
repo, err := r.repoResolver.repo(ctx)
repo, err := r.repoResolver.getRepo(ctx)
if err != nil {
return nil, err
}
@ -316,12 +316,7 @@ func (r *GitCommitResolver) FileNames(ctx context.Context) ([]string, error) {
}
func (r *GitCommitResolver) Languages(ctx context.Context) ([]string, error) {
repo, err := r.repoResolver.repo(ctx)
if err != nil {
return nil, err
}
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, repo, api.CommitID(r.oid), false)
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, r.repoResolver.RepoName(), api.CommitID(r.oid), false)
if err != nil {
return nil, err
}
@ -334,12 +329,7 @@ func (r *GitCommitResolver) Languages(ctx context.Context) ([]string, error) {
}
func (r *GitCommitResolver) LanguageStatistics(ctx context.Context) ([]*languageStatisticsResolver, error) {
repo, err := r.repoResolver.repo(ctx)
if err != nil {
return nil, err
}
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, repo, api.CommitID(r.oid), false)
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, r.repoResolver.RepoName(), api.CommitID(r.oid), false)
if err != nil {
return nil, err
}

View File

@ -276,14 +276,13 @@ func TestGitCommitFileNames(t *testing.T) {
externalServices.ListFunc.SetDefaultReturn(nil, nil)
repos := dbmocks.NewMockRepoStore()
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: 2, Name: "github.com/gorilla/mux"}, nil)
repos.GetByNameFunc.SetDefaultReturn(&types.Repo{ID: 2, Name: "github.com/gorilla/mux"}, nil)
db := dbmocks.NewMockDB()
db.ExternalServicesFunc.SetDefaultReturn(externalServices)
db.ReposFunc.SetDefaultReturn(repos)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoID(2), repo.ID)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
assert.Equal(t, exampleCommitSHA1, rev)
return exampleCommitSHA1, nil
}
@ -326,7 +325,7 @@ func TestGitCommitAncestors(t *testing.T) {
db := dbmocks.NewMockDB()
db.ReposFunc.SetDefaultReturn(repos)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return api.CommitID(rev), nil
}
@ -657,7 +656,7 @@ func TestGitCommitPerforceChangelist(t *testing.T) {
db := dbmocks.NewMockDB()
db.ReposFunc.SetDefaultReturn(repos)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return api.CommitID(rev), nil
}

View File

@ -381,7 +381,7 @@ func (r *GitTreeEntryResolver) urlPath(prefix *url.URL) *url.URL {
func (r *GitTreeEntryResolver) IsDirectory() bool { return r.stat.Mode().IsDir() }
func (r *GitTreeEntryResolver) ExternalURLs(ctx context.Context) ([]*externallink.Resolver, error) {
repo, err := r.commit.repoResolver.repo(ctx)
repo, err := r.commit.repoResolver.getRepo(ctx)
if err != nil {
return nil, err
}
@ -439,7 +439,7 @@ func (r *GitTreeEntryResolver) LSIF(ctx context.Context, args *struct{ ToolName
toolName = *args.ToolName
}
repo, err := r.commit.repoResolver.repo(ctx)
repo, err := r.commit.repoResolver.getRepo(ctx)
if err != nil {
return nil, err
}
@ -454,7 +454,7 @@ func (r *GitTreeEntryResolver) LSIF(ctx context.Context, args *struct{ ToolName
}
func (r *GitTreeEntryResolver) LocalCodeIntel(ctx context.Context) (*JSONValue, error) {
repo, err := r.commit.repoResolver.repo(ctx)
repo, err := r.commit.repoResolver.getRepo(ctx)
if err != nil {
return nil, err
}
@ -481,7 +481,7 @@ func (r *GitTreeEntryResolver) SymbolInfo(ctx context.Context, args *symbolInfoA
return nil, errors.New("expected arguments to symbolInfo")
}
repo, err := r.commit.repoResolver.repo(ctx)
repo, err := r.commit.repoResolver.getRepo(ctx)
if err != nil {
return nil, err
}

View File

@ -506,8 +506,8 @@ func testGitTree(t *testing.T, db *dbmocks.MockDB, tests []*Test) {
db.ExternalServicesFunc.SetDefaultReturn(externalServices)
db.ReposFunc.SetDefaultReturn(repos)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoID(2), repo.ID)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoName("github.com/gorilla/mux"), repo)
assert.Equal(t, exampleCommitSHA1, rev)
return exampleCommitSHA1, nil
}

View File

@ -94,17 +94,11 @@ func (r *PerforceChangelistResolver) cidURL() *url.URL {
func (r *PerforceChangelistResolver) Commit(ctx context.Context) (_ *GitCommitResolver, err error) {
repoResolver := r.repositoryResolver
r.commitOnce.Do(func() {
repo, err := repoResolver.repo(ctx)
if err != nil {
r.commitErr = err
return
}
r.commitID, r.commitErr = backend.NewRepos(
r.logger,
repoResolver.db,
repoResolver.gitserverClient,
).ResolveRev(ctx, repo, r.commitSHA)
).ResolveRev(ctx, repoResolver.name, r.commitSHA)
})
if r.commitErr != nil {

View File

@ -38,22 +38,48 @@ type RepositoryResolver struct {
id api.RepoID
name api.RepoName
logger log.Logger
hydration sync.Once
innerRepo *types.Repo
err error
db database.DB
gitserverClient gitserver.Client
logger log.Logger
// Fields below this line should not be used directly.
// Use the get* methods instead.
repoOnce sync.Once
repo *types.Repo
repoErr error
defaultBranchOnce sync.Once
defaultBranch *GitRefResolver
defaultBranchErr error
}
func NewRepositoryResolver(db database.DB, client gitserver.Client, repo *types.Repo) *RepositoryResolver {
// NewMinimalRepositoryResolver creates a new lazy resolver from the minimum necessary information: repo name and repo ID.
// If you have a fully resolved *types.Repo, use NewRepositoryResolver instead.
func NewMinimalRepositoryResolver(db database.DB, client gitserver.Client, id api.RepoID, name api.RepoName) *RepositoryResolver {
return &RepositoryResolver{
id: id,
name: name,
db: db,
gitserverClient: client,
logger: log.Scoped("repositoryResolver").
With(log.Object("repo",
log.String("name", string(name)),
log.Int32("id", int32(id)))),
}
}
// NewRepositoryResolver creates a repository resolver from a fully resolved *types.Repo. Do not use this
// function with an incomplete *types.Repo. Instead, use NewMinimalRepositoryResolver, which will lazily
// fetch the *types.Repo if needed.
func NewRepositoryResolver(db database.DB, gs gitserver.Client, repo *types.Repo) *RepositoryResolver {
// Protect against a nil repo
//
// TODO(@camdencheek): this shouldn't be necessary because it doesn't
// make sense to construct a repository resolver from a nil repo,
// but this was historically allowed, so tests fail without this.
// We should do an audit of callsites to fix places where this could
// be called with a nil repo.
var id api.RepoID
var name api.RepoName
if repo != nil {
@ -65,12 +91,12 @@ func NewRepositoryResolver(db database.DB, client gitserver.Client, repo *types.
id: id,
name: name,
db: db,
innerRepo: repo,
gitserverClient: client,
gitserverClient: gs,
logger: log.Scoped("repositoryResolver").
With(log.Object("repo",
log.String("name", string(name)),
log.Int32("id", int32(id)))),
repo: repo,
}
}
@ -126,9 +152,21 @@ func UnmarshalRepositoryIDs(ids []graphql.ID) ([]api.RepoID, error) {
}
// repo makes sure the repo is hydrated before returning it.
func (r *RepositoryResolver) repo(ctx context.Context) (*types.Repo, error) {
err := r.hydrate(ctx)
return r.innerRepo, err
func (r *RepositoryResolver) getRepo(ctx context.Context) (*types.Repo, error) {
r.repoOnce.Do(func() {
// Repositories with an empty creation date were created using RepoName.ToRepo(),
// they only contain ID and name information.
//
// TODO(@camdencheek): We _shouldn't_ need to inspect the CreatedAt date,
// but the API NewRepositoryResolver previously allowed passing in a *types.Repo
// with only the Name and ID fields populated.
if r.repo != nil && !r.repo.CreatedAt.IsZero() {
return
}
r.logger.Debug("RepositoryResolver.hydrate", log.String("repo.ID", string(r.IDInt32())))
r.repo, r.repoErr = r.db.Repos().Get(ctx, r.id)
})
return r.repo, r.repoErr
}
func (r *RepositoryResolver) RepoName() api.RepoName {
@ -140,32 +178,47 @@ func (r *RepositoryResolver) Name() string {
}
func (r *RepositoryResolver) ExternalRepo(ctx context.Context) (*api.ExternalRepoSpec, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
return &repo.ExternalRepo, err
}
func (r *RepositoryResolver) IsFork(ctx context.Context) (bool, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return false, err
}
return repo.Fork, err
}
func (r *RepositoryResolver) IsArchived(ctx context.Context) (bool, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return false, err
}
return repo.Archived, err
}
func (r *RepositoryResolver) IsPrivate(ctx context.Context) (bool, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return false, err
}
return repo.Private, err
}
func (r *RepositoryResolver) URI(ctx context.Context) (string, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return "", err
}
return repo.URI, err
}
func (r *RepositoryResolver) SourceType(ctx context.Context) (*SourceType, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to retrieve innerRepo")
}
@ -178,7 +231,10 @@ func (r *RepositoryResolver) SourceType(ctx context.Context) (*SourceType, error
}
func (r *RepositoryResolver) Description(ctx context.Context) (string, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return "", err
}
return repo.Description, err
}
@ -237,12 +293,7 @@ func (r *RepositoryResolver) Commit(ctx context.Context, args *RepositoryCommitA
attribute.String("commit", args.Rev))
defer tr.EndWithErr(&err)
repo, err := r.repo(ctx)
if err != nil {
return nil, err
}
commitID, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).ResolveRev(ctx, repo, args.Rev)
commitID, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).ResolveRev(ctx, r.name, args.Rev)
if err != nil {
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
return nil, nil
@ -284,7 +335,7 @@ func (r *RepositoryResolver) Changelist(ctx context.Context, args *RepositoryCha
return nil, nil
}
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
@ -308,7 +359,7 @@ func (r *RepositoryResolver) FirstEverCommit(ctx context.Context) (_ *GitCommitR
tr, ctx := trace.New(ctx, "RepositoryResolver.FirstEverCommit")
defer tr.EndWithErr(&err)
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
@ -356,18 +407,18 @@ func (r *RepositoryResolver) Language(ctx context.Context) (string, error) {
// Note: the repository database field is no longer updated as of
// https://github.com/sourcegraph/sourcegraph/issues/2586, so we do not use it anymore and
// instead compute the language on the fly.
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return "", err
}
commitID, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).ResolveRev(ctx, repo, "")
commitID, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).ResolveRev(ctx, r.name, "")
if err != nil {
// Comment: Should we return a nil error?
return "", err
}
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, repo, commitID, false)
inventory, err := backend.NewRepos(r.logger, r.db, r.gitserverClient).GetInventory(ctx, repo.Name, commitID, false)
if err != nil {
return "", err
}
@ -389,11 +440,13 @@ func (r *RepositoryResolver) CreatedAt() gqlutil.DateTime {
}
func (r *RepositoryResolver) RawCreatedAt() string {
if r.innerRepo == nil {
// TODO(@camdencheek): this represents a race condition between
// the sync.Once that populates r.repo and any callers of this method.
// The risk is small, so I'm not worrying about it right now.
if r.repo == nil {
return ""
}
return r.innerRepo.CreatedAt.Format(time.RFC3339)
return r.repo.CreatedAt.Format(time.RFC3339)
}
func (r *RepositoryResolver) UpdatedAt() *gqlutil.DateTime {
@ -409,7 +462,7 @@ func (r *RepositoryResolver) url() *url.URL {
}
func (r *RepositoryResolver) ExternalURLs(ctx context.Context) ([]*externallink.Resolver, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
@ -435,12 +488,8 @@ func (r *RepositoryResolver) ToCommitSearchResult() (*CommitSearchResultResolver
return nil, false
}
func (r *RepositoryResolver) Type(ctx context.Context) (*types.Repo, error) {
return r.repo(ctx)
}
func (r *RepositoryResolver) Stars(ctx context.Context) (int32, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return 0, err
}
@ -453,7 +502,7 @@ func (r *RepositoryResolver) KeyValuePairs(ctx context.Context) ([]KeyValuePair,
}
func (r *RepositoryResolver) Metadata(ctx context.Context) ([]KeyValuePair, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
@ -466,7 +515,7 @@ func (r *RepositoryResolver) Metadata(ctx context.Context) ([]KeyValuePair, erro
}
func (r *RepositoryResolver) Topics(ctx context.Context) ([]string, error) {
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}
@ -474,26 +523,6 @@ func (r *RepositoryResolver) Topics(ctx context.Context) ([]string, error) {
return repo.Topics, nil
}
func (r *RepositoryResolver) hydrate(ctx context.Context) error {
r.hydration.Do(func() {
// Repositories with an empty creation date were created using RepoName.ToRepo(),
// they only contain ID and name information.
if r.innerRepo != nil && !r.innerRepo.CreatedAt.IsZero() {
return
}
r.logger.Debug("RepositoryResolver.hydrate", log.String("repo.ID", string(r.IDInt32())))
var repo *types.Repo
repo, r.err = r.db.Repos().Get(ctx, r.IDInt32())
if r.err == nil {
r.innerRepo = repo
}
})
return r.err
}
func (r *RepositoryResolver) IndexConfiguration(ctx context.Context) (resolverstubs.IndexConfigurationResolver, error) {
return EnterpriseResolvers.codeIntelResolver.IndexConfiguration(ctx, r.ID())
}

View File

@ -18,14 +18,14 @@ type externalRepositoryResolver struct {
}
func (r *externalRepositoryResolver) ID(ctx context.Context) (string, error) {
repo, err := r.repository.repo(ctx)
repo, err := r.repository.getRepo(ctx)
if err != nil {
return "", err
}
return repo.ExternalRepo.ID, nil
}
func (r *externalRepositoryResolver) ServiceType(ctx context.Context) (string, error) {
repo, err := r.repository.repo(ctx)
repo, err := r.repository.getRepo(ctx)
if err != nil {
return "", err
}
@ -34,7 +34,7 @@ func (r *externalRepositoryResolver) ServiceType(ctx context.Context) (string, e
}
func (r *externalRepositoryResolver) ServiceID(ctx context.Context) (string, error) {
repo, err := r.repository.repo(ctx)
repo, err := r.repository.getRepo(ctx)
if err != nil {
return "", err
}
@ -50,7 +50,7 @@ func (r *RepositoryResolver) ExternalServices(ctx context.Context, args *struct
return nil, err
}
repo, err := r.repo(ctx)
repo, err := r.getRepo(ctx)
if err != nil {
return nil, err
}

View File

@ -91,7 +91,7 @@ func (r *repositoryMirrorInfoResolver) RemoteURL(ctx context.Context) (string, e
return strings.Replace(strings.Replace(u.String(), "fake://", "", 1), "/", ":", 1)
}
repo, err := r.repository.repo(ctx)
repo, err := r.repository.getRepo(ctx)
if err != nil {
return "", err
}
@ -159,7 +159,7 @@ func (r *repositoryMirrorInfoResolver) LastError(ctx context.Context) (*string,
}
func (r *repositoryMirrorInfoResolver) LastSyncOutput(ctx context.Context) (*string, error) {
output, ok, err := r.db.GitserverRepos().GetLastSyncOutput(ctx, r.repository.innerRepo.Name)
output, ok, err := r.db.GitserverRepos().GetLastSyncOutput(ctx, r.repository.name)
if err != nil {
return nil, err
}

View File

@ -26,8 +26,7 @@ import (
const exampleCommitSHA1 = "1234567890123456789012345678901234567890"
func TestRepository_Commit(t *testing.T) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoID(2), repo.ID)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
assert.Equal(t, "abc", rev)
return exampleCommitSHA1, nil
}
@ -68,8 +67,8 @@ func TestRepository_Commit(t *testing.T) {
func TestRepository_Changelist(t *testing.T) {
repo := &types.Repo{ID: 2, Name: "github.com/gorilla/mux"}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoID(2), repo.ID)
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
assert.Equal(t, api.RepoName("github.com/gorilla/mux"), repo)
return exampleCommitSHA1, nil
}

View File

@ -83,7 +83,7 @@ func (c *SearchResultsResolver) repositoryResolvers(ctx context.Context, ids []a
err := c.db.Repos().StreamMinimalRepos(ctx, database.ReposListOptions{
IDs: ids,
}, func(repo *types.MinimalRepo) {
resolvers = append(resolvers, NewRepositoryResolver(c.db, gsClient, repo.ToRepo()))
resolvers = append(resolvers, NewMinimalRepositoryResolver(c.db, gsClient, repo.ID, repo.Name))
})
if err != nil {
return nil, err
@ -134,7 +134,7 @@ func matchesToResolvers(db database.DB, matches []result.Match) []SearchResultRe
if existing, ok := repoResolvers[repoName]; ok {
return existing
}
resolver := NewRepositoryResolver(db, gsClient, repoName.ToRepo())
resolver := NewMinimalRepositoryResolver(db, gsClient, repoName.ID, repoName.Name)
repoResolvers[repoName] = resolver
return resolver
}

View File

@ -128,12 +128,12 @@ func searchResultsStatsLanguages(ctx context.Context, logger log.Logger, db data
} else if repoMatch, ok := res.(*result.RepoMatch); ok && !hasNonRepoMatches {
sawRepo(repoMatch.RepoName())
p.Go(func() error {
repoName := repoMatch.RepoName()
_, oid, err := gsClient.GetDefaultBranch(ctx, repoName.Name, false)
repoName := repoMatch.Name
_, oid, err := gsClient.GetDefaultBranch(ctx, repoName, false)
if err != nil {
return err
}
inv, err := backend.NewRepos(logger, db, gsClient).GetInventory(ctx, repoName.ToRepo(), oid, true)
inv, err := backend.NewRepos(logger, db, gsClient).GetInventory(ctx, repoName, oid, true)
if err != nil {
return err
}

View File

@ -42,11 +42,11 @@ func editorRev(ctx context.Context, logger log.Logger, db database.DB, repoName
// If we are on the default branch we want to return a clean URL without a
// branch. If we fail its best to return the full URL and allow the
// front-end to inform them of anything that is wrong.
defaultBranchCommitID, err := repos.ResolveRev(ctx, repo, "")
defaultBranchCommitID, err := repos.ResolveRev(ctx, repo.Name, "")
if err != nil {
return "@" + rev
}
branchCommitID, err := repos.ResolveRev(ctx, repo, rev)
branchCommitID, err := repos.ResolveRev(ctx, repo.Name, rev)
if err != nil {
return "@" + rev
}

View File

@ -18,7 +18,7 @@ import (
func TestEditorRev(t *testing.T) {
repoName := api.RepoName("myRepo")
logger := logtest.Scoped(t)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, _ *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, _ api.RepoName, rev string) (api.CommitID, error) {
if rev == "branch" {
return api.CommitID(strings.Repeat("b", 40)), nil
}

View File

@ -169,7 +169,7 @@ func TestNewCommon_repo_error(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
backend.Mocks.Repos.MockGetByName(t, api.RepoName(tt.name), 1)
backend.Mocks.Repos.MockGet(t, 1)
backend.Mocks.Repos.ResolveRev = func(context.Context, *types.Repo, string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(context.Context, api.RepoName, string) (api.CommitID, error) {
if tt.err != nil {
return "", tt.err
}

View File

@ -176,7 +176,7 @@ func mockBackendCommits(t *testing.T, revs ...api.CommitID) {
byRev[r] = struct{}{}
}
backend.Mocks.Repos.ResolveRev = func(_ context.Context, _ *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, _ api.RepoName, rev string) (api.CommitID, error) {
if _, ok := byRev[api.CommitID(rev)]; !ok {
t.Fatalf("ResolveRev received unexpected rev: %q", rev)
}

View File

@ -192,7 +192,7 @@ func toResultResolverList(ctx context.Context, cmd compute.Command, matches []re
if existing, ok := repoResolvers[repoName]; ok {
return existing
}
resolver := gql.NewRepositoryResolver(db, gitserverClient, repoName.ToRepo())
resolver := gql.NewMinimalRepositoryResolver(db, gitserverClient, repoName.ID, repoName.Name)
repoResolvers[repoName] = resolver
return resolver
}

View File

@ -69,10 +69,7 @@ func (r *Resolver) GetCodyContext(ctx context.Context, args graphqlbackend.GetCo
}
func (r *Resolver) fileChunkToResolver(ctx context.Context, chunk *codycontext.FileChunkContext) (graphqlbackend.ContextResultResolver, error) {
repoResolver := graphqlbackend.NewRepositoryResolver(r.db, r.gitserverClient, &types.Repo{
ID: chunk.RepoID,
Name: chunk.RepoName,
})
repoResolver := graphqlbackend.NewMinimalRepositoryResolver(r.db, r.gitserverClient, chunk.RepoID, chunk.RepoName)
commitResolver := graphqlbackend.NewGitCommitResolver(r.db, r.gitserverClient, repoResolver, chunk.CommitID, nil)
stat, err := r.gitserverClient.Stat(ctx, chunk.RepoName, chunk.CommitID, chunk.Path)

View File

@ -42,7 +42,7 @@ func getRepoRev(ctx context.Context, logger log.Logger, db database.DB, vars map
if err != nil {
return repoID, "", err
}
commitID, err := backend.NewRepos(logger, db, gsClient).ResolveRev(ctx, repo, repoRev.Rev)
commitID, err := backend.NewRepos(logger, db, gsClient).ResolveRev(ctx, repo.Name, repoRev.Rev)
if err != nil {
return repoID, "", err
}

View File

@ -45,8 +45,8 @@ func TestRepoShield(t *testing.T) {
panic("wrong path")
}
}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
if repo.ID != 2 || rev != "master" {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if repo != "github.com/gorilla/mux" || rev != "master" {
t.Error("wrong arguments to ResolveRev")
}
return "aed", nil

View File

@ -417,7 +417,7 @@ func (f *fakeRepoStore) List(_ context.Context, opts database.ReposListOptions)
for _, r := range f.Repos {
for _, id := range opts.IDs {
if id == r.ID {
repos = append(repos, r.ToRepo())
repos = append(repos, &types.Repo{ID: r.ID, Name: r.Name, Stars: r.Stars})
}
}
}

View File

@ -101,14 +101,14 @@ func TestStreamBlame(t *testing.T) {
backend.Mocks.Repos.Get = func(ctx context.Context, repo api.RepoID) (*types.Repo, error) {
return &types.Repo{Name: "github.com/bob/foo"}, nil
}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
switch rev {
case "1234":
return "efgh", nil
case "":
return "abcd", nil
default:
return "", &gitdomain.RevisionNotFoundError{Repo: repo.Name}
return "", &gitdomain.RevisionNotFoundError{Repo: repo}
}
}
usersStore := dbmocks.NewMockUserStore()

View File

@ -171,7 +171,7 @@ func TestBlobOwnershipPanelQueryPersonUnresolved(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
git := fakeGitserver{}
@ -288,7 +288,7 @@ func TestBlobOwnershipPanelQueryIngested(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
git := fakeGitserver{}
@ -386,7 +386,7 @@ func TestBlobOwnershipPanelQueryTeamResolved(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(repo, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if rev != parameterRevision {
return "", errors.Newf("ResolveRev, got %q want %q", rev, parameterRevision)
}
@ -473,7 +473,7 @@ func TestBlobOwnershipPanelQueryExternalTeamResolved(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(repo, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if rev != parameterRevision {
return "", errors.Newf("ResolveRev, got %q want %q", rev, parameterRevision)
}
@ -696,7 +696,7 @@ func TestOwnershipPagination(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "42", nil
}
git := fakeGitserver{}
@ -813,7 +813,7 @@ func TestOwnership_WithSignals(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
git := fakeGitserver{}
@ -986,7 +986,7 @@ func TestTreeOwnershipSignals(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
git := fakeGitserver{
@ -1181,7 +1181,7 @@ func TestCommitOwnershipSignals(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
git := fakeGitserver{}
@ -1460,7 +1460,7 @@ func TestOwnership_WithAssignedOwnersAndTeams(t *testing.T) {
repos := dbmocks.NewMockRepoStore()
db.ReposFunc.SetDefaultReturn(repos)
repos.GetFunc.SetDefaultReturn(&types.Repo{ID: repoID, Name: "github.com/sourcegraph/own"}, nil)
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(_ context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
return "deadbeef", nil
}
db.UserExternalAccountsFunc.SetDefaultReturn(dbmocks.NewMockUserExternalAccountsStore())

View File

@ -500,7 +500,12 @@ func (r *searchContextResolver) Repositories(ctx context.Context) ([]graphqlback
searchContextRepositories := make([]graphqlbackend.SearchContextRepositoryRevisionsResolver, len(repoRevs))
for idx, repoRev := range repoRevs {
searchContextRepositories[idx] = &searchContextRepositoryRevisionsResolver{graphqlbackend.NewRepositoryResolver(r.db, gitserver.NewClient("graphql.searchcontext.repositories"), repoRev.Repo.ToRepo()), repoRev.Revisions}
searchContextRepositories[idx] = &searchContextRepositoryRevisionsResolver{graphqlbackend.NewMinimalRepositoryResolver(
r.db,
gitserver.NewClient("graphql.searchcontext.repositories"),
repoRev.Repo.ID,
repoRev.Repo.Name,
), repoRev.Revisions}
}
return searchContextRepositories, nil
}

View File

@ -414,7 +414,7 @@ func setupRepoMocks(t *testing.T) {
return &types.Repo{ID: repoID}, nil
}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if rev != "deadbeef" {
t.Errorf("unexpected commit. want=%s have=%s", "deadbeef", rev)
}

View File

@ -89,7 +89,7 @@ func ensureRepoAndCommitExist(ctx context.Context, repoStore RepoStore, repoName
//
// 2. Resolve commit
if _, err := repoStore.ResolveRev(ctx, repo, commit); err != nil {
if _, err := repoStore.ResolveRev(ctx, repo.Name, commit); err != nil {
var reason string
if errors.HasType(err, &gitdomain.RevisionNotFoundError{}) {
reason = "commit not found"

View File

@ -146,7 +146,7 @@ func setupRepoMocks(t testing.TB) {
return &types.Repo{ID: 50}, nil
}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if rev != testCommit {
t.Errorf("unexpected commit. want=%s have=%s", testCommit, rev)
}

View File

@ -9,5 +9,5 @@ import (
type RepoStore interface {
GetByName(ctx context.Context, name api.RepoName) (*types.Repo, error)
ResolveRev(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error)
ResolveRev(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error)
}

View File

@ -276,12 +276,12 @@ func TestResolverIterator(t *testing.T) {
db := database.NewDB(logger, dbtest.NewDB(t))
for i := 1; i <= 5; i++ {
r := types.MinimalRepo{
r := &types.Repo{
Name: api.RepoName(fmt.Sprintf("github.com/foo/bar%d", i)),
Stars: i * 100,
}
if err := db.Repos().Create(ctx, r.ToRepo()); err != nil {
if err := db.Repos().Create(ctx, r); err != nil {
t.Fatal(err)
}
}
@ -435,18 +435,20 @@ func TestResolverIterateRepoRevs(t *testing.T) {
var all []RepoRevSpecs
for i := 1; i <= 5; i++ {
r := types.MinimalRepo{
r := &types.Repo{
Name: api.RepoName(fmt.Sprintf("github.com/foo/bar%d", i)),
Stars: i * 100,
}
repo := r.ToRepo()
if err := db.Repos().Create(ctx, repo); err != nil {
if err := db.Repos().Create(ctx, r); err != nil {
t.Fatal(err)
}
r.ID = repo.ID
all = append(all, RepoRevSpecs{Repo: r})
all = append(all, RepoRevSpecs{Repo: types.MinimalRepo{
ID: r.ID,
Name: r.Name,
Stars: r.Stars,
}})
}
withRevSpecs := func(rrs []RepoRevSpecs, revs ...query.RevisionSpecifier) []RepoRevSpecs {

View File

@ -528,14 +528,6 @@ type MinimalRepo struct {
Stars int
}
func (r *MinimalRepo) ToRepo() *Repo {
return &Repo{
ID: r.ID,
Name: r.Name,
Stars: r.Stars,
}
}
// MinimalRepos is an utility type with convenience methods for operating on lists of repo names
type MinimalRepos []MinimalRepo

View File

@ -457,7 +457,7 @@ func setupRepoMocks(t testing.TB) {
return &types.Repo{ID: 50}, nil
}
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo *types.Repo, rev string) (api.CommitID, error) {
backend.Mocks.Repos.ResolveRev = func(ctx context.Context, repo api.RepoName, rev string) (api.CommitID, error) {
if rev != testCommit {
t.Errorf("unexpected commit. want=%s have=%s", testCommit, rev)
}