2018-03-03 21:28:24 -08:00
|
|
|
package pkg
|
|
|
|
|
|
|
|
import (
|
2018-03-03 22:52:01 -08:00
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2018-03-03 22:24:37 -08:00
|
|
|
|
2018-03-03 21:28:24 -08:00
|
|
|
"github.com/pkg/errors"
|
2018-03-03 22:52:01 -08:00
|
|
|
"mcquay.me/fs"
|
|
|
|
"mcquay.me/pm"
|
2018-03-03 22:24:37 -08:00
|
|
|
"mcquay.me/pm/db"
|
2018-03-03 21:28:24 -08:00
|
|
|
)
|
|
|
|
|
2018-03-03 22:52:01 -08:00
|
|
|
const cache = "var/cache/pm"
|
|
|
|
|
2018-03-03 21:28:24 -08:00
|
|
|
// Install fetches and installs pkgs from appropriate remotes.
|
|
|
|
func Install(root string, pkgs []string) error {
|
2018-03-03 22:24:37 -08:00
|
|
|
av, err := db.LoadAvailable(root)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "loading available db")
|
|
|
|
}
|
|
|
|
|
|
|
|
ms, err := av.Installable(pkgs)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "checking ability to install")
|
|
|
|
}
|
2018-03-03 22:52:01 -08:00
|
|
|
|
|
|
|
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)
|
2018-03-03 22:24:37 -08:00
|
|
|
}
|
2018-03-03 22:52:01 -08:00
|
|
|
|
|
|
|
if err := download(cacheDir, ms); err != nil {
|
|
|
|
return errors.Wrap(err, "downloading")
|
|
|
|
}
|
|
|
|
|
2018-03-03 21:28:24 -08:00
|
|
|
return errors.New("NYI")
|
|
|
|
}
|
2018-03-03 22:52:01 -08:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|