github.com/upyun/upx@v0.4.7-0.20240419023638-b184a7cb7c10/upgrade.go (about)

     1  package upx
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"os"
     9  	"runtime"
    10  	"strings"
    11  )
    12  
    13  const (
    14  	VERSION_URL         = "https://raw.githubusercontent.com/upyun/upx/master/VERSION"
    15  	DOWNLOAD_URL_PREFIX = "http://collection.b0.upaiyun.com/softwares/upx/upx-"
    16  )
    17  
    18  func GetCurrentBinPath() string {
    19  	p, _ := os.Executable()
    20  	return p
    21  }
    22  
    23  func GetLatestVersion() (string, error) {
    24  	url := VERSION_URL
    25  	resp, err := http.Get(url)
    26  	if err != nil {
    27  		return "", fmt.Errorf("GetVersion: %v", err)
    28  	}
    29  	content, _ := ioutil.ReadAll(resp.Body)
    30  	resp.Body.Close()
    31  
    32  	if resp.StatusCode/100 != 2 {
    33  		return "", fmt.Errorf("Get %s: %d", url, resp.StatusCode)
    34  	}
    35  
    36  	return strings.TrimSpace(string(content)), nil
    37  }
    38  
    39  func DownloadBin(version, binPath string) error {
    40  	fd, err := os.Create(binPath)
    41  	if err != nil {
    42  		return fmt.Errorf("Create %s: %v", binPath, err)
    43  	}
    44  	defer fd.Close()
    45  
    46  	url := DOWNLOAD_URL_PREFIX + fmt.Sprintf("%s-%s-%s", runtime.GOOS, runtime.GOARCH, version)
    47  	if runtime.GOOS == "windows" {
    48  		url += ".exe"
    49  	}
    50  	fmt.Print(url)
    51  	resp, err := http.Get(url)
    52  	if err != nil {
    53  		return fmt.Errorf("Download %s: %v", url, err)
    54  	}
    55  	defer resp.Body.Close()
    56  
    57  	if resp.StatusCode != 200 {
    58  		content, _ := ioutil.ReadAll(resp.Body)
    59  		return fmt.Errorf("Download %s %d: %s", url, resp.StatusCode, string(content))
    60  	}
    61  
    62  	_, err = io.Copy(fd, resp.Body)
    63  	if err != nil {
    64  		return fmt.Errorf("Download %s: copy %v", url, err)
    65  	}
    66  	return nil
    67  }
    68  
    69  func ChmodAndRename(src, dst string) error {
    70  	err := os.Chmod(src, 0755)
    71  	if err != nil {
    72  		return fmt.Errorf("chmod %s: %v", src, err)
    73  	}
    74  	err = os.Rename(src, dst)
    75  	if err != nil {
    76  		return fmt.Errorf("rename %s %s: %v", src, dst, err)
    77  	}
    78  	return nil
    79  }
    80  
    81  func Upgrade() {
    82  	lv, err := GetLatestVersion()
    83  
    84  	if err != nil {
    85  		PrintErrorAndExit("Find Latest Version: %v", err)
    86  	}
    87  
    88  	Print("Find Latest Version: %s", lv)
    89  	Print("Current Version: %s", VERSION)
    90  
    91  	if lv == VERSION {
    92  		return
    93  	}
    94  
    95  	binPath := GetCurrentBinPath()
    96  	tmpBinPath := binPath + ".upgrade"
    97  	err = DownloadBin(lv, tmpBinPath)
    98  	if err != nil {
    99  		PrintErrorAndExit("Download Binary %s: %v", VERSION, err)
   100  	}
   101  	Print("Download Binary %s: OK", VERSION)
   102  
   103  	err = ChmodAndRename(tmpBinPath, binPath)
   104  	if err != nil {
   105  		PrintErrorAndExit("Chmod %s: %v", binPath, err)
   106  	}
   107  	PrintErrorAndExit("Chmod %s: OK", binPath)
   108  
   109  	return
   110  }