Skip to content

Commit

Permalink
Merge pull request #147 from kevincobain2000/feature/gobrew
Browse files Browse the repository at this point in the history
Fixes #145 by adding interactivity
  • Loading branch information
kevincobain2000 committed Nov 1, 2023
2 parents b48f97f + ed6fb34 commit 1859f1e
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 19 deletions.
16 changes: 11 additions & 5 deletions README.md
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
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
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
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
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")
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
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
@@ -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
}
}
}

0 comments on commit 1859f1e

Please sign in to comment.