diff --git a/README.md b/README.md
index 31b9493..2237156 100644
--- a/README.md
+++ b/README.md
@@ -69,13 +69,18 @@ Reload config.
**All DONE!**
-### Confirm
+### Quick Usage
+
+Just use command `gobrew` from any dir.
+
+
+
+
+
+
-```sh
-gobrew help
-```
-### Usage
+### Full Usage
Will install and set Go
@@ -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
diff --git a/cmd/gobrew/main.go b/cmd/gobrew/main.go
index a3ecb87..e92b34e 100644
--- a/cmd/gobrew/main.go
+++ b/cmd/gobrew/main.go
@@ -25,6 +25,8 @@ var allowedArgs = []string{
"install",
"use",
"uninstall",
+ "interactive",
+ "noninteractive",
"prune",
"version",
"self-update",
@@ -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, ".")
@@ -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":
diff --git a/go.mod b/go.mod
index 881b7c8..e486b3c 100644
--- a/go.mod
+++ b/go.mod
@@ -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
)
diff --git a/go.sum b/go.sum
index 08485b1..598070f 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
@@ -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=
diff --git a/gobrew.go b/gobrew.go
index c6cf651..0a82220 100644
--- a/gobrew.go
+++ b/gobrew.go
@@ -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
}
@@ -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)
}
@@ -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
@@ -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
}
@@ -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 {
diff --git a/gobrew_test.go b/gobrew_test.go
index 2a3a57e..9039ace 100644
--- a/gobrew_test.go
+++ b/gobrew_test.go
@@ -4,9 +4,10 @@ import (
"os"
"path/filepath"
"runtime"
+ "strings"
"testing"
- "gotest.tools/assert"
+ "github.com/stretchr/testify/assert"
)
func TestNewGobrewHomeDirUsesUserHomeDir(t *testing.T) {
@@ -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")
@@ -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)
+}
diff --git a/helpers.go b/helpers.go
new file mode 100644
index 0000000..4a6eb95
--- /dev/null
+++ b/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
+ }
+ }
+}
diff --git a/helpers_test.go b/helpers_test.go
new file mode 100644
index 0000000..85a3fc4
--- /dev/null
+++ b/helpers_test.go
@@ -0,0 +1,59 @@
+package gobrew
+
+import (
+ "testing"
+)
+
+func TestExtractMajorVersion(t *testing.T) {
+ type args struct {
+ version string
+ }
+ tests := []struct {
+ name string
+ args args
+ want string
+ }{
+ {
+ name: "extracts major version",
+ args: args{
+ version: "1.16.5",
+ },
+ want: "1.16",
+ },
+ {
+ name: "extracts major version if already major version",
+ args: args{
+ version: "1.16",
+ },
+ want: "1.16",
+ },
+ {
+ name: "extracts major version with extra parts",
+ args: args{
+ version: "",
+ },
+ want: "",
+ },
+ {
+ name: "extracts major version rc",
+ args: args{
+ version: "1.21rc1",
+ },
+ want: "1.21",
+ },
+ {
+ name: "extracts major version beta",
+ args: args{
+ version: "1.21beta1",
+ },
+ want: "1.21",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := ExtractMajorVersion(tt.args.version); got != tt.want {
+ t.Errorf("ExtractMajorVersion() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}