diff --git a/cmd/start.go b/cmd/start.go index 5144ac6..e2747b6 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -36,6 +36,7 @@ const ( serverBaseUrlFlag = "server-base-url" portFlag = "port" verboseModeFlag = "verbose-mode" + updateFlag = "update" ) var ( @@ -47,6 +48,7 @@ var ( clientID string port int verboseMode bool + update bool ) var startCmd = &cobra.Command{ diff --git a/cmd/version.go b/cmd/version.go index 6fe9ba1..ece2fed 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -17,11 +17,16 @@ limitations under the License. package cmd import ( + "bytes" "fmt" + "os" + "os/exec" + "path/filepath" "runtime" "strings" "github.com/gookit/color" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -42,15 +47,94 @@ var versionCmd = &cobra.Command{ } func printVersion() { + _, mod := filepath.Split(os.Args[0]) cyan := color.FgCyan.Render info := []string{ - fmt.Sprintf("httpsignature-proxy %s", cyan(version)), + fmt.Sprintf(mod+" %s", cyan(version)), fmt.Sprintf("built with %s from commit %s at %s by %s", cyan(runtime.Version()), cyan(commit), cyan(date), cyan(builtBy)), } output := strings.Join(info, "\n") fmt.Println(output) + if update { + updateModule(mod) + } } func init() { + versionCmd.Flags().BoolVarP(&update, updateFlag, "u", false, "update proxy to the latest version") RootCmd.AddCommand(versionCmd) } + +func updateModule(mod string) { + env := os.Environ() + + if _, err := runWhich("brew", env); err != nil { + fmt.Println("Brew is not found. See https://brew.sh/ how to install brew") + return + } + + fmt.Print("Loading updates... ") + if _, err := runBrew([]string{"update"}, env); err != nil { + fmt.Println(err.Error()) + return + } + fmt.Println("Done") + + fmt.Print("Checking new " + mod + " versions... ") + newVersion, err := checkNewVersion(mod, env) + if err != nil { + fmt.Println(err.Error()) + return + } + fmt.Println("Done") + + if len(newVersion) == 0 { + fmt.Println("No new versions") + return + } + fmt.Print("A new version " + newVersion + " of " + mod + " is available. Updating... ") + if _, err := runBrew([]string{"upgrade", mod}, env); err != nil { + fmt.Println(err.Error()) + return + } + fmt.Println("Done") +} + +func runBrew(params []string, env []string) (string, error) { + return run("brew", params, env) +} + +func runWhich(what string, env []string) (string, error) { + str, err := run("which", []string{what}, env) + if err != nil { + return "", errors.Wrap(err, "RunWithError") + } + return strings.Trim(str, " \n"), nil +} + +func run(command string, params []string, env []string) (string, error) { + errBuf := &bytes.Buffer{} + outBuf := &bytes.Buffer{} + cmd := exec.Command(command, params...) + cmd.Stderr = errBuf + cmd.Stdout = outBuf + cmd.Env = env + if err := cmd.Run(); err != nil { + return "", errors.New(errBuf.String() + "\n" + err.Error()) + } + status := strings.TrimSpace(outBuf.String()) + return status, nil +} + +func checkNewVersion(c string, env []string) (string, error) { + status, err := runBrew([]string{"upgrade", c, "-n"}, env) + if err != nil { + return "", err + } + if len(status) == 0 { + return "", nil + } + lines := strings.Split(status, "\n") + p := strings.Split(lines[1], " ") + return strings.Join(p[1:], " "), nil +}