package gitpb // this is becoming a standard format // todo: autogenerate this from the .proto file? import ( "fmt" "os" "sort" sync "sync" ) // bad global lock until I figure out some other plan var repolock sync.RWMutex type RepoIterator struct { sync.RWMutex packs []*Repo index int } // NewRepoIterator initializes a new iterator. func NewRepoIterator(packs []*Repo) *RepoIterator { return &RepoIterator{packs: packs} } // Scan moves to the next element and returns false if there are no more packs. func (it *RepoIterator) Scan() bool { if it.index >= len(it.packs) { return false } it.index++ return true } // Repo returns the current repo. func (it *RepoIterator) Repo() *Repo { if it.packs[it.index-1] == nil { for i, d := range it.packs { fmt.Println("i =", i, d) } fmt.Println("len =", len(it.packs)) fmt.Println("repo == nil", it.index, it.index-1) os.Exit(-1) } return it.packs[it.index-1] } // Use Scan() in a loop, similar to a while loop // // for iterator.Scan() { // d := iterator.Repo() // fmt.Println("Repo UUID:", d.Uuid) // } func (r *Repos) All() *RepoIterator { repoPointers := r.selectAllRepo() iterator := NewRepoIterator(repoPointers) return iterator } func (r *Repos) SortByName() *RepoIterator { packs := r.selectAllRepo() sort.Sort(RepoByName(packs)) iterator := NewRepoIterator(packs) return iterator } // enforces no duplicate package names func (all *Repos) Append(newP *Repo) bool { repolock.Lock() defer repolock.Unlock() for _, p := range all.Repos { if p.GoPath == newP.GoPath { return false } } all.Repos = append(all.Repos, newP) return true } /* // returns time.Duration since last Update() func (r *Repo) LastPull() time.Duration { t := time.Since(r.LastPull.AsTime()) return t } */ // find a package by gopath func (all *Repos) FindByPath(gopath string) *Repo { repolock.RLock() defer repolock.RUnlock() for _, p := range all.Repos { if p.GoPath == gopath { return p } } return nil } func (all *Repos) Len() int { repolock.RLock() defer repolock.RUnlock() return len(all.Repos) } type RepoByName []*Repo func (a RepoByName) Len() int { return len(a) } func (a RepoByName) Less(i, j int) bool { return a[i].GoPath < a[j].GoPath } func (a RepoByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } // safely returns a slice of pointers to the Repo protobufs func (all *Repos) selectAllRepo() []*Repo { repolock.RLock() defer repolock.RUnlock() // Create a new slice to hold pointers to each Repo var aRepos []*Repo aRepos = make([]*Repo, len(all.Repos)) for i, p := range all.Repos { aRepos[i] = p // Copy pointers for safe iteration } return aRepos }