128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
"github.com/AlecAivazis/survey/v2/terminal"
|
|
"github.com/Masterminds/semver/v3"
|
|
"github.com/fatih/color"
|
|
"github.com/minio/selfupdate"
|
|
)
|
|
|
|
var UPDATEURL = "http://gozilla.fhi.mpg.de/goca"
|
|
|
|
// Color function variables matching tools.go in dns
|
|
var Crb func(...interface{}) string = color.New(color.Bold, color.FgRed).SprintFunc()
|
|
var Cgb func(...interface{}) string = color.New(color.Bold, color.FgGreen).SprintFunc()
|
|
var Cwb func(...interface{}) string = color.New(color.Bold, color.FgWhite).SprintFunc()
|
|
|
|
func SF(format string, a ...any) string {
|
|
return fmt.Sprintf(format, a...)
|
|
}
|
|
|
|
func PE(msg ...string) (n int, err error) {
|
|
if len(msg) == 2 {
|
|
return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Crb("ERROR"), Cwb(msg[0]), msg[1])
|
|
}
|
|
return fmt.Fprintf(os.Stdout, "%s: %s\n", Crb("ERROR"), Cwb(msg[0]))
|
|
}
|
|
|
|
func PO(msg ...string) (n int, err error) {
|
|
if len(msg) == 2 {
|
|
return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Cgb("OK"), Cwb(msg[0]), msg[1])
|
|
}
|
|
return fmt.Fprintf(os.Stdout, "%s: %s\n", Cgb("OK"), Cwb(msg[0]))
|
|
}
|
|
|
|
func checkforupdate(URL string) { // ----------------------------------------------------- check for new version
|
|
prg := prgname()
|
|
resp, err := http.Get(URL + "/version.txt")
|
|
if err == nil {
|
|
scanner := bufio.NewScanner(resp.Body)
|
|
if scanner.Scan() {
|
|
lversion := strings.TrimSpace(scanner.Text())
|
|
sv_version, err := semver.NewVersion(Version)
|
|
if err == nil {
|
|
sv_lversion, err := semver.NewVersion(lversion)
|
|
if err == nil {
|
|
if sv_lversion.GreaterThan(sv_version) {
|
|
ans := Yesno(SF("new '%s' version found (%s -> %s), update now?",
|
|
prg, sv_version, sv_lversion), true, false)
|
|
if ans {
|
|
updateurl := SF("%s/%s_%s_%s_%s", URL, prg, lversion, runtime.GOOS, runtime.GOARCH)
|
|
|
|
if err := doupdate(updateurl); err != nil {
|
|
PE(SF("Update failed: %v\n", err))
|
|
os.Exit(1)
|
|
}
|
|
PO("Update successful!", "please run your last command again")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
resp.Body.Close()
|
|
}
|
|
}
|
|
|
|
func doupdate(url string) error { // ----------------------------------------------------------------- do update
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("server returned status: %v", resp.Status)
|
|
}
|
|
err = selfupdate.Apply(resp.Body, selfupdate.Options{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Yesno(msg string, def bool, overwrite bool) bool { // -------------------------- AlecAivazis/survey: yes/no
|
|
if overwrite {
|
|
return true
|
|
}
|
|
|
|
var err error
|
|
tmp := ""
|
|
if def {
|
|
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"Yes", "No"}}, &tmp)
|
|
} else {
|
|
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"No", "Yes"}}, &tmp)
|
|
}
|
|
|
|
if err != nil {
|
|
if err == terminal.InterruptErr {
|
|
fmt.Fprintln(os.Stdout, Crb("Interrupted."))
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
if tmp == "Yes" {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
func prgname() string { // ---------------------------------------------------------------- program name
|
|
exepath, err := os.Executable()
|
|
if err != nil {
|
|
PE(SF("Error getting executable path: %s", err))
|
|
return ""
|
|
}
|
|
exename := filepath.Base(exepath)
|
|
return exename
|
|
}
|