8000 Go version by tristanisham · Pull Request #5 · tristanisham/zvm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Go version #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/zig-cache
/zig-out
/zig-out
38 changes: 0 additions & 38 deletions build.zig

This file was deleted.

54 changes: 54 additions & 0 deletions cli/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package cli

import (
"encoding/json"
"log"
"os"
"path/filepath"
)

func Initialize() *ZVM {
home, err := os.UserHomeDir()
if err != nil {
home = "~"
}
zvm_path := filepath.Join(home, ".zvm")
if _, err := os.Stat(zvm_path); os.IsNotExist(err) {
if err := os.MkdirAll(zvm_path, 0775); err != nil {
log.Fatal(err)
}
}

return &ZVM{
zvmBaseDir: zvm_path,
}
}

type ZVM struct {
zvmBaseDir string
zigVersions zigVersionMap
}

// A representaiton of the offical json schema for Zig versions
type zigVersionMap = map[string]zigVersion

// A representation of individual Zig versions
type zigVersion = map[string]any

func (z *ZVM) loadVersionCache() error {
ver, err := os.ReadFile(filepath.Join(z.zvmBaseDir, "versions.json"))
if err != nil {
return err
}
if err := json.Unmarshal(ver, &z.zigVersions); err != nil {
return err
}
return nil
}

func (z ZVM) getVersion(version string) *zigVersion {
if version, ok := z.zigVersions[version]; ok {
return &version
}
return nil
}
156 changes: 156 additions & 0 deletions cli/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package cli

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/schollz/progressbar/v3"
"github.com/tristanisham/clr"
)

func (z *ZVM) Install(version string) error {
zvm := z.zvmBaseDir
os.Mkdir(zvm, 0755)

req, err := http.NewRequest("GET", "https://ziglang.org/download/index.json", nil)
if err != nil {
return err
}

req.Header.Set("User-Agent", "zvm (Zig Version Manager) 0.0.2")
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

versions, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
if err := os.WriteFile(filepath.Join(zvm, "versions.json"), versions, 0755); err != nil {
return err
}

rawVersionStructure := make(zigVersionMap)
if err := json.Unmarshal(versions, &rawVersionStructure); err != nil {
return err
}
z.zigVersions = rawVersionStructure

tarPath, err := getTarPath(version, &rawVersionStructure)
if err != nil {
return err
}

tarReq, err := http.Get(*tarPath)
if err != nil {
return err
}
defer tarReq.Body.Close()
// _ = os.MkdirAll(filepath.Join(zvm, version), 0755)
// tarDownloadPath := filepath.Join(zvm, version, fmt.Sprintf("%s.tar.xz", version))

out, err := os.CreateTemp(zvm, "*.tar.xz")
if err != nil {
return err
}
defer out.Close()
defer os.RemoveAll(out.Name())

pbar := progressbar.DefaultBytes(
tarReq.ContentLength,
fmt.Sprintf("Downloading %s:", clr.Green(version)),
)

_, err = io.Copy(io.MultiWriter(out, pbar), tarReq.Body)
if err != nil {
return err
}

// The base directory where all Zig files for the appropriate version are installed
// installedVersionPath := filepath.Join(zvm, version)
fmt.Println("Extracting bundle...")

if err := extractTarXZ(out.Name(), zvm); err != nil {
log.Fatal(clr.Red(err))
}
tarName := strings.TrimPrefix(*tarPath, "https://ziglang.org/builds/")
tarName = strings.TrimSuffix(tarName, ".tar.xz")
if err := os.Rename(filepath.Join(zvm, tarName), filepath.Join(zvm, version)); err != nil {
if _, err := os.Stat(filepath.Join(zvm, version)); os.IsExist(err) {
if err := os.Remove(filepath.Join(zvm, version)); err != nil {
log.Fatalln(clr.Red(err))
} else {
if err := os.Rename(filepath.Join(zvm, tarName), filepath.Join(zvm, version)); err != nil {
log.Fatalln(clr.Yellow(err))
}
}
}
}

// This removes the extra download
if err := os.RemoveAll(filepath.Join(zvm, tarName)); err != nil {
log.Println(clr.Red(err))
}

if err := os.Remove(filepath.Join(zvm, "bin")); err != nil {
log.Println(clr.Yellow(err))
}

if err := os.Symlink(filepath.Join(zvm, version), filepath.Join(zvm, "bin")); err != nil {
log.Fatal(clr.Red(err))
}

return nil
}

