diff --git a/cmd/pm/main.go b/cmd/pm/main.go index 5f81ade..7cf6687 100644 --- a/cmd/pm/main.go +++ b/cmd/pm/main.go @@ -23,6 +23,7 @@ subcommands: environ (env) -- print environment information install (in) -- install packages keyring (key) -- interact with pm's OpenPGP keyring + ls -- list installed packages package (pkg) -- create packages pull -- fetch all available packages from all configured remotes remote -- configure remote pmd servers @@ -232,6 +233,10 @@ func main() { if err := pkg.Install(root, pkgs); err != nil { fatalf("installing: %v\n", err) } + case "ls": + if err := db.ListInstalled(root, os.Stdout); err != nil { + fatalf("listing installed: %v\n", err) + } case "version", "v": fmt.Printf("pm: version %v\n", Version) default: diff --git a/db/installed.go b/db/installed.go index 14f3a3a..22b4eb2 100644 --- a/db/installed.go +++ b/db/installed.go @@ -2,6 +2,8 @@ package db import ( "encoding/json" + "fmt" + "io" "os" "path/filepath" @@ -33,6 +35,19 @@ func IsInstalled(root string, m pm.Meta) (bool, error) { return r, nil } +// ListInstalled pretty prints the installed database to w. +func ListInstalled(root string, w io.Writer) error { + db, err := loadi(root) + if err != nil { + return errors.Wrap(err, "loading installed db") + } + + for m := range db.Traverse() { + fmt.Fprintf(w, "%v\t%v\t%v\n", m.Name, m.Version, m.Remote.String()) + } + return nil +} + func loadi(root string) (pm.Installed, error) { r := pm.Installed{} dbn := filepath.Join(root, in) diff --git a/installed.go b/installed.go index 50ebdbd..aaa2608 100644 --- a/installed.go +++ b/installed.go @@ -1,4 +1,24 @@ package pm +import "sort" + // Installed tracks installed packages. type Installed map[Name]Meta + +// Traverse returns a chan of Meta that will be sanely sorted. +func (i Installed) Traverse() <-chan Meta { + r := make(chan Meta) + go func() { + names := Names{} + for n := range i { + names = append(names, n) + } + sort.Sort(names) + + for _, n := range names { + r <- i[n] + } + close(r) + }() + return r +}