Adds pm pull

This commit is contained in:
Stephen McQuay 2018-03-02 23:23:11 -08:00
parent 2a0220cddc
commit 74d360f6d7
Signed by: sm
GPG Key ID: 4E4B72F479BA3CE5
5 changed files with 90 additions and 8 deletions

View File

@ -1,6 +1,8 @@
package pm package pm
import ( import (
"net/url"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -38,3 +40,13 @@ func (a Available) Update(o Available) error {
} }
return nil return nil
} }
func (a Available) SetRemote(u url.URL) {
for n, vers := range a {
for v, _ := range vers {
m := a[n][v]
m.Remote = u
a[n][v] = m
}
}
}

View File

@ -2,6 +2,7 @@ package pm
import ( import (
"errors" "errors"
"net/url"
"testing" "testing"
) )
@ -92,4 +93,13 @@ func TestAvailableUpdate(t *testing.T) {
if got, want := a["a"]["v1.0.0"].Description, "test last in"; got != want { if got, want := a["a"]["v1.0.0"].Description, "test last in"; got != want {
t.Fatalf("last in didn't override") t.Fatalf("last in didn't override")
} }
u, err := url.Parse("https://pm.mcquay.me/darwin/amd64")
if err != nil {
t.Fatalf("parsing url: %v", err)
}
a.SetRemote(*u)
if got, want := a["a"]["v1.0.0"].Remote, *u; got != want {
t.Fatalf("last in didn't override")
}
} }

View File

@ -1,6 +1,9 @@
package pm package pm
import "errors" import (
"errors"
"net/url"
)
// Meta tracks metadata for a package // Meta tracks metadata for a package
type Meta struct { type Meta struct {
@ -8,6 +11,8 @@ type Meta struct {
Version Version `json:"version"` Version Version `json:"version"`
Description string `json:"description"` Description string `json:"description"`
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
Remote url.URL `json:"remote"`
} }
// Valid validates the contents of a Meta for requires fields. // Valid validates the contents of a Meta for requires fields.

View File

@ -1,8 +1,63 @@
package remote package remote
import "github.com/pkg/errors" import (
"encoding/json"
"net/http"
"os"
"path/filepath"
"github.com/pkg/errors"
"mcquay.me/pm"
)
const an = "var/lib/pm/available.json"
// Pull updates the available package database. // Pull updates the available package database.
func Pull(root string) error { func Pull(root string) error {
return errors.New("NYI") db, err := load(root)
if err != nil {
return errors.Wrap(err, "loading db")
}
o := pm.Available{}
// Order here is important: the guarantee made is that any packages that
// exist in multiple remotes will be fetched by the first configured
// remote, which is why we traverse the database in reverse.
//
// TODO (sm): make this concurrent
for i := range db {
u := db[len(db)-i-1]
resp, err := http.Get(u.String() + "/available.json")
if err != nil {
return errors.Wrap(err, "http get")
}
a := pm.Available{}
if err := json.NewDecoder(resp.Body).Decode(&a); err != nil {
return errors.Wrap(err, "decode remote available")
}
a.SetRemote(u)
o.Update(a)
}
if err := saveAvailable(root, o); err != nil {
return errors.Wrap(err, "saving available db")
}
return nil
}
func saveAvailable(root string, db pm.Available) error {
f, err := os.Create(filepath.Join(root, an))
if err != nil {
return errors.Wrap(err, "create")
}
enc := json.NewEncoder(f)
enc.SetIndent("", "\t")
if err := enc.Encode(&db); err != nil {
return errors.Wrap(err, "decoding db")
}
if err := f.Close(); err != nil {
return errors.Wrap(err, "close db")
}
return nil
} }

View File

@ -15,7 +15,7 @@ import (
// DB is a slice of available URI // DB is a slice of available URI
type DB []url.URL type DB []url.URL
const fn = "var/lib/pm/available.json" const rn = "var/lib/pm/remotes.json"
// Add appends the provided uri to the list of configured remotes. // Add appends the provided uri to the list of configured remotes.
func Add(root string, uris []string) error { func Add(root string, uris []string) error {
@ -93,13 +93,13 @@ func List(root string, w io.Writer) error {
func load(root string) (DB, error) { func load(root string) (DB, error) {
r := DB{} r := DB{}
dbn := filepath.Join(root, fn) dbn := filepath.Join(root, rn)
if !fs.Exists(dbn) { if !fs.Exists(dbn) {
return r, nil return r, nil
} }
f, err := os.Open(filepath.Join(root, fn)) f, err := os.Open(filepath.Join(root, rn))
if err != nil { if err != nil {
return r, errors.Wrap(err, "open") return r, errors.Wrap(err, "open")
} }
@ -112,7 +112,7 @@ func load(root string) (DB, error) {
} }
func save(root string, db DB) error { func save(root string, db DB) error {
f, err := os.Create(filepath.Join(root, fn)) f, err := os.Create(filepath.Join(root, rn))
if err != nil { if err != nil {
return errors.Wrap(err, "create") return errors.Wrap(err, "create")
} }
@ -140,7 +140,7 @@ func strip(u url.URL) url.URL {
} }
func mkdirs(root string) error { func mkdirs(root string) error {
d, _ := filepath.Split(filepath.Join(root, fn)) d, _ := filepath.Split(filepath.Join(root, rn))
if !fs.Exists(d) { if !fs.Exists(d) {
if err := os.MkdirAll(d, 0700); err != nil { if err := os.MkdirAll(d, 0700); err != nil {
return errors.Wrap(err, "mk pm dir") return errors.Wrap(err, "mk pm dir")