gitforgefs/git/client.go

90 lines
1.9 KiB
Go
Raw Normal View History

2020-12-29 02:37:18 +00:00
package git
import (
"errors"
2020-12-29 02:37:18 +00:00
"net/url"
"os"
"path/filepath"
"strconv"
2020-12-29 02:37:18 +00:00
)
2021-03-03 05:24:27 +00:00
const (
CloneInit = iota
CloneClone = iota
)
type GitClonerPuller interface {
CloneOrPull(url string, pid int, defaultBranch string) (localRepoLoc string, err error)
}
2020-12-29 02:37:18 +00:00
type GitClientParam struct {
2021-03-03 05:24:27 +00:00
CloneLocation string
RemoteName string
RemoteURL *url.URL
CloneMethod int
PullDepth int
AutoPull bool
CloneBuffSize int
CloneWorkerCount int
PullBuffSize int
PullWorkerCount int
2020-12-29 02:37:18 +00:00
}
type gitClient struct {
GitClientParam
cloneChan chan *gitCloneParam
pullChan chan *gitPullParam
2020-12-29 02:37:18 +00:00
}
func NewClient(p GitClientParam) (*gitClient, error) {
// Create the client
c := &gitClient{
GitClientParam: p,
cloneChan: make(chan *gitCloneParam, p.CloneBuffSize),
pullChan: make(chan *gitPullParam, p.PullBuffSize),
2020-12-29 02:37:18 +00:00
}
// Start worker goroutines
for i := 0; i < p.CloneWorkerCount; i++ {
go c.cloneWorker()
}
for i := 0; i < p.PullWorkerCount; i++ {
go c.pullWorker()
2020-12-29 02:37:18 +00:00
}
return c, nil
}
func (c *gitClient) getLocalRepoLoc(pid int) string {
return filepath.Join(c.CloneLocation, c.RemoteURL.Hostname(), strconv.Itoa(pid))
}
func (c *gitClient) CloneOrPull(url string, pid int, defaultBranch string) (localRepoLoc string, err error) {
localRepoLoc = c.getLocalRepoLoc(pid)
// TODO: Better manage concurrency, filter out duplicate requests
if _, err := os.Stat(localRepoLoc); os.IsNotExist(err) {
// Dispatch to clone worker
select {
case c.cloneChan <- &gitCloneParam{
url: url,
defaultBranch: defaultBranch,
dst: localRepoLoc,
}:
default:
return localRepoLoc, errors.New("failed to clone local repo")
}
} else if c.AutoPull {
// Dispatch to pull worker
select {
case c.pullChan <- &gitPullParam{
repoPath: localRepoLoc,
defaultBranch: defaultBranch,
}:
default:
return localRepoLoc, errors.New("failed to pull local repo")
}
}
return localRepoLoc, nil
}