parent
11220cc573
commit
a9d92b3074
23
disk/disk.go
23
disk/disk.go
|
@ -7,7 +7,6 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
|
@ -17,13 +16,7 @@ import (
|
|||
"github.com/mholt/archiver/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
amd64Re = regexp.MustCompile(`amd64|x86_64|64`)
|
||||
linuxRe = regexp.MustCompile(`linux|linux64`)
|
||||
windowsRe = regexp.MustCompile(`windows|win64`)
|
||||
)
|
||||
|
||||
func Install(asset forge.Asset) error {
|
||||
func Install(name string, asset forge.Asset) error {
|
||||
tmp, err := os.MkdirTemp(os.TempDir(), "eget-*")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -49,7 +42,7 @@ func Install(asset forge.Asset) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := unpack(tmpDest, asset.Name); err != nil {
|
||||
if err := unpack(tmpDest, name); err != nil {
|
||||
return fmt.Errorf("could not unpack download: %w", err)
|
||||
}
|
||||
|
||||
|
@ -57,7 +50,7 @@ func Install(asset forge.Asset) error {
|
|||
}
|
||||
|
||||
func unpack(src, name string) error {
|
||||
dest := filepath.Join(xdg.DataHome, "eget", name)
|
||||
dest := Path(name)
|
||||
if err := os.MkdirAll(dest, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("could not make all dest dirs: %w", err)
|
||||
}
|
||||
|
@ -68,7 +61,11 @@ func unpack(src, name string) error {
|
|||
uaIface, err := archiver.ByExtension(src)
|
||||
if err != nil {
|
||||
if filepath.Ext(src) == binExt {
|
||||
return os.Rename(src, filepath.Join(dest, name+binExt))
|
||||
dest = filepath.Join(dest, name+binExt)
|
||||
if err := os.Rename(src, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chmod(dest, 0o755)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -120,3 +117,7 @@ func moveDir(src, dest string) error {
|
|||
return os.Rename(walkPath, destPath)
|
||||
})
|
||||
}
|
||||
|
||||
func Path(name string) string {
|
||||
return filepath.Join(xdg.DataHome, "eget", name)
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
amd64Re = regexp.MustCompile(`amd64|x86_64|64`)
|
||||
linuxRe = regexp.MustCompile(`linux|linux64`)
|
||||
windowsRe = regexp.MustCompile(`windows|win64`)
|
||||
amd64Re = regexp.MustCompile(`amd64|x86_64|64-bit|[^m]64`)
|
||||
linuxRe = regexp.MustCompile(`linux`)
|
||||
windowsRe = regexp.MustCompile(`windows|\Awin`)
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
|
@ -66,6 +66,7 @@ func Latest(f Forger) (Asset, error) {
|
|||
if amd64Re.MatchString(a.Name) && re.MatchString(a.Name) {
|
||||
fmt.Printf("found %q\n", a.Name)
|
||||
asset = a
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
76
main.go
76
main.go
|
@ -1,25 +1,52 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"go.jolheiser.com/eget/disk"
|
||||
"go.jolheiser.com/eget/forge"
|
||||
"go.jolheiser.com/eget/meta"
|
||||
"go.jolheiser.com/eget/shell"
|
||||
)
|
||||
|
||||
var Version = "develop"
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("eget <project URI>")
|
||||
fs := flag.NewFlagSet("eget", flag.ExitOnError)
|
||||
fs.Usage = func() {
|
||||
fmt.Fprintln(fs.Output(), "eget <package>")
|
||||
fs.PrintDefaults()
|
||||
}
|
||||
updateFlag := fs.Bool("update", false, "Update package")
|
||||
fs.BoolVar(updateFlag, "u", *updateFlag, "--update")
|
||||
deleteFlag := flag.Bool("delete", false, "Delete package")
|
||||
fs.BoolVar(deleteFlag, "d", *deleteFlag, "--delete")
|
||||
nuFlag := fs.Bool("nu", false, "Write out Nu environment")
|
||||
if err := fs.Parse(os.Args[1:]); err != nil {
|
||||
fs.Usage()
|
||||
return
|
||||
}
|
||||
|
||||
if *nuFlag {
|
||||
nu, err := shell.Nu()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(nu)
|
||||
return
|
||||
}
|
||||
|
||||
if fs.NArg() < 1 {
|
||||
fs.Usage()
|
||||
return
|
||||
}
|
||||
|
||||
var f forge.Forger
|
||||
var err error
|
||||
uri := os.Args[1]
|
||||
uri := fs.Arg(0)
|
||||
|
||||
f, err = forge.NewGitea(uri)
|
||||
if strings.HasPrefix(uri, "github") {
|
||||
|
@ -29,12 +56,53 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
name := uriName(uri)
|
||||
if *deleteFlag {
|
||||
if err := os.RemoveAll(disk.Path(name)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := meta.Remove(name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("removed %q\n", name)
|
||||
return
|
||||
}
|
||||
|
||||
asset, err := forge.Latest(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := disk.Install(asset); err != nil {
|
||||
if *updateFlag {
|
||||
m, err := meta.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if strings.EqualFold(asset.Name, m.Packages[name]) {
|
||||
fmt.Printf("%q is up-to-date\n", name)
|
||||
return
|
||||
}
|
||||
if err := os.RemoveAll(disk.Path(name)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := disk.Install(name, asset); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := meta.Upsert(name, asset.Name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
verb := "installed"
|
||||
if *updateFlag {
|
||||
verb = "updated"
|
||||
}
|
||||
fmt.Printf("%s %q\n", verb, uri)
|
||||
}
|
||||
|
||||
func uriName(uri string) string {
|
||||
parts := strings.FieldsFunc(uri, func(r rune) bool { return r == '/' })
|
||||
return parts[len(parts)-1]
|
||||
}
|
||||
|
|
32
meta/meta.go
32
meta/meta.go
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
@ -11,36 +12,37 @@ import (
|
|||
)
|
||||
|
||||
type Meta struct {
|
||||
Packages []Package `json:"packages"`
|
||||
Packages map[string]string `json:"packages"`
|
||||
}
|
||||
|
||||
type Package struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func Add(pkg Package) error {
|
||||
func Upsert(name, version string) error {
|
||||
m, err := Read()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range m.Packages {
|
||||
if strings.EqualFold(pkg.Name, p.Name) {
|
||||
return errors.New("package already exists locally")
|
||||
for n := range m.Packages {
|
||||
if strings.EqualFold(n, name) {
|
||||
m.Packages[n] = version
|
||||
return save(m)
|
||||
}
|
||||
}
|
||||
m.Packages = append(m.Packages, pkg)
|
||||
m.Packages[name] = version
|
||||
return save(m)
|
||||
}
|
||||
|
||||
func Read() (Meta, error) {
|
||||
var m Meta
|
||||
m := Meta{
|
||||
Packages: make(map[string]string),
|
||||
}
|
||||
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 {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return m, json.Unmarshal([]byte(`{}`), &m)
|
||||
}
|
||||
return m, fmt.Errorf("could not open meta file: %w", err)
|
||||
}
|
||||
defer fi.Close()
|
||||
|
@ -56,9 +58,9 @@ func Remove(name string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for idx, p := range m.Packages {
|
||||
if strings.EqualFold(name, p.Name) {
|
||||
m.Packages = append(m.Packages[:idx], m.Packages[idx+1:]...)
|
||||
for n := range m.Packages {
|
||||
if strings.EqualFold(n, name) {
|
||||
delete(m.Packages, name)
|
||||
return save(m)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.jolheiser.com/eget/disk"
|
||||
"go.jolheiser.com/eget/meta"
|
||||
)
|
||||
|
||||
func Nu() (string, error) {
|
||||
tmpl := "let-env PATH = ($env.PATH | append '%s')\n"
|
||||
m, err := meta.Read()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
Reference in New Issue