parent
11220cc573
commit
a9d92b3074
23
disk/disk.go
23
disk/disk.go
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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
76
main.go
|
@ -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)
|
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"
|
"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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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