122 lines
2.8 KiB
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
|
|
}
|