func getTarPath(version string, data *map[string]map[string]any) (*string, error) {
if info, ok := (*data)[version]; ok {
arch, ops := zigStyleSysInfo()
if systemInfo, ok := info[fmt.Sprintf("%s-%s", arch, ops)]; ok {
if base, ok := systemInfo.(map[string]any); ok {
if tar, ok := base["tarball"].(string); ok {
return &tar, nil
}
} else {
return nil, fmt.Errorf("unable to find necessary download path")
}
} else {
return nil, fmt.Errorf("invalid/unsupported system: ARCH: %s OS: %s", arch, ops)
}
}
return nil, fmt.Errorf("invalid Zig version: %s", version)
}

func zigStyleSysInfo() (string, string) {
var arch string
switch runtime.GOARCH {
case "amd64":
arch = "x86_64"
default:
arch = runtime.GOARCH
}

return arch, runtime.GOOS
}

func extractTarXZ(bundle, out string) error {
tar := exec.Command("tar", "-xf", bundle, "-C", out)
tar.Stdout = os.Stdout
tar.Stderr = os.Stderr
if err := tar.Run(); err != nil {
return err
}

return nil
}
29 changes: 29 additions & 0 deletions cli/use.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cli

import (
"log"
"os"
"path/filepath"

"github.com/tristanisham/clr"
)

func (z *ZVM) Use(ver string) error {
z.loadVersionCache()
if err := z.getVersion(ver); err == nil {
return z.Install(ver)
}
return z.setBin(ver)
}

func (z *ZVM) setBin(ver string) error {
version_path := filepath.Join(z.zvmBaseDir, ver)
if err := os.Remove(filepath.Join(z.zvmBaseDir, "bin")); err != nil {
log.Println(clr.Yellow(err))
}

if err := os.Symlink(version_path, filepath.Join(z.zvmBaseDir, "bin")); err != nil {
return err
}
return nil
}
16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module zvm

go 1.19

require (
github.com/schollz/progressbar/v3 v3.12.1
github.com/tristanisham/clr v0.0.0-20221004001624-00ee60046d85
)

require (
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/rivo/uniseg v0.4.3 // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/term v0.2.0 // indirect
)
30 changes: 30 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ=
github.com/schollz/progressbar/v3 v3.12.1/go.mod h1:g7QSuwyGpqCjVQPFZXA31MSxtrhka9Y9LMdF+XT77/Y=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tristanisham/clr v0.0.0-20221004001624-00ee60046d85 h1:zD4b2hs7jZ2sJtgtNdpMZyo4D4/Ifct8SMxvPNNkHzs=
github.com/tristanisham/clr v0.0.0-20221004001624-00ee60046d85/go.mod h1:cKn2HV8Beq81OHjb2gja2ZiU4HAEQ6LSuxyaIT5Mg7o=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
29 changes: 29 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"log"
"os"
"zvm/cli"
)

func main() {
zvm := cli.Initialize()
args := os.Args[1:]
for i, arg := range args {
switch arg {
case "install", "i":
if len(args) > i+1 {
if err := zvm.Install(args[i+1]); err != nil {
log.Fatal(err)
}
}
case "use":
if len(args) > i+1 {
if err := zvm.Use(args[i+1]); err != nil {
log.Fatal(err)
}
}
}
}

}
Loading
0