107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package update
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"vrc_osc_go/internal/buildinfo"
|
|
"vrc_osc_go/internal/common"
|
|
)
|
|
|
|
type Manager struct {
|
|
Client *Client
|
|
OwnerRepo string
|
|
AssetName string
|
|
CurrentLabel string
|
|
}
|
|
|
|
func (m *Manager) CheckAndUpdate() (bool, error) {
|
|
if m.Client == nil || m.OwnerRepo == "" || m.AssetName == "" {
|
|
return false, nil
|
|
}
|
|
latest, err := m.Client.LatestRelease(m.OwnerRepo)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if latest.TagName == "" || latest.TagName == m.CurrentLabel {
|
|
return false, nil
|
|
}
|
|
assetURL := ""
|
|
for _, a := range latest.Assets {
|
|
if a.Name == m.AssetName {
|
|
assetURL = a.URL
|
|
break
|
|
}
|
|
}
|
|
if assetURL == "" {
|
|
return false, fmt.Errorf("asset %q not found in release %s", m.AssetName, latest.TagName)
|
|
}
|
|
base := common.RootDir()
|
|
tmpDir := filepath.Join(base, "update", latest.TagName)
|
|
if err := os.MkdirAll(tmpDir, 0o755); err != nil {
|
|
return false, err
|
|
}
|
|
zipPath := filepath.Join(tmpDir, m.AssetName)
|
|
log.Printf("update available: %s -> %s", m.CurrentLabel, latest.TagName)
|
|
if err := m.Client.DownloadAsset(assetURL, zipPath); err != nil {
|
|
return false, err
|
|
}
|
|
if err := ExtractZip(zipPath, tmpDir); err != nil {
|
|
return false, err
|
|
}
|
|
exePath := filepath.Join(base, CurrentExeName())
|
|
newExe := filepath.Join(tmpDir, CurrentExeName())
|
|
if _, err := os.Stat(newExe); err != nil {
|
|
return false, err
|
|
}
|
|
backup := exePath + ".bak"
|
|
_ = os.Remove(backup)
|
|
if err := os.Rename(exePath, backup); err != nil {
|
|
return false, err
|
|
}
|
|
if err := CopyFile(newExe, exePath); err != nil {
|
|
_ = os.Rename(backup, exePath)
|
|
return false, err
|
|
}
|
|
_ = os.Remove(backup)
|
|
return true, nil
|
|
}
|
|
|
|
func CopyFile(src, dst string) error {
|
|
in, err := os.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
if err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil {
|
|
return err
|
|
}
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
_, err = io.Copy(out, in)
|
|
return err
|
|
}
|
|
|
|
func Launch(exe string, args []string) error {
|
|
cmd := exec.Command(exe, args...)
|
|
cmd.Dir = filepath.Dir(exe)
|
|
return cmd.Start()
|
|
}
|
|
|
|
func Version() string { return buildinfo.Version }
|
|
|
|
func CurrentExeName() string {
|
|
if runtime.GOOS == "windows" {
|
|
return "vrc_osc.exe"
|
|
}
|
|
return "vrc_osc"
|
|
}
|