From dd3fecc69925af8eb0fdaf813a83780fc0e3f377 Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Fri, 2 Mar 2018 23:23:13 -0800 Subject: [PATCH] Rearrange some code, adds pm av --- available.go | 12 +++++++ cmd/pm/main.go | 15 ++++++--- remote/pull.go => db/available.go | 52 ++++++++++++++++++++++++++++++- {remote => db}/remote.go | 14 ++++----- {remote => db}/remote_test.go | 6 ++-- 5 files changed, 83 insertions(+), 16 deletions(-) rename remote/pull.go => db/available.go (58%) rename {remote => db}/remote.go (86%) rename {remote => db}/remote_test.go (96%) diff --git a/available.go b/available.go index 89e0b51..7d71bdd 100644 --- a/available.go +++ b/available.go @@ -9,8 +9,20 @@ import ( // Name exists to document the keys in Available type Name string +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 +type Versions []Version + +// TODO (sm): make this semver sort? +func (n Versions) Len() int { return len(n) } +func (n Versions) Swap(a, b int) { n[a], n[b] = n[b], n[a] } +func (n Versions) Less(a, b int) bool { return n[a] < n[b] } // Available is the structure used to represent the collection of all packages // that can be installed. diff --git a/cmd/pm/main.go b/cmd/pm/main.go index 8b3a0a5..53ed5a0 100644 --- a/cmd/pm/main.go +++ b/cmd/pm/main.go @@ -8,14 +8,15 @@ import ( "github.com/pkg/errors" "mcquay.me/fs" + "mcquay.me/pm/db" "mcquay.me/pm/keyring" "mcquay.me/pm/pkg" - "mcquay.me/pm/remote" ) const usage = `pm: simple, cross-platform system package manager subcommands: + available (av) -- print out all installable packages environ (env) -- print environment information keyring (key) -- interact with pm's OpenPGP keyring package (pkg) -- create packages @@ -193,25 +194,29 @@ func main() { if len(args) < 1 { fatalf("missing arg\n\nusage: pm remote add []\n") } - if err := remote.Add(root, args); err != nil { + if err := db.AddRemotes(root, args); err != nil { fatalf("remote add: %v\n", err) } case "rm": if len(args) < 1 { fatalf("missing arg\n\nusage: pm remote rm []\n") } - if err := remote.Remove(root, args); err != nil { + if err := db.RemoveRemotes(root, args); err != nil { fatalf("remote remove: %v\n", err) } case "ls": - if err := remote.List(root, os.Stdout); err != nil { + if err := db.ListRemotes(root, os.Stdout); err != nil { fatalf("list: %v\n", err) } default: fatalf("unknown package subcommand: %q\n\nusage: %v", sub, remoteUsage) } case "pull": - if err := remote.Pull(root); err != nil { + if err := db.Pull(root); err != nil { + fatalf("pulling available packages: %v\n", err) + } + case "available", "av": + if err := db.ListAvailable(root, os.Stdout); err != nil { fatalf("pulling available packages: %v\n", err) } default: diff --git a/remote/pull.go b/db/available.go similarity index 58% rename from remote/pull.go rename to db/available.go index add328f..7097d95 100644 --- a/remote/pull.go +++ b/db/available.go @@ -1,12 +1,16 @@ -package remote +package db import ( "encoding/json" + "fmt" + "io" "net/http" "os" "path/filepath" + "sort" "github.com/pkg/errors" + "mcquay.me/fs" "mcquay.me/pm" ) @@ -46,6 +50,52 @@ func Pull(root string) error { return nil } +// ListAvailable prints all installable packages +func ListAvailable(root string, w io.Writer) error { + db, err := loadAvailable(root) + if err != nil { + return errors.Wrap(err, "loading") + } + names := pm.Names{} + nvs := map[pm.Name]pm.Versions{} + for n, vers := range db { + 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] { + m := db[n][v] + fmt.Fprintf(w, "%v\t%v\t%v\n", m.Name, m.Version, m.Remote.String()) + } + } + return nil +} + +func loadAvailable(root string) (pm.Available, error) { + r := pm.Available{} + dbn := filepath.Join(root, rn) + + if !fs.Exists(dbn) { + return r, nil + } + + f, err := os.Open(filepath.Join(root, an)) + if err != nil { + return r, errors.Wrap(err, "open") + } + + if err := json.NewDecoder(f).Decode(&r); err != nil { + return r, errors.Wrap(err, "decoding db") + } + + return r, nil +} + func saveAvailable(root string, db pm.Available) error { f, err := os.Create(filepath.Join(root, an)) if err != nil { diff --git a/remote/remote.go b/db/remote.go similarity index 86% rename from remote/remote.go rename to db/remote.go index 93b9247..3074cf7 100644 --- a/remote/remote.go +++ b/db/remote.go @@ -1,4 +1,4 @@ -package remote +package db import ( "encoding/json" @@ -17,8 +17,8 @@ type DB []url.URL const rn = "var/lib/pm/remotes.json" -// Add appends the provided uri to the list of configured remotes. -func Add(root string, uris []string) error { +// AddRemotes appends the provided uri to the list of configured remotes. +func AddRemotes(root string, uris []string) error { db, err := load(root) if err != nil { return errors.Wrap(err, "loading") @@ -46,8 +46,8 @@ func Add(root string, uris []string) error { return save(root, db) } -// Remove removes the given uri from the list of configured remotes. -func Remove(root string, uris []string) error { +// RemoveRemotes removes the given uri from the list of configured remotes. +func RemoveRemotes(root string, uris []string) error { db, err := load(root) if err != nil { return errors.Wrap(err, "loading") @@ -79,8 +79,8 @@ func Remove(root string, uris []string) error { return save(root, o) } -// List prints all configured remotes to w. -func List(root string, w io.Writer) error { +// ListRemotes prints all configured remotes to w. +func ListRemotes(root string, w io.Writer) error { db, err := load(root) if err != nil { return errors.Wrap(err, "loading") diff --git a/remote/remote_test.go b/db/remote_test.go similarity index 96% rename from remote/remote_test.go rename to db/remote_test.go index c2d55e6..5d79ed9 100644 --- a/remote/remote_test.go +++ b/db/remote_test.go @@ -1,4 +1,4 @@ -package remote +package db import ( "bytes" @@ -46,7 +46,7 @@ func TestAdd(t *testing.T) { "http\ns://\nFoo|n", } - if err := Add(root, bad); err == nil { + if err := AddRemotes(root, bad); err == nil { t.Fatalf("didn't detect bad url") } @@ -54,7 +54,7 @@ func TestAdd(t *testing.T) { "https://pm.mcquay.me/darwin/amd64", } - if err := Add(root, uris); err != nil { + if err := AddRemotes(root, uris); err != nil { t.Fatalf("add: %v", err) }