From 68942b6cdd757ce78b14ae10bdfd468c1194f411 Mon Sep 17 00:00:00 2001 From: stephen mcquay Date: Sat, 3 Mar 2018 22:52:01 -0800 Subject: [PATCH] pm install downloads packages --- meta.go | 7 ++++++- pkg/install.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/meta.go b/meta.go index 9460e3e..6035777 100644 --- a/meta.go +++ b/meta.go @@ -29,9 +29,14 @@ func (m Meta) Valid() (bool, error) { return true, nil } +// Pkg returns the string name the .pkg should have on disk. +func (m Meta) Pkg() string { + return fmt.Sprintf("%s-%s.pkg", m.Name, m.Version) +} + // URL returns the http location of this package. func (m Meta) URL() string { - return fmt.Sprintf("%s/%s-%s.pkg", m.Remote.String(), m.Name, m.Version) + return fmt.Sprintf("%s/%s", m.Remote.String(), m.Pkg()) } func (m Meta) String() string { diff --git a/pkg/install.go b/pkg/install.go index a0dae41..80f5ea3 100644 --- a/pkg/install.go +++ b/pkg/install.go @@ -1,12 +1,19 @@ package pkg import ( - "log" + "io" + "net/http" + "os" + "path/filepath" "github.com/pkg/errors" + "mcquay.me/fs" + "mcquay.me/pm" "mcquay.me/pm/db" ) +const cache = "var/cache/pm" + // Install fetches and installs pkgs from appropriate remotes. func Install(root string, pkgs []string) error { av, err := db.LoadAvailable(root) @@ -18,8 +25,44 @@ func Install(root string, pkgs []string) error { if err != nil { return errors.Wrap(err, "checking ability to install") } - for _, m := range ms { - log.Printf("fake install %v", m) + + cacheDir := filepath.Join(root, cache) + if !fs.Exists(cacheDir) { + if err := os.MkdirAll(cacheDir, 0755); err != nil { + return errors.Wrap(err, "creating non-existent cache dir") + } } + if !fs.IsDir(cacheDir) { + return errors.Errorf("%q is not a directory!", cacheDir) + } + + if err := download(cacheDir, ms); err != nil { + return errors.Wrap(err, "downloading") + } + return errors.New("NYI") } + +func download(cache string, ms pm.Metas) error { + // TODO (sm): concurrently fetch + for _, m := range ms { + resp, err := http.Get(m.URL()) + if err != nil { + return errors.Wrap(err, "http get") + } + fn := filepath.Join(cache, m.Pkg()) + f, err := os.Create(fn) + if err != nil { + return errors.Wrap(err, "creating") + } + + if n, err := io.Copy(f, resp.Body); err != nil { + return errors.Wrapf(err, "copy %q to disk after %d bytes", m.URL(), n) + } + + if err := resp.Body.Close(); err != nil { + return errors.Wrap(err, "closing resp body") + } + } + return nil +}