Skip to content

Commit

Permalink
Install zig and zls only if version is not already installed
Browse files Browse the repository at this point in the history
  • Loading branch information
timodempwolf committed Sep 24, 2024
1 parent 0d21bfd commit 76c7897
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 37 deletions.
83 changes: 69 additions & 14 deletions cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"slices"
"strings"

"github.com/schollz/progressbar/v3"
Expand All @@ -30,13 +31,47 @@ import (
"github.com/tristanisham/clr"
)

func (z *ZVM) Install(version string) error {
func (z *ZVM) Install(version string, force bool) error {
os.Mkdir(z.baseDir, 0755)
rawVersionStructure, err := z.fetchVersionMap()
if err != nil {
return err
}

if !force {
installedVersions, err := z.GetInstalledVersions()
if err != nil {
return err
}
if slices.Contains(installedVersions, version) {
alreadyInstalled := true
installedVersion := version
if version == "master" {
targetZig := strings.TrimSpace(filepath.Join(z.baseDir, "master", "zig"))
cmd := exec.Command(targetZig, "version")
var zigVersion strings.Builder
cmd.Stdout = &zigVersion
err := cmd.Run()
if err != nil {
log.Warn(err)
}

installedVersion = strings.TrimSpace(zigVersion.String())
if master, ok := rawVersionStructure["master"]; ok {
if remoteVersion, ok := master["version"].(string); ok {
if installedVersion != remoteVersion {
alreadyInstalled = false
}
}
}
if alreadyInstalled {
fmt.Printf("Zig version %s is already installed\n", installedVersion)
return nil
}
}
}
}

tarPath, err := getTarPath(version, &rawVersionStructure)
if err != nil {
if errors.Is(err, ErrUnsupportedVersion) {
Expand Down Expand Up @@ -273,23 +308,23 @@ type zlsCIZLSVersion struct {
Targets []string
}

func getZLSDownloadUrl(version string, archDouble string) (string, error) {
func getZLSDownloadUrl(version string, archDouble string) (string, string, error) {
if version == "master" {
resp, err := http.Get("https://zigtools-releases.nyc3.digitaloceanspaces.com/zls/index.json")
if err != nil {
return "", err
return "", "", err
}
defer resp.Body.Close()

var releaseBuffer bytes.Buffer
_, err = releaseBuffer.ReadFrom(resp.Body)
if err != nil {
return "", err
return "", "", err
}

var ciIndex zlsCIDownloadIndexResponse
if err := json.Unmarshal(releaseBuffer.Bytes(), &ciIndex); err != nil {
return "", err
return "", "", err
}

exeName := "zls"
Expand All @@ -298,31 +333,31 @@ func getZLSDownloadUrl(version string, archDouble string) (string, error) {
}

format_url := "https://zigtools-releases.nyc3.digitaloceanspaces.com/zls/%v/%v/%v"
return fmt.Sprintf(format_url, ciIndex.Latest, archDouble, exeName), nil
return fmt.Sprintf(format_url, ciIndex.Latest, archDouble, exeName), ciIndex.Latest, nil
} else {
url := fmt.Sprintf("https://api.github.com/repos/zigtools/zls/releases/tags/%v", version)

// get release information
resp, err := http.Get(url)
if err != nil {
return "", err
return "", "", err
}
defer resp.Body.Close()

var releaseBuffer bytes.Buffer
_, err = releaseBuffer.ReadFrom(resp.Body)
if err != nil {
return "", err
return "", "", err
}

// getting list of assets
var taggedReleaseResponse githubTaggedReleaseResponse
if err := json.Unmarshal(releaseBuffer.Bytes(), &taggedReleaseResponse); err != nil {
return "", err
return "", "", err
}

if len(taggedReleaseResponse.Assets) == 0 {
return "", errors.New("invalid ZLS version")
return "", "", errors.New("invalid ZLS version")
}

// getting platform information
Expand All @@ -335,14 +370,14 @@ func getZLSDownloadUrl(version string, archDouble string) (string, error) {
}

if downloadUrl == "" {
return "", errors.New("invalid ZLS release URL")
return "", "", errors.New("invalid ZLS release URL")
}

return downloadUrl, nil
return downloadUrl, version, nil
}
}

func (z *ZVM) InstallZls(version string) error {
func (z *ZVM) InstallZls(version string, force bool) error {
if version != "master" && strings.Count(version, ".") != 2 {
return fmt.Errorf("%w: versions are SEMVER (MAJOR.MINOR.MINUSCULE)", ErrUnsupportedVersion)
}
Expand All @@ -367,11 +402,31 @@ func (z *ZVM) InstallZls(version string) error {
// master does not need unzipping, zpm just serves full binary
shouldUnzip := version != "master"

downloadUrl, err := getZLSDownloadUrl(version, expectedArchOs)
downloadUrl, selectedVersion, err := getZLSDownloadUrl(version, expectedArchOs)
if err != nil {
return err
}

if !force {
installedVersion := ""
targetZls := strings.TrimSpace(filepath.Join(z.baseDir, version, "zls"))
if _, err := os.Stat(targetZls); err == nil {
cmd := exec.Command(targetZls, "--version")
var zigVersion strings.Builder
cmd.Stdout = &zigVersion
err := cmd.Run()
if err != nil {
log.Warn(err)
}

installedVersion = strings.TrimSpace(zigVersion.String())
}
if installedVersion == selectedVersion {
fmt.Printf("ZLS version %s is already installed\n", installedVersion)
return nil
}
}

request, err := http.NewRequest("GET", downloadUrl, nil)
if err != nil {
return err
Expand Down
49 changes: 29 additions & 20 deletions cli/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,43 @@ func (z *ZVM) ListVersions() error {
}

version := zigVersion.String()
dir, err := os.ReadDir(z.baseDir)

installedVersions, err := z.GetInstalledVersions()
if err != nil {
return err
}

for _, key := range installedVersions {
if key == strings.TrimSpace(version) || key == "master" && strings.Contains(version, "-dev.") {
if z.Settings.UseColor {
// Should just check bin for used version
fmt.Println(clr.Green(key))
} else {
fmt.Printf("%s [x]", key)
}
} else {
fmt.Println(key)
}
}

return nil
}

func (z *ZVM) GetInstalledVersions() ([]string, error) {
dir, err := os.ReadDir(z.baseDir)
if err != nil {
return nil, err
}
versions := make([]string, 0, len(dir))
for _, key := range dir {
switch key.Name() {
case "settings.json", "bin", "versions.json", "self":
continue
default:
if key.Name() == strings.TrimSpace(version) || key.Name() == "master" && strings.Contains(version, "-dev.") {
if z.Settings.UseColor {
// Should just check bin for used version
fmt.Println(clr.Green(key.Name()))
} else {
fmt.Printf("%s [x]", key.Name())
}
} else {
fmt.Println(key.Name())
}
versions = append(versions, key.Name())
}
}

return nil
return versions, nil
}

func (z ZVM) ListRemoteAvailable() error {
Expand All @@ -62,7 +75,7 @@ func (z ZVM) ListRemoteAvailable() error {
return err
}

options := make([]string, 0)
options := make([]string, 0, len(versions))

for key := range versions {
options = append(options, "v"+key)
Expand All @@ -72,15 +85,11 @@ func (z ZVM) ListRemoteAvailable() error {
slices.Reverse(options)

// Remove "v" prefix to maintain consistency with zig versioning
newOptions := options[:0]
finalList := options[:0]
for _, version := range options {
newOptions = append(newOptions, version[1:])
finalList = append(finalList, version[1:])
}

finalList := make([]string, 0)

finalList = append(finalList, newOptions...)

fmt.Println(strings.Join(finalList, "\n"))

return nil
Expand Down
2 changes: 1 addition & 1 deletion cli/use.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (z *ZVM) Use(ver string) error {

fmt.Printf("It looks like %s isn't installed. Would you like to install it? [y/n]\n", ver)
if getConfirmation() {
if err = z.Install(ver); err != nil {
if err = z.Install(ver, false); err != nil {
return err
}
} else {
Expand Down
9 changes: 7 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ var zvmApp = &opts.App{
// Aliases: []string{"z"},
Usage: "install ZLS",
},
&opts.BoolFlag{
Name: "force",
Usage: "force installation even if the version is already installed",
},
},
Description: "To install the latest version, use `master`",
Args: true,
Expand All @@ -91,15 +95,16 @@ var zvmApp = &opts.App{
// return err
// }
// }
force := ctx.Bool("force")

// Install Zig
if err := zvm.Install(req.Package); err != nil {
if err := zvm.Install(req.Package, force); err != nil {
return err
}

// Install ZLS (if requested)
if ctx.Bool("zls") {
if err := zvm.InstallZls(req.Package); err != nil {
if err := zvm.InstallZls(req.Package, force); err != nil {
return err
}
}
Expand Down

0 comments on commit 76c7897

Please sign in to comment.