Files
navi/internal/update/update_darwin.go
T

96 lines
2.1 KiB
Go

//go:build darwin
package update
import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
)
// Apply downloads the new binary into ~/Downloads (no silent self-replace).
func Apply(ctx context.Context, manifestURL string) (string, error) {
st, err := Check(ctx, manifestURL)
if err != nil {
return "", err
}
if !st.Available {
if st.Error != "" {
return "", fmt.Errorf("%s", st.Error)
}
return "", fmt.Errorf("обновление не найдено")
}
if !allowedDownloadURL(st.URL) {
return "", fmt.Errorf("URL обновления должен быть на git.evilfox.cc или files.de4ima.uk")
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
dir := filepath.Join(home, "Downloads")
_ = os.MkdirAll(dir, 0o755)
dest := filepath.Join(dir, fmt.Sprintf("Navis-%s-darwin-%s", sanitizeDarwinVer(st.Latest), runtime.GOARCH))
tmp := dest + ".part"
_ = os.Remove(tmp)
_ = os.Remove(dest)
if err := downloadFile(ctx, st.URL, tmp); err != nil {
return "", err
}
if st.SHA256 != "" {
sum, err := fileSHA256(tmp)
if err != nil {
_ = os.Remove(tmp)
return "", err
}
if sum != "" && !eqFold(sum, st.SHA256) {
_ = os.Remove(tmp)
return "", fmt.Errorf("checksum mismatch")
}
}
if err := os.Rename(tmp, dest); err != nil {
_ = os.Remove(tmp)
return "", err
}
_ = os.Chmod(dest, 0o755)
_ = exec.Command("open", "-R", dest).Start()
return fmt.Sprintf("Скачано v%s:\n%s\nЗакройте Navis и запустите новый файл.", st.Latest, dest), nil
}
func sanitizeDarwinVer(v string) string {
out := make([]rune, 0, len(v))
for _, r := range v {
switch {
case r >= '0' && r <= '9', r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r == '.', r == '-':
out = append(out, r)
}
}
if len(out) == 0 {
return "update"
}
return string(out)
}
func eqFold(a, b string) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
ca, cb := a[i], b[i]
if ca >= 'A' && ca <= 'F' {
ca += 'a' - 'A'
}
if cb >= 'A' && cb <= 'F' {
cb += 'a' - 'A'
}
if ca != cb {
return false
}
}
return true
}