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 }