Skip to content

Commit

Permalink
Merge pull request #16 from owenthereal/upgrade
Browse files Browse the repository at this point in the history
Add `goup upgrade [version]`
  • Loading branch information
owenthereal authored Oct 16, 2020
2 parents 2e17598 + 014c971 commit 84e7607
Show file tree
Hide file tree
Showing 351 changed files with 65,918 additions and 2,056 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ $ GOUP_GO_HOST=golang.google.cn goup install # For Gophers in China, see https:/
## How it works

* `install.sh` downloads the latest Goup release for your platform and appends Goup's bin directory (`$HOME/.go/bin`) & Go's bin directory (`$HOME/.go/current/bin`) to your PATH environment variable.
* `goup` switches to selected Go version.
* `goup install` downloads specified version of Go to`$HOME/.go/VERSION` and symlinks it to `$HOME/.go/current`.
* `goup show` shows the activated Go version located at `$HOME/.go/current`.
* `goup remove` removes the specified Go version.
* `goup ls-ver` lists all available Go versions from https://golang.org/dl.
* `goup upgrade` upgrades goup.

## License

Expand Down
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,22 @@ module github.com/owenthereal/goup
go 1.15

require (
github.com/apex/log v1.9.0 // indirect
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect
github.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c // indirect
github.com/dsnet/compress v0.0.1 // indirect
github.com/google/go-github v17.0.0+incompatible // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/gosuri/uilive v0.0.4 // indirect
github.com/gosuri/uiprogress v0.0.1 // indirect
github.com/hooklift/assert v0.1.0 // indirect
github.com/kierdavis/ansi v0.0.0-20180105022324-90d93b0fcae2
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/manifoldco/promptui v0.8.0
github.com/olekukonko/tablewriter v0.0.4
github.com/sirupsen/logrus v1.2.0
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/tj/go-update v2.2.4+incompatible
github.com/ulikunitz/xz v0.5.8 // indirect
)
91 changes: 91 additions & 0 deletions go.sum

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions internal/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ var (
logger *logrus.Logger

ProfileFiles []string

rootCmdVerboseFlag bool
)

func init() {
Expand All @@ -34,17 +36,21 @@ func init() {

func NewCommand() *cobra.Command {
rootCmd := &cobra.Command{
Use: "goup",
Short: "The Go installer",
RunE: runChooseVersion,
Use: "goup",
Short: "The Go installer",
PersistentPreRunE: preRunRoot,
RunE: runChooseVersion,
}

rootCmd.PersistentFlags().BoolVarP(&rootCmdVerboseFlag, "verbose", "v", false, "Verbose")

rootCmd.AddCommand(installCmd())
rootCmd.AddCommand(removeCmd())
rootCmd.AddCommand(initCmd())
rootCmd.AddCommand(showCmd())
rootCmd.AddCommand(listCmd())
rootCmd.AddCommand(versionCmd())
rootCmd.AddCommand(upgradeCmd())

return rootCmd
}
Expand Down Expand Up @@ -76,6 +82,14 @@ func GoupDir(paths ...string) string {
return filepath.Join(elem...)
}

func preRunRoot(cmd *cobra.Command, args []string) error {
if rootCmdVerboseFlag {
logger.SetLevel(logrus.DebugLevel)
}

return nil
}

func runChooseVersion(cmd *cobra.Command, args []string) error {
vers, err := listGoVers()
if err != nil {
Expand Down
196 changes: 196 additions & 0 deletions internal/commands/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package commands

import (
"fmt"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"github.com/kierdavis/ansi"
"github.com/spf13/cobra"
"github.com/tj/go-update"
"github.com/tj/go-update/progress"
"github.com/tj/go-update/stores/github"
)

func upgradeCmd() *cobra.Command {
return &cobra.Command{
Use: "upgrade [version]",
Short: "Upgrade goup",
Long: "Upgrade goup by providing a version. If no version is provided, upgrade to the latest goup.",
RunE: runUpgrade,
}
}

func runUpgrade(cmd *cobra.Command, args []string) error {
ansi.HideCursor()
defer ansi.ShowCursor()

m := &manager{
Manager: &update.Manager{
Command: "goup",
Store: &github.Store{
Owner: "owenthereal",
Repo: "goup",
Version: Version,
},
},
}

var r release
if len(args) > 0 {
rr, err := m.GetRelease(trimVPrefix(args[0]))
if err != nil {
return fmt.Errorf("error fetching release: %s", err)
}

r = release{rr}
} else {
// fetch the new releases
releases, err := m.LatestReleases()
if err != nil {
log.Fatalf("error fetching releases: %s", err)
}

// no updates
if len(releases) == 0 {
logger.Println("No upgrades")
return nil
}

// latest release
r = release{releases[0]}

}

// find the tarball for this system
a := r.FindTarballWithVersion(runtime.GOOS, runtime.GOARCH)
if a == nil {
return fmt.Errorf("no upgrade for your system")
}

bin, err := a.DownloadProxy(progress.Reader)
if err != nil {
return fmt.Errorf("error downloading: %s", err)
}

logger.Debugf("Downloaded release to %s", bin)

// install it
if err := m.InstallBin(bin); err != nil {
return fmt.Errorf("error installing: %s", err)
}

logger.Printf("Upgraded to %s", trimVPrefix(r.Version))

return nil
}

type manager struct {
*update.Manager
}

func (m *manager) InstallBin(bin string) error {
oldbin, err := exec.LookPath(m.Command)
if err != nil {
return fmt.Errorf("error looking up path of %q: %w", m.Command, err)
}

dir := filepath.Dir(oldbin)

if err := os.Chmod(bin, 0755); err != nil {
return fmt.Errorf("error in chmod: %w", err)
}

dst := filepath.Join(dir, m.Command)
tmp := dst + ".tmp"

logger.Debugf("Copy %q to %q", bin, tmp)
if err := copyFile(tmp, bin); err != nil {
return fmt.Errorf("error in copying: %w", err)
}

if runtime.GOOS == "windows" {
old := dst + ".old"
logger.Debugf("Windows workaround renaming %q to %q", dst, old)
if err := os.Rename(dst, old); err != nil {
return fmt.Errorf("error in windows renmaing: %w", err)
}
}

logger.Debugf("Renaming %q to %q", tmp, dst)
if err := os.Rename(tmp, dst); err != nil {
return fmt.Errorf("error in renaming: %w", err)
}

return nil
}

type release struct {
*update.Release
}

func (r *release) FindTarballWithVersion(os, arch string) *update.Asset {
s := fmt.Sprintf("%s-%s", os, arch)
for _, a := range r.Assets {
if s == a.Name {
return a
}
}

return nil
}

func trimVPrefix(s string) string {
return strings.TrimPrefix(s, "v")
}

// copyFile copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
func copyFile(dst, src string) (err error) {
in, err := os.Open(src)
if err != nil {
return
}
defer in.Close()

out, err := os.Create(dst)
if err != nil {
return
}

defer func() {
if e := out.Close(); e != nil {
err = e
}
}()

_, err = io.Copy(out, in)
if err != nil {
return
}

err = out.Sync()
if err != nil {
return
}

si, err := os.Stat(src)
if err != nil {
return
}

err = os.Chmod(dst, si.Mode())
if err != nil {
return
}

return
}
1 change: 1 addition & 0 deletions vendor/github.com/apex/log/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions vendor/github.com/apex/log/History.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vendor/github.com/apex/log/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions vendor/github.com/apex/log/Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 84e7607

Please sign in to comment.