src.dualinventive.com/go/devsim/repository/git/bucket.go

122 lines
2.8 KiB
Go

package git
import (
"path/filepath"
"sync"
"src.dualinventive.com/go/devsim"
"src.dualinventive.com/go/devsim/repository"
"gopkg.in/src-d/go-git.v4/plumbing/transport"
)
// Bucket is a collection of GIT repositories
type Bucket struct {
mx sync.Mutex
authMethod transport.AuthMethod
baseRepositoryDir string
repositories []*Repository
}
// Static check
var _ repository.Bucket = &Bucket{}
// NewBucket creates a new GIT repository bucket. The repository uses authMethod for GIT authorization.
// The repository is cloned in the baseRepositoryDir.
func NewBucket(authMethod transport.AuthMethod, baseRepositoryDir string) *Bucket {
return &Bucket{
authMethod: authMethod,
baseRepositoryDir: baseRepositoryDir,
}
}
// Add adds the URI to the repository bucket
func (g *Bucket) Add(uri string) error {
// The base dir for the repository is our base dir plus the uri of the repository.
dir := filepath.Join(g.baseRepositoryDir, sanitizePathString(uri))
r, err := newRepository(uri, dir, g.authMethod)
if err != nil {
return err
}
return g.add(r)
}
// add adds the repository to the bucket
func (g *Bucket) add(repo *Repository) error {
g.mx.Lock()
defer g.mx.Unlock()
uri := repo.URI()
if g.find(uri) != nil {
return devsim.ErrAlreadyExists
}
g.repositories = append(g.repositories, repo)
return nil
}
// Remove removes the URI from the repository bucket
func (g *Bucket) Remove(uri string) error {
g.mx.Lock()
defer g.mx.Unlock()
index, err := g.findIndex(uri)
if err != nil {
return err
}
g.repositories = append(g.repositories[:index], g.repositories[index+1:]...)
return nil
}
// Poll polls all the repositories in the repository bucket.
func (g *Bucket) Poll() []error {
errs := make([]error, 0)
for _, r := range g.List() {
if err := r.Poll(); err != nil {
errs = append(errs, err)
}
}
return errs
}
// Find finds the repository using the URI
func (g *Bucket) Find(URI string) (repository.Repository, error) {
g.mx.Lock()
defer g.mx.Unlock()
s := g.find(URI)
if s == nil {
return nil, devsim.ErrNotFound
}
return s, nil
}
// findIndex returns the index of the repository. This is not thread safe.
func (g *Bucket) findIndex(uri string) (int, error) {
for i := range g.repositories {
if g.repositories[i].URI() == uri {
return i, nil
}
}
return 0, devsim.ErrNotFound
}
// find returns the repository or nil when the repository is not found.
func (g *Bucket) find(uri string) *Repository {
for i := range g.repositories {
if g.repositories[i].URI() == uri {
return g.repositories[i]
}
}
return nil
}
// List returns all the repositories in the repository bucket.
func (g *Bucket) List() []repository.Repository {
g.mx.Lock()
tmp := make([]repository.Repository, len(g.repositories))
for i, repository := range g.repositories {
tmp[i] = repository
}
g.mx.Unlock()
return tmp
}