Release 1.4.0: macOS CLI builds and multi-platform update channel.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Navis
2026-07-28 07:43:14 +03:00
co-authored by Cursor
parent f7fded5b40
commit f266ea8288
23 changed files with 696 additions and 166 deletions
+60 -7
View File
@@ -7,6 +7,7 @@ import (
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
@@ -54,13 +55,13 @@ func EnsureBinary(binDir string) (string, error) {
if err != nil {
return "", err
}
zipPath := filepath.Join(binDir, assetName)
if err := downloadFile(zipPath, url); err != nil {
archivePath := filepath.Join(binDir, assetName)
if err := downloadFile(archivePath, url); err != nil {
return "", err
}
defer os.Remove(zipPath)
defer os.Remove(archivePath)
if err := unzipNaive(zipPath, binDir); err != nil {
if err := extractNaiveArchive(archivePath, binDir); err != nil {
return "", err
}
return ResolveBinary(binDir)
@@ -119,9 +120,6 @@ func findReleaseAsset(pattern string) (name, downloadURL string, err error) {
}
for _, a := range rel.Assets {
if strings.HasPrefix(a.Name, prefix) && strings.HasSuffix(a.Name, suffix) {
if strings.Contains(a.Name, ".tar.") {
return "", "", fmt.Errorf("auto-extract of %s not implemented; download manually from %s", a.Name, a.BrowserDownloadURL)
}
return a.Name, a.BrowserDownloadURL, nil
}
}
@@ -147,6 +145,61 @@ func downloadFile(path, url string) error {
return err
}
func extractNaiveArchive(archivePath, destDir string) error {
lower := strings.ToLower(archivePath)
switch {
case strings.HasSuffix(lower, ".zip"):
return unzipNaive(archivePath, destDir)
case strings.HasSuffix(lower, ".tar.xz"), strings.HasSuffix(lower, ".txz"):
return extractTarXz(archivePath, destDir)
default:
return fmt.Errorf("unsupported archive: %s", filepath.Base(archivePath))
}
}
func extractTarXz(archivePath, destDir string) error {
tmp, err := os.MkdirTemp(destDir, "naive-extract-*")
if err != nil {
return err
}
defer os.RemoveAll(tmp)
cmd := exec.Command("tar", "-xJf", archivePath, "-C", tmp)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("tar extract: %w (%s)", err, strings.TrimSpace(string(out)))
}
want := "naive"
var found string
_ = filepath.Walk(tmp, func(path string, info os.FileInfo, err error) error {
if err != nil || info == nil || info.IsDir() {
return nil
}
if info.Name() == want {
found = path
}
return nil
})
if found == "" {
return fmt.Errorf("archive does not contain %s", want)
}
dest := filepath.Join(destDir, want)
in, err := os.Open(found)
if err != nil {
return err
}
defer in.Close()
out, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o755)
if err != nil {
return err
}
defer out.Close()
if _, err := io.Copy(out, in); err != nil {
return err
}
return nil
}
func unzipNaive(zipPath, destDir string) error {
r, err := zip.OpenReader(zipPath)
if err != nil {