feat: working version

Signed-off-by: jolheiser <john.olheiser@gmail.com>
main
jolheiser 2023-01-14 00:02:25 -06:00
parent 11220cc573
commit a9d92b3074
Signed by: jolheiser
GPG Key ID: B853ADA5DA7BBF7A
5 changed files with 130 additions and 33 deletions

View File

@ -7,7 +7,6 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"strings" "strings"
@ -17,13 +16,7 @@ import (
"github.com/mholt/archiver/v3" "github.com/mholt/archiver/v3"
) )
var ( func Install(name string, asset forge.Asset) error {
amd64Re = regexp.MustCompile(`amd64|x86_64|64`)
linuxRe = regexp.MustCompile(`linux|linux64`)
windowsRe = regexp.MustCompile(`windows|win64`)
)
func Install(asset forge.Asset) error {
tmp, err := os.MkdirTemp(os.TempDir(), "eget-*") tmp, err := os.MkdirTemp(os.TempDir(), "eget-*")
if err != nil { if err != nil {
return err return err
@ -49,7 +42,7 @@ func Install(asset forge.Asset) error {
return err 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) 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 { 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 { if err := os.MkdirAll(dest, os.ModePerm); err != nil {
return fmt.Errorf("could not make all dest dirs: %w", err) 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) uaIface, err := archiver.ByExtension(src)
if err != nil { if err != nil {
if filepath.Ext(src) == binExt { 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 return err
} }
@ -120,3 +117,7 @@ func moveDir(src, dest string) error {
return os.Rename(walkPath, destPath) return os.Rename(walkPath, destPath)
}) })
} }
func Path(name string) string {
return filepath.Join(xdg.DataHome, "eget", name)
}

View File

@ -10,9 +10,9 @@ import (
) )
var ( var (
amd64Re = regexp.MustCompile(`amd64|x86_64|64`) amd64Re = regexp.MustCompile(`amd64|x86_64|64-bit|[^m]64`)
linuxRe = regexp.MustCompile(`linux|linux64`) linuxRe = regexp.MustCompile(`linux`)
windowsRe = regexp.MustCompile(`windows|win64`) windowsRe = regexp.MustCompile(`windows|\Awin`)
) )
type Release struct { type Release struct {
@ -66,6 +66,7 @@ func Latest(f Forger) (Asset, error) {
if amd64Re.MatchString(a.Name) && re.MatchString(a.Name) { if amd64Re.MatchString(a.Name) && re.MatchString(a.Name) {
fmt.Printf("found %q\n", a.Name) fmt.Printf("found %q\n", a.Name)
asset = a asset = a
break
} }
} }

76
main.go
View File

@ -1,25 +1,52 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"go.jolheiser.com/eget/disk" "go.jolheiser.com/eget/disk"
"go.jolheiser.com/eget/forge" "go.jolheiser.com/eget/forge"
"go.jolheiser.com/eget/meta"
"go.jolheiser.com/eget/shell"
) )
var Version = "develop" var Version = "develop"
func main() { func main() {
if len(os.Args) < 2 { fs := flag.NewFlagSet("eget", flag.ExitOnError)
fmt.Println("eget <project URI>") 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 return
} }
var f forge.Forger var f forge.Forger
var err error var err error
uri := os.Args[1] uri := fs.Arg(0)
f, err = forge.NewGitea(uri) f, err = forge.NewGitea(uri)
if strings.HasPrefix(uri, "github") { if strings.HasPrefix(uri, "github") {
@ -29,12 +56,53 @@ func main() {
panic(err) 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) asset, err := forge.Latest(f)
if err != nil { if err != nil {
panic(err) 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) 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]
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/fs"
"os" "os"
"strings" "strings"
@ -11,36 +12,37 @@ import (
) )
type Meta struct { type Meta struct {
Packages []Package `json:"packages"` Packages map[string]string `json:"packages"`
} }
type Package struct { func Upsert(name, version string) error {
Name string `json:"name"`
Version string `json:"version"`
}
func Add(pkg Package) error {
m, err := Read() m, err := Read()
if err != nil { if err != nil {
return err return err
} }
for _, p := range m.Packages { for n := range m.Packages {
if strings.EqualFold(pkg.Name, p.Name) { if strings.EqualFold(n, name) {
return errors.New("package already exists locally") m.Packages[n] = version
return save(m)
} }
} }
m.Packages = append(m.Packages, pkg) m.Packages[name] = version
return save(m) return save(m)
} }
func Read() (Meta, error) { func Read() (Meta, error) {
var m Meta m := Meta{
Packages: make(map[string]string),
}
fp, err := metaPath() fp, err := metaPath()
if err != nil { if err != nil {
return m, fmt.Errorf("could not get meta file: %w", err) return m, fmt.Errorf("could not get meta file: %w", err)
} }
fi, err := os.Open(fp) fi, err := os.Open(fp)
if err != nil { 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) return m, fmt.Errorf("could not open meta file: %w", err)
} }
defer fi.Close() defer fi.Close()
@ -56,9 +58,9 @@ func Remove(name string) error {
if err != nil { if err != nil {
return err return err
} }
for idx, p := range m.Packages { for n := range m.Packages {
if strings.EqualFold(name, p.Name) { if strings.EqualFold(n, name) {
m.Packages = append(m.Packages[:idx], m.Packages[idx+1:]...) delete(m.Packages, name)
return save(m) return save(m)
} }
} }

25
shell/nu.go 100644
View File

@ -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
}