Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Implement logic to clone git remotes only once #5804

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions api/internal/git/cloner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@
package git

import (
"sync"

"sigs.k8s.io/kustomize/kyaml/filesys"
)

// Cloner is a function that can clone a git repo.
type Cloner func(repoSpec *RepoSpec) error

var (
clones = make(map[string]filesys.ConfirmedDir)
cloneCount = make(map[filesys.ConfirmedDir]uint16)
cloneMutex sync.Mutex
)

// ClonerUsingGitExec uses a local git install, as opposed
// to say, some remote API, to obtain a local clone of
// a remote repo.
func ClonerUsingGitExec(repoSpec *RepoSpec) error {
if dir, found := clones[repoSpec.Raw()]; found {
repoSpec.Dir = dir
cloneCount[dir] += 1
return nil
}

cloneMutex.Lock()
defer cloneMutex.Unlock()

r, err := newCmdRunner(repoSpec.Timeout)
if err != nil {
return err
}
repoSpec.Dir = r.dir
cloneCount[r.dir] = 1
if err = r.run("init"); err != nil {
return err
}
Expand All @@ -41,6 +59,10 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
if repoSpec.Submodules {
return r.run("submodule", "update", "--init", "--recursive")
}

// save the location of the clone for later reuse
clones[repoSpec.Raw()] = r.dir

return nil
}

Expand All @@ -54,3 +76,16 @@ func DoNothingCloner(dir filesys.ConfirmedDir) Cloner {
return nil
}
}

// DecrementCloneCount decrements the count of repoSpecs using a directory clone.
func DecrementCloneCount(dir filesys.ConfirmedDir) uint16 {
cloneMutex.Lock()
defer cloneMutex.Unlock()

if count, exists := cloneCount[dir]; exists && count > 0 {
cloneCount[dir] -= 1
return cloneCount[dir]
}

return 0
}
7 changes: 6 additions & 1 deletion api/internal/git/repospec.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ func (x *RepoSpec) AbsPath() string {
}

func (x *RepoSpec) Cleaner(fSys filesys.FileSystem) func() error {
return func() error { return fSys.RemoveAll(x.Dir.String()) }
return func() error {
if DecrementCloneCount(x.Dir) == 0 {
return fSys.RemoveAll(x.Dir.String())
}
return nil
}
}

const (
Expand Down