Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package go-mod-upgrade for openSUSE:Factory checked in at 2025-02-19 15:59:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/go-mod-upgrade (Old) and /work/SRC/openSUSE:Factory/.go-mod-upgrade.new.25061 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "go-mod-upgrade" Wed Feb 19 15:59:05 2025 rev:3 rq:1246821 version:0.11.0 Changes: -------- --- /work/SRC/openSUSE:Factory/go-mod-upgrade/go-mod-upgrade.changes 2024-04-09 16:52:28.423681036 +0200 +++ /work/SRC/openSUSE:Factory/.go-mod-upgrade.new.25061/go-mod-upgrade.changes 2025-02-19 15:59:59.199675682 +0100 @@ -1,0 +2,12 @@ +Mon Feb 17 15:35:12 UTC 2025 - [email protected] + +- Update to version 0.11.0: + * fix: goreleaser --clean flag instead of --rm-dist + * Bump golangci-lint and github actions versions + * refac: new internal package app + * refac: new internal package module + * go tool: add helper function to test if it's supported + * Add support for Go 1.24 tools (#60) + * Don't stop at first path when `force` flag is set + +------------------------------------------------------------------- Old: ---- go-mod-upgrade-0.10.0.obscpio New: ---- go-mod-upgrade-0.11.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ go-mod-upgrade.spec ++++++ --- /var/tmp/diff_new_pack.q9hc68/_old 2025-02-19 15:59:59.863703465 +0100 +++ /var/tmp/diff_new_pack.q9hc68/_new 2025-02-19 15:59:59.863703465 +0100 @@ -1,7 +1,7 @@ # # spec file for package go-mod-upgrade # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: go-mod-upgrade -Version: 0.10.0 +Version: 0.11.0 Release: 0 Summary: Update outdated Go dependencies interactively License: MIT @@ -36,7 +36,8 @@ %autosetup -D -a 1 %build -GOFLAGS="-buildmode=pie" GIT_TAG="v%{version}" go build ./... +# Temporarily use explicit build until goreleaser is packaged for openSUSE. +GOFLAGS="-buildmode=pie" GIT_TAG="v%{version}" go build -o go-mod-upgrade main.go %check ./go-mod-upgrade --version ++++++ _service ++++++ --- /var/tmp/diff_new_pack.q9hc68/_old 2025-02-19 15:59:59.891704637 +0100 +++ /var/tmp/diff_new_pack.q9hc68/_new 2025-02-19 15:59:59.895704804 +0100 @@ -4,7 +4,7 @@ <param name="url">https://github.com/oligot/go-mod-upgrade.git</param> <param name="scm">git</param> <param name="revision">main</param> - <param name="version">v0.10.0</param> + <param name="version">v0.11.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="versionrewrite-replacement">\1</param> ++++++ go-mod-upgrade-0.10.0.obscpio -> go-mod-upgrade-0.11.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/go-mod-upgrade-0.10.0/.github/workflows/go.yaml new/go-mod-upgrade-0.11.0/.github/workflows/go.yaml --- old/go-mod-upgrade-0.10.0/.github/workflows/go.yaml 2024-04-08 11:11:42.000000000 +0200 +++ new/go-mod-upgrade-0.11.0/.github/workflows/go.yaml 2025-02-16 15:17:57.000000000 +0100 @@ -10,7 +10,7 @@ - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: "~1.17" + go-version: "~1.18" - run: go test -race ./... build: name: Build @@ -22,7 +22,7 @@ - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: "~1.17" + go-version: "~1.18" - run: go build lint: name: Lint @@ -31,7 +31,7 @@ - uses: actions/checkout@v2 - uses: golangci/golangci-lint-action@v2 with: - version: v1.57 + version: v1.63 goreleaser: name: Release runs-on: ubuntu-20.04 @@ -52,6 +52,6 @@ uses: goreleaser/goreleaser-action@v2 with: version: latest - args: release --rm-dist + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/go-mod-upgrade-0.10.0/Makefile new/go-mod-upgrade-0.11.0/Makefile --- old/go-mod-upgrade-0.10.0/Makefile 2024-04-08 11:11:42.000000000 +0200 +++ new/go-mod-upgrade-0.11.0/Makefile 2025-02-16 15:17:57.000000000 +0100 @@ -2,7 +2,7 @@ goreleaser = ./bin/goreleaser $(golangci-lint): - curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.57.2 + curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.63.4 $(goreleaser): curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/go-mod-upgrade-0.10.0/internal/app/app.go new/go-mod-upgrade-0.11.0/internal/app/app.go --- old/go-mod-upgrade-0.10.0/internal/app/app.go 1970-01-01 01:00:00.000000000 +0100 +++ new/go-mod-upgrade-0.11.0/internal/app/app.go 2025-02-16 15:17:57.000000000 +0100 @@ -0,0 +1,397 @@ +package app + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + "time" + + "github.com/AlecAivazis/survey/v2" + term "github.com/AlecAivazis/survey/v2/terminal" + "github.com/Masterminds/semver/v3" + "github.com/apex/log" + "github.com/briandowns/spinner" + "github.com/fatih/color" + "github.com/urfave/cli/v2" + "golang.org/x/mod/modfile" + + "github.com/oligot/go-mod-upgrade/internal/module" +) + +func max(x, y int) int { + if x > y { + return x + } + return y +} + +// MultiSelect that doesn't show the answer +// It just reset the prompt and the answers are shown afterwards +type MultiSelect struct { + survey.MultiSelect +} + +func (m MultiSelect) Cleanup(config *survey.PromptConfig, val interface{}) error { + return m.Render("", nil) +} + +type AppEnv struct { + Verbose bool + Force bool + PageSize int + Hook string + Ignore cli.StringSlice +} + +func (app *AppEnv) Run() error { + if app.Verbose { + log.SetLevel(log.DebugLevel) + } + var paths []string + gw, err := exec.Command("go", "env", "GOWORK").Output() + if err != nil { + return err + } + gowork := strings.TrimSpace(string(gw)) + if gowork == "" || gowork == "off" { + cwd, err := os.Getwd() + if err != nil { + return err + } + paths = append(paths, cwd) + } else { + log.WithField("gowork", gowork).Info("Workspace mode") + content, err := os.ReadFile(gowork) + if err != nil { + return err + } + work, err := modfile.ParseWork("go.work", content, nil) + if err != nil { + return err + } + for _, use := range work.Use { + if use != nil { + paths = append(paths, use.Path) + } + } + } + + for _, path := range paths { + cwd, err := os.Getwd() + if err != nil { + return err + } + dir := path + if !filepath.IsAbs(path) { + dir = filepath.Join(filepath.Dir(gowork), path) + } + log.WithField("dir", dir).Info("Using directory") + if err := os.Chdir(dir); err != nil { + return err + } + modules, err := discoverModules(app.Ignore.Value()) + if err != nil { + return err + } + supported, err := toolsSupported() + if err != nil { + return err + } + log.WithFields(log.Fields{ + "supported": supported, + }).Debug("Tool support") + if supported { + toolModules, err := discoverTools(app.Ignore.Value()) + if err != nil { + return err + } + modules = append(modules, toolModules...) + } + if len(modules) > 0 { + if app.Force { + log.Debug("Update all modules in non-interactive mode...") + } else { + modules = choose(modules, app.PageSize) + } + update(modules, app.Hook) + } else { + fmt.Println("All modules are up to date") + } + if err := os.Chdir(cwd); err != nil { + return err + } + } + return nil +} + +func discoverModules(ignoreNames []string) ([]module.Module, error) { + s := spinner.New(spinner.CharSets[14], 100*time.Millisecond) + if err := s.Color("yellow"); err != nil { + return nil, err + } + s.Suffix = " Discovering modules..." + s.Start() + + args := []string{ + "list", + "-u", + "-mod=readonly", + "-f", + "'{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}: {{.Version}} -> {{.Update.Version}}{{end}}'", + "-m", + "all", + } + + cmd := exec.Command("go", args...) + // Disable Go workspace mode, otherwise this can cause trouble + // See issue https://github.com/oligot/go-mod-upgrade/issues/35 + cmd.Env = append(os.Environ(), "GOWORK=off") + list, err := cmd.Output() + s.Stop() + + // Clear line + fmt.Printf("\r%s\r", strings.Repeat(" ", len(s.Suffix)+1)) + + if err != nil { + return nil, fmt.Errorf("Error running go command to discover modules: %w", err) + } + + split := strings.Split(string(list), "\n") + modules := []module.Module{} + re := regexp.MustCompile(`'(.+): (.+) -> (.+)'`) + for _, x := range split { + if x != "''" && x != "" { + matched := re.FindStringSubmatch(x) + if len(matched) < 4 { + return nil, fmt.Errorf("Couldn't parse module %s", x) + } + name, from, to := matched[1], matched[2], matched[3] + log.WithFields(log.Fields{ + "name": name, + "from": from, + "to": to, + }).Debug("Found module") + if shouldIgnore(name, from, to, ignoreNames) { + continue + } + fromversion, err := semver.NewVersion(from) + if err != nil { + return nil, err + } + toversion, err := semver.NewVersion(to) + if err != nil { + return nil, err + } + d := module.Module{ + Name: name, + From: fromversion, + To: toversion, + } + modules = append(modules, d) + } + } + return modules, nil +} + +func discoverTools(ignoreNames []string) ([]module.Module, error) { + + s := spinner.New(spinner.CharSets[14], 100*time.Millisecond) + if err := s.Color("yellow"); err != nil { + return nil, err + } + s.Suffix = " Discovering tool modules..." + s.Start() + + toolsArgs := []string{ + "list", + "-f", + "{{if .Module}}{{.Module.Path}} {{.Module.Version}}{{end}}", + "tool", + } + cmd := exec.Command("go", toolsArgs...) + cmd.Env = append(os.Environ(), "GOWORK=off") + toolsOutput, err := cmd.Output() + + s.Stop() + fmt.Printf("\r%s\r", strings.Repeat(" ", len(s.Suffix)+1)) + + if err != nil { + if strings.Contains(err.Error(), "matched no packages") { + return []module.Module{}, nil + } + log.WithFields(log.Fields{ + "error": err, + "args": cmd.Args, + }).Error("error listing tools") + return nil, fmt.Errorf("error listing tools: %w", err) + } + + var modules []module.Module + tools := strings.Split(strings.TrimSpace(string(toolsOutput)), "\n") + for _, tool := range tools { + if tool == "" { + continue + } + + parts := strings.Fields(tool) + if len(parts) == 1 { + continue // local tool + } + if len(parts) != 2 { + return nil, fmt.Errorf("invalid tool format: %s", tool) + } + toolPath, currentVersion := parts[0], parts[1] + + // Check for updates + updateArgs := []string{ + "list", + "-m", + "-f", + "{{if .Update}}{{.Update.Version}}{{end}}", + "-u", + toolPath, + } + updateCmd := exec.Command("go", updateArgs...) + updateCmd.Env = append(os.Environ(), "GOWORK=off") + if updateOutput, err := updateCmd.Output(); err == nil { + newVersion := strings.TrimSpace(string(updateOutput)) + if newVersion != "" && newVersion != currentVersion { + fromVersion, err := semver.NewVersion(currentVersion) + if err != nil { + return nil, fmt.Errorf("invalid tool version: %s -> %s: %w", toolPath, currentVersion, err) + } + toVersion, err := semver.NewVersion(newVersion) + if err != nil { + return nil, fmt.Errorf("invalid tool update version: %s -> %s: %w", toolPath, newVersion, err) + } + log.WithFields(log.Fields{ + "tool": toolPath, + "from": currentVersion, + "to": newVersion, + }).Debug("Found tool module update available") + if shouldIgnore(toolPath, currentVersion, newVersion, ignoreNames) { + continue + } + modules = append(modules, module.Module{ + Name: toolPath, + From: fromVersion, + To: toVersion, + }) + } + } + } + + return modules, nil +} + +func toolsSupported() (bool, error) { + gv, err := exec.Command("go", "version").Output() + if err != nil { + return false, err + } + + version := strings.TrimSpace(string(gv)) + re := regexp.MustCompile(`go version go([\d\.]+)(rc.+)?`) + matched := re.FindStringSubmatch(version) + if len(matched) < 2 { + return false, fmt.Errorf("Couldn't parse go version %s", version) + } + + goversion, err := semver.NewVersion(matched[1]) + if err != nil { + return false, err + } + log.WithFields(log.Fields{ + "major": goversion.Major(), + "minor": goversion.Minor(), + }).Debug("Go version") + if goversion.Major() >= 1 && goversion.Minor() >= 24 { + return true, nil + } + return false, nil +} + +func shouldIgnore(name, from, to string, ignoreNames []string) bool { + for _, ig := range ignoreNames { + if strings.Contains(name, ig) { + c := color.New(color.FgYellow).SprintFunc() + log.WithFields(log.Fields{ + "name": name, + "from": from, + "to": to, + }).Debug(c("Ignore module")) + return true + } + } + return false +} + +func choose(modules []module.Module, pageSize int) []module.Module { + maxName := 0 + maxFrom := 0 + for _, x := range modules { + maxName = max(maxName, len(x.Name)) + maxFrom = max(maxFrom, len(x.From.String())) + } + options := []string{} + for _, x := range modules { + from := x.FormatFrom(maxFrom) + option := fmt.Sprintf("%s %s -> %s", x.FormatName(maxName), from, x.FormatTo()) + options = append(options, option) + } + prompt := &MultiSelect{ + survey.MultiSelect{ + Message: "Choose which modules to update", + Options: options, + PageSize: pageSize, + }, + } + choice := []int{} + err := survey.AskOne(prompt, &choice) + if err == term.InterruptErr { + log.Info("Bye") + os.Exit(0) + } else if err != nil { + log.WithError(err).Error("Choose failed") + os.Exit(1) + } + updates := []module.Module{} + for _, x := range choice { + updates = append(updates, modules[x]) + } + return updates +} + +func update(modules []module.Module, hook string) { + for _, x := range modules { + fmt.Fprintf(color.Output, "Updating %s to version %s...\n", x.FormatName(len(x.Name)), x.FormatTo()) + out, err := exec.Command("go", "get", "-d", x.Name).CombinedOutput() + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "name": x.Name, + "out": string(out), + }).Error("Error while updating module") + } + if hook != "" { + out, err := exec.Command( + hook, + x.Name, + x.From.String(), + x.To.String(), + ).CombinedOutput() + if err != nil { + log.WithFields(log.Fields{ + "error": err, + "hook": hook, + "out": string(out), + }).Error("Error while executing hook") + os.Exit(1) + } + log.Info(string(out)) + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/go-mod-upgrade-0.10.0/internal/module/module.go new/go-mod-upgrade-0.11.0/internal/module/module.go --- old/go-mod-upgrade-0.10.0/internal/module/module.go 1970-01-01 01:00:00.000000000 +0100 +++ new/go-mod-upgrade-0.11.0/internal/module/module.go 2025-02-16 15:17:57.000000000 +0100 @@ -0,0 +1,76 @@ +package module + +import ( + "bytes" + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/fatih/color" +) + +func padRight(str string, length int) string { + if len(str) >= length { + return str + } + return str + strings.Repeat(" ", length-len(str)) +} + +type Module struct { + Name string + From *semver.Version + To *semver.Version +} + +func (mod *Module) FormatName(length int) string { + c := color.New(color.FgWhite).SprintFunc() + from := mod.From + to := mod.To + if from.Minor() != to.Minor() { + c = color.New(color.FgYellow).SprintFunc() + } + if from.Patch() != to.Patch() { + c = color.New(color.FgGreen).SprintFunc() + } + if from.Prerelease() != to.Prerelease() { + c = color.New(color.FgRed).SprintFunc() + } + return c(padRight(mod.Name, length)) +} + +func (mod *Module) FormatFrom(length int) string { + c := color.New(color.FgBlue).SprintFunc() + return c(padRight(mod.From.String(), length)) +} + +func (mod *Module) FormatTo() string { + green := color.New(color.FgGreen).SprintFunc() + var buf bytes.Buffer + from := mod.From + to := mod.To + same := true + fmt.Fprintf(&buf, "%d.", to.Major()) + if from.Minor() == to.Minor() { + fmt.Fprintf(&buf, "%d.", to.Minor()) + } else { + fmt.Fprintf(&buf, "%s%s", green(to.Minor()), green(".")) + same = false + } + if from.Patch() == to.Patch() && same { + fmt.Fprintf(&buf, "%d", to.Patch()) + } else { + fmt.Fprintf(&buf, "%s", green(to.Patch())) + same = false + } + if to.Prerelease() != "" { + if from.Prerelease() == to.Prerelease() && same { + fmt.Fprintf(&buf, "-%s", to.Prerelease()) + } else { + fmt.Fprintf(&buf, "-%s", green(to.Prerelease())) + } + } + if to.Metadata() != "" { + fmt.Fprintf(&buf, "%s%s", green("+"), green(to.Metadata())) + } + return buf.String() +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/go-mod-upgrade-0.10.0/main.go new/go-mod-upgrade-0.11.0/main.go --- old/go-mod-upgrade-0.10.0/main.go 2024-04-08 11:11:42.000000000 +0200 +++ new/go-mod-upgrade-0.11.0/main.go 2025-02-16 15:17:57.000000000 +0100 @@ -1,26 +1,17 @@ package main import ( - "bytes" "errors" "fmt" "os" "os/exec" - "path/filepath" - "regexp" "runtime/debug" - "strings" - "time" - "github.com/AlecAivazis/survey/v2" - term "github.com/AlecAivazis/survey/v2/terminal" - "github.com/Masterminds/semver/v3" "github.com/apex/log" logcli "github.com/apex/log/handlers/cli" - "github.com/briandowns/spinner" - "github.com/fatih/color" "github.com/urfave/cli/v2" - "golang.org/x/mod/modfile" + + "github.com/oligot/go-mod-upgrade/internal/app" ) var ( @@ -31,314 +22,6 @@ builtBy = "" ) -func max(x, y int) int { - if x > y { - return x - } - return y -} - -func padRight(str string, length int) string { - if len(str) >= length { - return str - } - return str + strings.Repeat(" ", length-len(str)) -} - -func formatName(module Module, length int) string { - c := color.New(color.FgWhite).SprintFunc() - from := module.from - to := module.to - if from.Minor() != to.Minor() { - c = color.New(color.FgYellow).SprintFunc() - } - if from.Patch() != to.Patch() { - c = color.New(color.FgGreen).SprintFunc() - } - if from.Prerelease() != to.Prerelease() { - c = color.New(color.FgRed).SprintFunc() - } - return c(padRight(module.name, length)) -} - -func formatFrom(from *semver.Version, length int) string { - c := color.New(color.FgBlue).SprintFunc() - return c(padRight(from.String(), length)) -} - -func formatTo(module Module) string { - green := color.New(color.FgGreen).SprintFunc() - var buf bytes.Buffer - from := module.from - to := module.to - same := true - fmt.Fprintf(&buf, "%d.", to.Major()) - if from.Minor() == to.Minor() { - fmt.Fprintf(&buf, "%d.", to.Minor()) - } else { - fmt.Fprintf(&buf, "%s%s", green(to.Minor()), green(".")) - same = false - } - if from.Patch() == to.Patch() && same { - fmt.Fprintf(&buf, "%d", to.Patch()) - } else { - fmt.Fprintf(&buf, "%s", green(to.Patch())) - same = false - } - if to.Prerelease() != "" { - if from.Prerelease() == to.Prerelease() && same { - fmt.Fprintf(&buf, "-%s", to.Prerelease()) - } else { - fmt.Fprintf(&buf, "-%s", green(to.Prerelease())) - } - } - if to.Metadata() != "" { - fmt.Fprintf(&buf, "%s%s", green("+"), green(to.Metadata())) - } - return buf.String() -} - -type Module struct { - name string - from *semver.Version - to *semver.Version -} - -// MultiSelect that doesn't show the answer -// It just reset the prompt and the answers are shown afterwards -type MultiSelect struct { - survey.MultiSelect -} - -func (m MultiSelect) Cleanup(config *survey.PromptConfig, val interface{}) error { - return m.Render("", nil) -} - -type appEnv struct { - verbose bool - force bool - pageSize int - hook string - ignore cli.StringSlice -} - -func (app *appEnv) run() error { - if app.verbose { - log.SetLevel(log.DebugLevel) - } - var paths []string - gw, err := exec.Command("go", "env", "GOWORK").Output() - if err != nil { - return err - } - gowork := strings.TrimSpace(string(gw)) - if gowork == "" || gowork == "off" { - cwd, err := os.Getwd() - if err != nil { - return err - } - paths = append(paths, cwd) - } else { - log.WithField("gowork", gowork).Info("Workspace mode") - content, err := os.ReadFile(gowork) - if err != nil { - return err - } - work, err := modfile.ParseWork("go.work", content, nil) - if err != nil { - return err - } - for _, use := range work.Use { - if use != nil { - paths = append(paths, use.Path) - } - } - } - - for _, path := range paths { - cwd, err := os.Getwd() - if err != nil { - return err - } - dir := path - if !filepath.IsAbs(path) { - dir = filepath.Join(filepath.Dir(gowork), path) - } - log.WithField("dir", dir).Info("Using directory") - if err := os.Chdir(dir); err != nil { - return err - } - modules, err := discover(app.ignore.Value()) - if err != nil { - return err - } - if app.force { - log.Debug("Update all modules in non-interactive mode...") - update(modules, app.hook) - return nil - } - if len(modules) > 0 { - modules = choose(modules, app.pageSize) - update(modules, app.hook) - } else { - fmt.Println("All modules are up to date") - } - if err := os.Chdir(cwd); err != nil { - return err - } - } - return nil -} - -func discover(ignoreNames []string) ([]Module, error) { - s := spinner.New(spinner.CharSets[14], 100*time.Millisecond) - if err := s.Color("yellow"); err != nil { - return nil, err - } - s.Suffix = " Discovering modules..." - s.Start() - - args := []string{ - "list", - "-u", - "-mod=readonly", - "-f", - "'{{if (and (not (or .Main .Indirect)) .Update)}}{{.Path}}: {{.Version}} -> {{.Update.Version}}{{end}}'", - "-m", - "all", - } - - cmd := exec.Command("go", args...) - cmd.Env = os.Environ() - // Disable Go workspace mode, otherwise this can cause trouble - // See issue https://github.com/oligot/go-mod-upgrade/issues/35 - cmd.Env = append(cmd.Env, "GOWORK=off") - list, err := cmd.Output() - s.Stop() - - // Clear line - fmt.Printf("\r%s\r", strings.Repeat(" ", len(s.Suffix)+1)) - - if err != nil { - return nil, fmt.Errorf("Error running go command to discover modules: %w", err) - } - - split := strings.Split(string(list), "\n") - modules := []Module{} - re := regexp.MustCompile(`'(.+): (.+) -> (.+)'`) - for _, x := range split { - if x != "''" && x != "" { - matched := re.FindStringSubmatch(x) - if len(matched) < 4 { - return nil, fmt.Errorf("Couldn't parse module %s", x) - } - name, from, to := matched[1], matched[2], matched[3] - log.WithFields(log.Fields{ - "name": name, - "from": from, - "to": to, - }).Debug("Found module") - if shouldIgnore(name, from, to, ignoreNames) { - continue - } - fromversion, err := semver.NewVersion(from) - if err != nil { - return nil, err - } - toversion, err := semver.NewVersion(to) - if err != nil { - return nil, err - } - d := Module{ - name: name, - from: fromversion, - to: toversion, - } - modules = append(modules, d) - } - } - return modules, nil -} - -func shouldIgnore(name, from, to string, ignoreNames []string) bool { - for _, ig := range ignoreNames { - if strings.Contains(name, ig) { - c := color.New(color.FgYellow).SprintFunc() - log.WithFields(log.Fields{ - "name": name, - "from": from, - "to": to, - }).Debug(c("Ignore module")) - return true - } - } - return false -} - -func choose(modules []Module, pageSize int) []Module { - maxName := 0 - maxFrom := 0 - maxTo := 0 - for _, x := range modules { - maxName = max(maxName, len(x.name)) - maxFrom = max(maxFrom, len(x.from.String())) - maxTo = max(maxTo, len(x.to.String())) - } - options := []string{} - for _, x := range modules { - from := formatFrom(x.from, maxFrom) - option := fmt.Sprintf("%s %s -> %s", formatName(x, maxName), from, formatTo(x)) - options = append(options, option) - } - prompt := &MultiSelect{ - survey.MultiSelect{ - Message: "Choose which modules to update", - Options: options, - PageSize: pageSize, - }, - } - choice := []int{} - err := survey.AskOne(prompt, &choice) - if err == term.InterruptErr { - log.Info("Bye") - os.Exit(0) - } else if err != nil { - log.WithError(err).Error("Choose failed") - os.Exit(1) - } - updates := []Module{} - for _, x := range choice { - updates = append(updates, modules[x]) - } - return updates -} - -func update(modules []Module, hook string) { - for _, x := range modules { - fmt.Fprintf(color.Output, "Updating %s to version %s...\n", formatName(x, len(x.name)), formatTo(x)) - out, err := exec.Command("go", "get", "-d", x.name).CombinedOutput() - if err != nil { - log.WithFields(log.Fields{ - "error": err, - "name": x.name, - "out": string(out), - }).Error("Error while updating module") - } - if hook != "" { - out, err := exec.Command(hook, x.name, x.from.String(), x.to.String()).CombinedOutput() - if err != nil { - log.WithFields(log.Fields{ - "error": err, - "hook": hook, - "out": string(out), - }).Error("Error while executing hook") - os.Exit(1) - } - log.Info(string(out)) - } - } -} - func versionPrinter(c *cli.Context) { version := c.App.Version if commit != "" { @@ -362,7 +45,7 @@ func main() { var ( - app = &appEnv{} + app = &app.AppEnv{} ) log.SetHandler(logcli.Default) @@ -383,36 +66,36 @@ Aliases: []string{"p"}, Value: 10, Usage: "Specify page size", - Destination: &app.pageSize, + Destination: &app.PageSize, }, &cli.BoolFlag{ Name: "force", Aliases: []string{"f"}, Value: false, Usage: "Force update all modules in non-interactive mode", - Destination: &app.force, + Destination: &app.Force, }, &cli.BoolFlag{ Name: "verbose", Aliases: []string{"v"}, Value: false, Usage: "Verbose mode", - Destination: &app.verbose, + Destination: &app.Verbose, }, &cli.PathFlag{ Name: "hook", Usage: "Hook to execute for each updated module", - Destination: &app.hook, + Destination: &app.Hook, }, &cli.StringSliceFlag{ Name: "ignore", Aliases: []string{"i"}, Usage: "Ignore modules matching the given regular expression", - Destination: &app.ignore, + Destination: &app.Ignore, }, }, Action: func(c *cli.Context) error { - return app.run() + return app.Run() }, UseShortOptionHandling: true, EnableBashCompletion: true, ++++++ go-mod-upgrade.obsinfo ++++++ --- /var/tmp/diff_new_pack.q9hc68/_old 2025-02-19 16:00:00.011709658 +0100 +++ /var/tmp/diff_new_pack.q9hc68/_new 2025-02-19 16:00:00.015709825 +0100 @@ -1,5 +1,5 @@ name: go-mod-upgrade -version: 0.10.0 -mtime: 1712567502 -commit: b738e47383b91fedcb67494e5b8b28ac5b10e800 +version: 0.11.0 +mtime: 1739715477 +commit: 64bfaf3912b266594fe5b39aba0df6e54654286e ++++++ vendor.tar.gz ++++++
