Skip to content

Commit

Permalink
refactor: move all clone ops to the front of the line
Browse files Browse the repository at this point in the history
Run through the configs and populate/update the cache before doing
anything else.  This will deduplicate repos, as well as surfacing
any network issues early
  • Loading branch information
nisimond authored and retr0h committed Mar 6, 2024
1 parent 1f6b9ae commit 7503568
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
41 changes: 29 additions & 12 deletions internal/repositories/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func New(
repoManager: repoManager,
execManager: execManager,
logger: logger,
cloneCache: make(map[string]string),
}
}

Expand Down Expand Up @@ -72,22 +73,12 @@ func (r *Repositories) getCacheDir() (string, error) {

// Overlay clone and extract the Repository items.
func (r *Repositories) Overlay() error {
cacheDir, err := r.getCacheDir()
if err != nil {
r.logger.Error(
"error expanding dir",
slog.String("giltDir", r.config.GiltDir),
slog.String("cacheDir", cacheDir),
slog.String("err", err.Error()),
)
if err := r.populateCloneCache(); err != nil {
return err
}

for _, c := range r.config.Repositories {
targetDir, err := r.repoManager.Clone(c, cacheDir)
if err != nil {
return err
}
targetDir := r.cloneCache[c.Git]

// Easy mode: create a full worktree, directly in DstDir
if c.DstDir != "" {
Expand Down Expand Up @@ -138,3 +129,29 @@ func (r *Repositories) Overlay() error {

return nil
}

// populateCloneCache ensure that all named repos exist and are up-to-date
func (r *Repositories) populateCloneCache() error {
cacheDir, err := r.getCacheDir()
if err != nil {
r.logger.Error(
"error expanding dir",
slog.String("giltDir", r.config.GiltDir),
slog.String("cacheDir", cacheDir),
slog.String("err", err.Error()),
)
return err
}

for _, c := range r.config.Repositories {
if _, exists := r.cloneCache[c.Git]; exists {
continue
}
targetDir, err := r.repoManager.Clone(c, cacheDir)
if err != nil {
return err
}
r.cloneCache[c.Git] = targetDir
}
return nil
}
15 changes: 15 additions & 0 deletions internal/repositories/repositories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type RepositoriesTestSuite struct {

appFs avfs.VFS
giltDir string
gitURL string
logger *slog.Logger
}

Expand Down Expand Up @@ -75,6 +76,7 @@ func (suite *RepositoriesTestSuite) SetupTest() {

suite.appFs = memfs.New()
suite.giltDir = "/giltDir"
suite.gitURL = "https://example.com/user/repo.git"

suite.logger = slog.New(slog.NewTextHandler(os.Stdout, nil))
}
Expand Down Expand Up @@ -106,6 +108,19 @@ func (suite *RepositoriesTestSuite) TestgetCacheDirCannotCreateError() {
assert.Equal(suite.T(), "", got)
}

func (suite *RepositoriesTestSuite) TestPopulateCloneCacheDedupesCloneCalls() {
repos := suite.NewTestRepositories(suite.giltDir)
// The same repository, but two different versions
repos.config.Repositories = []config.Repository{
{Git: suite.gitURL, Version: "v1"},
{Git: suite.gitURL, Version: "v2"},
}
// .Times(1) is the default behavior, but let's be explicit
suite.mockRepo.EXPECT().Clone(gomock.Any(), gomock.Any()).Return(suite.giltDir, nil).Times(1)
err := repos.populateCloneCache()
assert.NoError(suite.T(), err)
}

// In order for `go test` to run this suite, we need to create
// a normal test function and pass our suite to suite.Run.
func TestRepositoriesTestSuite(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions internal/repositories/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ type Repositories struct {

repoManager internal.RepositoryManager
execManager internal.ExecManager

cloneCache map[string]string
}

0 comments on commit 7503568

Please sign in to comment.