Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #145 by adding interactivity #147

Merged
merged 5 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,18 @@ Reload config.

**All DONE!**

### Confirm
### Quick Usage

Just use command `gobrew` from any dir.

<p align="center">
<a href="https://github.com/kevincobain2000/gobrew">
<img alt="gobrew command" src="https://imgur.com/X6P3r8L.png">
</a>
</p>

```sh
gobrew help
```

### Usage
### Full Usage

Will install and set Go

Expand Down Expand Up @@ -333,3 +338,4 @@ alias cd='builtin cd "$@" && ls go.mod 2> /dev/null && gobrew use mod'
- v1.9.0 - v1.8.6 ~ v1.9.0, updates colors packages, fixes UT issues for Github status codes
- v1.9.1 - Minor logging fixes
- v1.9.2 - Minor log message updated
- v1.9.4 - `gobrew` interactive
12 changes: 9 additions & 3 deletions cmd/gobrew/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ var allowedArgs = []string{
"install",
"use",
"uninstall",
"interactive",
"noninteractive",
"prune",
"version",
"self-update",
Expand All @@ -42,11 +44,11 @@ func init() {
flag.Parse()
args = flag.Args()
if len(args) == 0 {
log.Print(usage())
return
actionArg = "interactive"
} else {
actionArg = args[0]
}

actionArg = args[0]
if len(args) == 2 {
versionArg = args[1]
versionArgSlice := strings.Split(versionArg, ".")
Expand All @@ -64,6 +66,10 @@ func init() {
func main() {
gb := gobrew.NewGoBrew()
switch actionArg {
case "interactive", "info":
gb.Interactive(true)
case "noninteractive":
gb.Interactive(false)
case "h", "help":
log.Print(usage())
case "ls", "list":
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ require (
github.com/c4milo/unpackit v1.0.0
github.com/gookit/color v1.5.4
github.com/schollz/progressbar/v3 v3.13.1
gotest.tools v2.2.0+incompatible
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dsnet/compress v0.0.1 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/klauspost/compress v1.4.1 // indirect
github.com/klauspost/cpuid v1.2.0 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/hooklift/assert v0.1.0 h1:UZzFxx5dSb9aBtvMHTtnPuvFnBvcEhHTPb9+0+jpEjs=
Expand Down Expand Up @@ -51,7 +49,7 @@ golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
119 changes: 116 additions & 3 deletions gobrew.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,107 @@ func NewGoBrewDirectory(homeDir string) GoBrew {
return gb
}

func (gb *GoBrew) Interactive(ask bool) {
currentVersion := gb.CurrentVersion()
currentMajorVersion := ExtractMajorVersion(currentVersion)

latestVersion := gb.getLatestVersion()
latestMajorVersion := ExtractMajorVersion(latestVersion)

modVersion := ""
if gb.hasModFile() {
modVersion = gb.getModVersion()
}

if modVersion == "" {
modVersion = "None"
}

fmt.Println()

if currentVersion == "" {
currentVersion = "None"
color.Warnln("GO Installed Version", ".......", currentVersion)
} else {
labels := []string{}
if modVersion != "None" && currentMajorVersion != modVersion {
labels = append(labels, "not same as go.mod")
}
if currentVersion != latestVersion {
labels = append(labels, "not latest")
}
label := ""
if len(labels) > 0 {
label = "(" + strings.Join(labels, ", ") + ")"
}
if label != "" {
label = " " + color.FgRed.Render(label)
}
color.Successln("GO Installed Version", ".......", currentVersion+label)
}

if modVersion != "None" && latestMajorVersion != modVersion {
label := " " + color.FgYellow.Render("(not latest)")
color.Successln("GO go.mod Version", " .......", modVersion+label)
} else {
color.Successln("GO go.mod Version", " .......", modVersion)
}

color.Successln("GO Latest Version", " .......", latestVersion)
fmt.Println()

if currentVersion == "None" {
color.Warnln("GO is not installed.")
c := true
if ask {
c = AskForConfirmation("Do you want to use latest GO version (" + latestVersion + ")?")
}
if c {
gb.Install(latestVersion)
gb.Use(latestVersion)
}
return
}

if currentMajorVersion != modVersion {
color.Warnf("GO Installed Version (%s) and go.mod Version (%s) are different.\n", currentMajorVersion, modVersion)
c := true
if ask {
c = AskForConfirmation("Do you want to use GO version same as go.mod version (" + modVersion + "@latest)?")
}
if c {
gb.Install(modVersion + "@latest")
juev marked this conversation as resolved.
Show resolved Hide resolved
gb.Use(modVersion + "@latest")
}
return
}

if currentVersion != latestVersion {
color.Warnf("GO Installed Version (%s) and GO Latest Version (%s) are different.\n", currentVersion, latestVersion)
c := true
if ask {
c = AskForConfirmation("Do you want to update GO to latest version (" + latestVersion + ")?")
}
if c {
gb.Install(latestVersion)
gb.Use(latestVersion)
}
return
}
}

func (gb *GoBrew) getLatestVersion() string {
getGolangVersions := gb.getGolangVersions()
// loop through reverse and ignore beta and rc versions to get latest version
for i := len(getGolangVersions) - 1; i >= 0; i-- {
r := regexp.MustCompile("beta.*|rc.*")
matches := r.FindAllString(getGolangVersions[i], -1)
if len(matches) == 0 {
return strings.ReplaceAll(getGolangVersions[i], "go", "")
}
}
return ""
}
func (gb *GoBrew) getArch() string {
return runtime.GOOS + "-" + runtime.GOARCH
}
Expand Down Expand Up @@ -247,7 +348,7 @@ func (gb *GoBrew) getGroupedVersion(versions []string, print bool) map[string][]
gb.print("\t", print)
} else {
if print {
color.Infop(lookupKey)
color.Successp(lookupKey)
}
gb.print("\t", print)
}
Expand Down Expand Up @@ -465,6 +566,18 @@ func (gb *GoBrew) judgeVersion(version string) string {
return version
}

func (gb *GoBrew) hasModFile() bool {
modFilePath := filepath.Join("go.mod")
_, err := os.Stat(modFilePath)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}

// read go.mod file and extract version
// Do not use go to get the version as go list -m -f '{{.GoVersion}}'
// Because go might not be installed
Expand Down Expand Up @@ -514,7 +627,7 @@ func (gb *GoBrew) Version(currentVersion string) {

// Upgrade of GoBrew
func (gb *GoBrew) Upgrade(currentVersion string) {
if "v"+currentVersion == gb.getLatestVersion() {
if "v"+currentVersion == gb.getGobrewVersion() {
color.Infoln("[INFO] your version is already newest")
return
}
Expand Down Expand Up @@ -638,7 +751,7 @@ func (gb *GoBrew) changeSymblinkGo(version string) {
utils.CheckError(os.Symlink(versionGoDir, gb.currentGoDir), "==> [Error]: symbolic link failed")
}

func (gb *GoBrew) getLatestVersion() string {
func (gb *GoBrew) getGobrewVersion() string {
url := "https://api.github.com/repos/kevincobain2000/gobrew/releases/latest"
data := doRequest(url)
if len(data) == 0 {
Expand Down
45 changes: 43 additions & 2 deletions gobrew_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"

"gotest.tools/assert"
"github.com/stretchr/testify/assert"
)

func TestNewGobrewHomeDirUsesUserHomeDir(t *testing.T) {
Expand Down Expand Up @@ -196,7 +197,7 @@ func TestDoNotUpgradeLatestVersion(t *testing.T) {
}
binaryFile := filepath.Join(binaryDir, baseName)

currentVersion := gb.getLatestVersion()
currentVersion := gb.getGobrewVersion()

if currentVersion == "" {
t.Skip("could not determine the current version")
Expand All @@ -208,3 +209,43 @@ func TestDoNotUpgradeLatestVersion(t *testing.T) {
t.Errorf("unexpected upgrade of latest version")
}
}

func TestInteractive(t *testing.T) {
tempDir := filepath.Join(os.TempDir(), "gobrew-test-interactive")
err := os.MkdirAll(tempDir, os.ModePerm)
if err != nil {
t.Skip("could not create directory for gobrew update:", err)
return
}

defer func() {
_ = os.RemoveAll(tempDir)
}()

gb := NewGoBrewDirectory(tempDir)
currentVersion := gb.CurrentVersion()
latestVersion := gb.getLatestVersion()
// modVersion := gb.getModVersion()
assert.Equal(t, "", currentVersion)
assert.NotEqual(t, currentVersion, latestVersion)

ask := false
gb.Interactive(ask)

currentVersion = gb.CurrentVersion()
// remove string private from currentVersion (for macOS) due to /private/var symlink issue
currentVersion = strings.Replace(currentVersion, "private", "", -1)
assert.Equal(t, currentVersion, latestVersion)

gb.Install("1.16.5") // we know, it is not latest
gb.Use("1.16.5")
currentVersion = gb.CurrentVersion()
currentVersion = strings.Replace(currentVersion, "private", "", -1)
assert.Equal(t, "1.16.5", currentVersion)
assert.NotEqual(t, currentVersion, latestVersion)

gb.Interactive(ask)
currentVersion = gb.CurrentVersion()
currentVersion = strings.Replace(currentVersion, "private", "", -1)
assert.Equal(t, currentVersion, latestVersion)
}
47 changes: 47 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package gobrew

import (
"bufio"
"fmt"
"log"
"os"
"strings"

"github.com/gookit/color"
)

func ExtractMajorVersion(version string) string {
parts := strings.Split(version, ".")
if len(parts) < 2 {
return ""
}
// remove rc and beta
parts[1] = strings.Split(parts[1], "rc")[0]
parts[1] = strings.Split(parts[1], "beta")[0]

// Take the first two parts and join them back with a period to create the new version.
majorVersion := strings.Join(parts[:2], ".")
return majorVersion
}

func AskForConfirmation(s string) bool {
reader := bufio.NewReader(os.Stdin)

for {
fmt.Printf("%s ", s)
color.Successf("[y/n]: ")

response, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}

response = strings.ToLower(strings.TrimSpace(response))

if response == "y" || response == "yes" {
return true
} else if response == "" || response == "n" || response == "no" {
return false
}
}
}