2023-01-13 05:07:57 +00:00
|
|
|
package meta
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2023-01-14 06:02:25 +00:00
|
|
|
"io/fs"
|
2023-01-13 05:07:57 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
2023-01-15 03:31:58 +00:00
|
|
|
"go.jolheiser.com/eget/disk"
|
|
|
|
|
2023-01-13 05:07:57 +00:00
|
|
|
"github.com/adrg/xdg"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Meta struct {
|
2023-01-15 03:31:58 +00:00
|
|
|
Packages map[string]Package `json:"packages"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Package struct {
|
|
|
|
Repo string `json:"repo"`
|
|
|
|
Version string `json:"version"`
|
2023-01-13 05:07:57 +00:00
|
|
|
}
|
|
|
|
|
2023-01-15 03:31:58 +00:00
|
|
|
func Upsert(name, repo, version string) error {
|
2023-01-13 05:07:57 +00:00
|
|
|
m, err := Read()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-01-14 06:02:25 +00:00
|
|
|
for n := range m.Packages {
|
|
|
|
if strings.EqualFold(n, name) {
|
2023-01-15 03:31:58 +00:00
|
|
|
m.Packages[n] = Package{
|
|
|
|
Repo: repo,
|
|
|
|
Version: version,
|
|
|
|
}
|
2023-01-14 06:02:25 +00:00
|
|
|
return save(m)
|
2023-01-13 05:07:57 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-15 03:31:58 +00:00
|
|
|
m.Packages[name] = Package{
|
|
|
|
Repo: repo,
|
|
|
|
Version: version,
|
|
|
|
}
|
2023-01-13 05:07:57 +00:00
|
|
|
return save(m)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Read() (Meta, error) {
|
2023-01-14 06:02:25 +00:00
|
|
|
m := Meta{
|
2023-01-15 03:31:58 +00:00
|
|
|
Packages: make(map[string]Package),
|
2023-01-14 06:02:25 +00:00
|
|
|
}
|
2023-01-13 05:07:57 +00:00
|
|
|
fp, err := metaPath()
|
|
|
|
if err != nil {
|
|
|
|
return m, fmt.Errorf("could not get meta file: %w", err)
|
|
|
|
}
|
|
|
|
fi, err := os.Open(fp)
|
|
|
|
if err != nil {
|
2023-01-14 06:02:25 +00:00
|
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
|
|
return m, json.Unmarshal([]byte(`{}`), &m)
|
|
|
|
}
|
2023-01-13 05:07:57 +00:00
|
|
|
return m, fmt.Errorf("could not open meta file: %w", err)
|
|
|
|
}
|
|
|
|
defer fi.Close()
|
|
|
|
|
|
|
|
if err := json.NewDecoder(fi).Decode(&m); err != nil {
|
|
|
|
return m, fmt.Errorf("could not decode meta: %w", err)
|
|
|
|
}
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func Remove(name string) error {
|
|
|
|
m, err := Read()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-01-14 06:02:25 +00:00
|
|
|
for n := range m.Packages {
|
|
|
|
if strings.EqualFold(n, name) {
|
|
|
|
delete(m.Packages, name)
|
2023-01-13 05:07:57 +00:00
|
|
|
return save(m)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fmt.Errorf("could not find package to remove for %q", name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func metaPath() (string, error) {
|
2023-01-15 03:31:58 +00:00
|
|
|
return xdg.ConfigFile("eget/packages.json")
|
|
|
|
}
|
|
|
|
|
|
|
|
func nushellPath() (string, error) {
|
|
|
|
return xdg.DataFile("eget/eget.nu")
|
2023-01-13 05:07:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func save(m Meta) error {
|
|
|
|
fp, err := metaPath()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not get meta path: %w", err)
|
|
|
|
}
|
|
|
|
fi, err := os.Create(fp)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not create meta file: %w", err)
|
|
|
|
}
|
2023-01-15 03:31:58 +00:00
|
|
|
if err := json.NewEncoder(fi).Encode(m); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := fi.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fp, err = nushellPath()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not get nushell path: %w", err)
|
|
|
|
}
|
|
|
|
fi, err = os.Create(fp)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not create nushell file: %w", err)
|
|
|
|
}
|
2023-01-13 05:07:57 +00:00
|
|
|
defer fi.Close()
|
2023-01-15 03:31:58 +00:00
|
|
|
out, err := m.nushell()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not generate nushell environment: %w", err)
|
|
|
|
}
|
|
|
|
fi.WriteString(out)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m Meta) nushell() (string, error) {
|
|
|
|
tmpl := "let-env PATH = ($env.PATH | append '%s')\n"
|
|
|
|
|
|
|
|
var out strings.Builder
|
|
|
|
out.WriteString("# managed by eget; DO NOT EDIT\n\n")
|
|
|
|
for name := range m.Packages {
|
|
|
|
out.WriteString(fmt.Sprintf(tmpl, disk.Path(name)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return out.String(), nil
|
2023-01-13 05:07:57 +00:00
|
|
|
}
|