pm/available.go

95 lines
2.0 KiB
Go
Raw Normal View History

package pm
import (
2018-03-02 23:23:11 -08:00
"net/url"
2018-03-02 23:23:16 -08:00
"sort"
2018-03-02 23:23:11 -08:00
"github.com/pkg/errors"
)
// Name exists to document the keys in Available
type Name string
2018-03-02 23:23:21 -08:00
// Names is a slice of names ... with sorting!
2018-03-02 23:23:13 -08:00
type Names []Name
func (n Names) Len() int { return len(n) }
func (n Names) Swap(a, b int) { n[a], n[b] = n[b], n[a] }
func (n Names) Less(a, b int) bool { return n[a] < n[b] }
// Version exists to document the keys in Available
type Version string
2018-03-02 23:23:21 -08:00
// Versions is a slice of Version ... with sorting!
2018-03-02 23:23:13 -08:00
type Versions []Version
// TODO (sm): make this semver sort?
2018-03-03 22:21:58 -08:00
func (v Versions) Len() int { return len(v) }
func (v Versions) Swap(a, b int) { v[a], v[b] = v[b], v[a] }
func (v Versions) Less(a, b int) bool { return v[a] < v[b] }
// Available is the structure used to represent the collection of all packages
// that can be installed.
type Available map[Name]map[Version]Meta
// Add inserts m into a.
func (a Available) Add(m Meta) error {
if _, err := m.Valid(); err != nil {
return errors.Wrap(err, "invalid meta")
}
if _, ok := a[Name(m.Name)]; !ok {
a[m.Name] = map[Version]Meta{}
}
a[m.Name][m.Version] = m
return nil
}
// Update inserts all data from o into a.
func (a Available) Update(o Available) error {
for _, vers := range o {
for _, m := range vers {
if err := a.Add(m); err != nil {
return errors.Wrap(err, "adding")
}
}
}
return nil
}
2018-03-02 23:23:11 -08:00
2018-03-02 23:23:21 -08:00
// SetRemote adds the information in the url to the database.
2018-03-02 23:23:11 -08:00
func (a Available) SetRemote(u url.URL) {
for n, vers := range a {
2018-03-02 23:23:21 -08:00
for v := range vers {
2018-03-02 23:23:11 -08:00
m := a[n][v]
m.Remote = u
a[n][v] = m
}
}
}
2018-03-02 23:23:16 -08:00
2018-03-02 23:23:21 -08:00
// Traverse returns a chan of Meta that will be sanely sorted.
2018-03-02 23:23:16 -08:00
func (a Available) Traverse() <-chan Meta {
r := make(chan Meta)
go func() {
names := Names{}
nvs := map[Name]Versions{}
for n, vers := range a {
names = append(names, n)
for v := range vers {
nvs[n] = append(nvs[n], v)
}
sort.Sort(nvs[n])
}
sort.Sort(names)
for _, n := range names {
for _, v := range nvs[n] {
r <- a[n][v]
}
}
close(r)
}()
return r
}