diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d839cdc --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 inhere + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index db3529a..7b1dd75 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Go multi version env manager - features TODO -> **[EN README](README.md)** +> **[中文说明](README.zh-CN.md)** ## Install @@ -57,3 +57,14 @@ go run ./cmd/goenv ```bash go install ./cmd/goenv ``` + +## Base on + +- https://github/gookit/color +- https://github/gookit/config +- https://github/gookit/gcli +- https://github/gookit/goutil + +## LICENSE + +[MIT](LICENSE) diff --git a/README.zh-CN.md b/README.zh-CN.md index 1271a9a..d61392a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -10,16 +10,61 @@ - features TODO -> **[中文说明](README.zh-CN.md)** +> **[EN README](README.md)** ## Install +**Use go install** + ```shell -go get github.com/inherelab/goenv +go install github.com/inherelab/goenv/cmd/goenv ``` ## Usage +```shell +goenv +``` + +switch version: + +```shell +goenv switch 1.16 +``` +Or: + +```shell +goenv use 1.16 +``` + +## Development + +### Clone + +```shell +go clone https://github.com/inherelab/goenv +cd goenv +``` + +### Run + ```bash go run ./cmd/goenv ``` + +### Install + +```bash +go install ./cmd/goenv +``` + +## Base on + +- https://github/gookit/color +- https://github/gookit/config +- https://github/gookit/gcli +- https://github/gookit/goutil + +## LICENSE + +[MIT](LICENSE) diff --git a/cli/cli.go b/cli/cli.go index 2ae58b8..ef0e709 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -67,5 +67,5 @@ func addCommands() { // MakeAdaptor instance func makeAdaptor() (internal.Adaptor, error) { - return internal.NewEnvManager(goenv.Cfg.Mode).MakeAdaptor() + return internal.MakeAdaptor(goenv.Cfg.Mode) } diff --git a/config.go b/config.go index 7929226..98fe508 100644 --- a/config.go +++ b/config.go @@ -1,29 +1,62 @@ package goenv -var defConf = ` -# +var defConf = `# # config for https://github.com/inherelab/goenv # author: https://github.com/inhere # -# mode allow: goenv, brew +# mode allow: auto, goenv, brew mode: brew # on use brew mode brew_lib_dir: /usr/local/opt +# use goenv mode. +# https://golang.org/dl +dl_host: https://golang.google.cn/dl +# install go dir. +install_dir: /usr/local/go + # custom add env map env_map: - GO_ROOT: path/to + APP_ENV: dev current: version: 1.16 path: /usr/local/opt/go@1.16 -# use goenv mode. -# https://golang.org/dl -dl_host: https://golang.google.cn/dl -# install go dir. -install_dir: /usr/local/go - ` + +// mode consts +const ( + ModeAuto = "auto" + ModeGoEnv = "goenv" + ModeBrew = "brew" + ModeScoop = "scoop" +) + +// appConf struct +type appConf struct { + // ConfFile path + ConfFile string + + // Mode allow: auto, goenv, brew + Mode string `json:"mode" default:"auto"` + // BrewLibDir path + BrewLibDir string `json:"brew_lib_dir" default:"/usr/local/opt"` + + // DlHost address, on use mode=goenv + DlHost string `json:"dl_host" default:"https://golang.org/dl"` + // InstallDir the go install dir. + InstallDir string `json:"install_dir" default:"/usr/local/go"` +} + +// IsBrewMode check +func (c *appConf) IsBrewMode() bool { + return c.Mode == ModeBrew +} + +// IsGoEnvMode check +func (c *appConf) IsGoEnvMode() bool { + return c.Mode == ModeGoEnv +} diff --git a/etc/goenv.yml b/etc/goenv.yml index 9ed6d79..0741d2e 100644 --- a/etc/goenv.yml +++ b/etc/goenv.yml @@ -1,20 +1,24 @@ +# +# config for https://github.com/inherelab/goenv +# author: https://github.com/inhere +# + +# mode allow: goenv, brew +mode: brew + +# on use brew mode +brew_lib_dir: /usr/local/opt + +# use goenv mode. # https://golang.org/dl dl_host: https://golang.google.cn/dl - +# install go dir. install_dir: /usr/local/go -mode: brew -env: - GO_ROOT: path/to +# custom add env map +env_map: + APP_ENV: dev current: version: 1.16 - path: /path/to - -brew: - lib_path: /usr/local/opt -# versions: -# - version: 1.16 -# path: /usr/local/opt/go@1.16 -# - version: 1.19 -# path: /usr/local/opt/go@1.19 + path: /usr/local/opt/go@1.16 diff --git a/goenv.go b/goenv.go index a20d785..aa213d0 100644 --- a/goenv.go +++ b/goenv.go @@ -9,11 +9,6 @@ import ( "github.com/gookit/goutil/sysutil" ) -const ( - ModeGoEnv = "goenv" - ModeBrew = "brew" -) - var defaultFile = "~/.config/goenv/goenv.yml" var ConfFile = envutil.Getenv("GOENV_CONF_FILE", defaultFile) var Version = "0.0.1" @@ -23,32 +18,6 @@ var CfgMgr *config.Config // Cfg for the application var Cfg = &appConf{} -// appConf struct -type appConf struct { - // ConfFile path - ConfFile string - - // Mode allow: goenv, brew - Mode string `json:"mode" default:"goenv"` - // BrewLibDir path - BrewLibDir string `json:"brew_lib_dir" default:"/usr/local/opt"` - - // DlHost address, on use mode=goenv - DlHost string `json:"dl_host" default:"https://golang.org/dl"` - // InstallDir the go install dir. - InstallDir string `json:"install_dir" default:"/usr/local/go"` -} - -// IsBrewMode check -func (c *appConf) IsBrewMode() bool { - return c.Mode == ModeBrew -} - -// IsGoEnvMode check -func (c *appConf) IsGoEnvMode() bool { - return c.Mode == ModeGoEnv -} - // Init config and more func Init() error { if err := loadConfig(); err != nil { diff --git a/internal/brew.go b/internal/brew.go index b1a4080..522d2cb 100644 --- a/internal/brew.go +++ b/internal/brew.go @@ -77,6 +77,10 @@ func (a *BrewAdaptor) fmtVerAndLibPath(ver string) (string, string) { func (a *BrewAdaptor) Switch(ver string) error { ver, insPath := a.fmtVerAndLibPath(ver) if !fsutil.PathExists(insPath) { + if interact.Confirm(fmt.Sprintf("Not found go%s. Install now?", ver), true) { + return a.Install(ver) + } + return errorx.Rawf("not found Go %s on %s", ver, "/usr/local/opt") } @@ -96,26 +100,24 @@ func (a *BrewAdaptor) Switch(ver string) error { return nil } - var line string - - cmdline := "brew unlink go@" + old - cliutil.Magentaln("Unbinding links for go:", cmdline) - line, err = cliutil.ExecLine(cmdline) + // cmdline = "brew unlink go@" + old + cmdArgs := arrutil.Strings{"brew", "unlink", "go@" + old} + cliutil.Magentaln("Unbinding links for go:", cmdArgs.Join(" ")) + err = sysutil.FlushExec(cmdArgs[0], cmdArgs[1:]...) if err != nil { return err } - fmt.Println(line) - cmdline = "brew link go@" + ver - cliutil.Magentaln("Binding links for go:", cmdline) - line, err = cliutil.ExecLine(cmdline) + // "brew link go@" + ver + cmdArgs = arrutil.Strings{"brew", "link", "go@" + ver} + cliutil.Magentaln("Binding links for go:", cmdArgs.Join(" ")) + err = sysutil.FlushExec(cmdArgs[0], cmdArgs[1:]...) if err != nil { return err } - fmt.Println(line) cliutil.Infoln("Switch successful!") - return sysutil.NewCmd("go", "version").OutputToStd().Run() + return sysutil.NewCmd("go", "version").FlushRun() } // Install go by given version @@ -129,12 +131,11 @@ func (a *BrewAdaptor) Install(ver string) error { c := sysutil.NewCmd("brew", "install") c.WithArgf("go@%s", ver) - c.OutputToStd() - c.BeforeExec = func(c *sysutil.Cmd) { + c.RunBefore = func(c *cmdr.Cmd) { cliutil.Yellowln(">", c.Cmdline()) } - return c.Run() + return c.FlushRun() } // Update go by given version @@ -150,7 +151,7 @@ func (a *BrewAdaptor) Update(ver string) error { c := sysutil.NewCmd("brew", "upgrade") c.WithArgf("go@%s", ver) c.OutputToStd() - c.BeforeExec = func(c *sysutil.Cmd) { + c.RunBefore = func(c *cmdr.Cmd) { cliutil.Yellowln(">", c.Cmdline()) } @@ -169,7 +170,7 @@ func (a *BrewAdaptor) Uninstall(ver string) error { c := sysutil.NewCmd("brew", "uninstall") c.WithArgf("go@%s", ver) c.OutputToStd() - c.BeforeExec = func(c *sysutil.Cmd) { + c.RunBefore = func(c *cmdr.Cmd) { cliutil.Yellowln(">", c.Cmdline()) } diff --git a/internal/manager.go b/internal/manager.go index 967feff..f4d7f8c 100644 --- a/internal/manager.go +++ b/internal/manager.go @@ -2,31 +2,38 @@ package internal import ( "github.com/gookit/goutil/errorx" + "github.com/gookit/goutil/sysutil" "github.com/inherelab/goenv" ) -// EnvManager struct -type EnvManager struct { - adaptor string -} - -// NewEnvManager instance -func NewEnvManager(adaptor string) *EnvManager { - return &EnvManager{ - adaptor: adaptor, - } -} - // MakeAdaptor instance -func (m *EnvManager) MakeAdaptor() (Adaptor, error) { - switch m.adaptor { +func MakeAdaptor(adaptor string) (Adaptor, error) { + switch autoSelectAdaptor(adaptor) { case goenv.ModeBrew: return NewBrewAdaptor(), nil case goenv.ModeGoEnv: return &GoEnvAdaptor{}, nil default: - return nil, errorx.Rawf("unsupported adaptor %q", m.adaptor) + return nil, errorx.Rawf("unsupported adaptor %q", adaptor) + } +} + +func autoSelectAdaptor(name string) string { + if name != goenv.ModeAuto { + return name + } + + if sysutil.IsWindows() { + if sysutil.HasExecutable(goenv.ModeScoop) { + return goenv.ModeScoop + } + return goenv.ModeGoEnv + } + + if sysutil.HasExecutable(goenv.ModeBrew) { + return goenv.ModeBrew } + return goenv.ModeGoEnv } // CallOpts struct