github.com/emmahsax/go-git-helper@v0.0.8-0.20240519163017-907b9de0fa52/cmd/update/update.go (about) 1 package update 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "os" 8 "os/user" 9 "runtime" 10 "strings" 11 12 "github.com/emmahsax/go-git-helper/internal/executor" 13 "github.com/emmahsax/go-git-helper/internal/utils" 14 "github.com/spf13/cobra" 15 "github.com/tidwall/gjson" 16 ) 17 18 type Update struct { 19 Debug bool 20 Executor executor.ExecutorInterface 21 Owner string 22 Repository string 23 } 24 25 var ( 26 asset = "git-helper_" + runtime.GOOS + "_" + runtime.GOARCH 27 newPath = "/usr/local/bin/git-helper" // This is for linux and mac based systems only 28 ) 29 30 func NewCommand(packageOwner, packageRepository string) *cobra.Command { 31 var ( 32 debug bool 33 ) 34 35 cmd := &cobra.Command{ 36 Use: "update", 37 Short: "Updates Git Helper with the newest version on GitHub", 38 Args: cobra.ExactArgs(0), 39 DisableFlagsInUseLine: true, 40 RunE: func(cmd *cobra.Command, args []string) error { 41 newUpdate(packageOwner, packageRepository, debug, executor.NewExecutor(debug)).execute() 42 return nil 43 }, 44 } 45 46 cmd.Flags().BoolVar(&debug, "debug", false, "enables debug mode") 47 48 return cmd 49 } 50 51 func newUpdate(owner, repository string, debug bool, executor executor.ExecutorInterface) *Update { 52 return &Update{ 53 Debug: debug, 54 Executor: executor, 55 Owner: owner, 56 Repository: repository, 57 } 58 } 59 60 func (u *Update) execute() { 61 u.downloadGitHelper() 62 u.moveGitHelper() 63 u.setPermissions() 64 u.outputNewVersion() 65 } 66 67 func (u *Update) downloadGitHelper() { 68 fmt.Println("Installing latest git-helper version") 69 70 releaseURL := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", u.Owner, u.Repository) 71 downloadURL := u.getDownloadURL(u.fetchReleaseBody(releaseURL)) 72 binaryName := strings.Split(downloadURL, "/")[len(strings.Split(downloadURL, "/"))-1] 73 u.downloadAndSaveBinary(downloadURL, binaryName) 74 } 75 76 func (u *Update) fetchReleaseBody(releaseURL string) []byte { 77 resp, err := http.Get(releaseURL) 78 if err != nil { 79 utils.HandleError(err, u.Debug, nil) 80 return []byte{} 81 } 82 defer resp.Body.Close() 83 84 body, err := io.ReadAll(resp.Body) 85 if err != nil { 86 utils.HandleError(err, u.Debug, nil) 87 return []byte{} 88 } 89 90 return body 91 } 92 93 func (u *Update) getDownloadURL(body []byte) string { 94 var downloadURL string 95 switch runtime.GOOS { 96 case "darwin": 97 downloadURL = gjson.Get(string(body), "assets.#(name==\""+asset+"\").browser_download_url").String() 98 case "linux": 99 downloadURL = gjson.Get(string(body), "assets.#(name==\""+asset+"\").browser_download_url").String() 100 default: 101 fmt.Println("Unsupported operating system:", runtime.GOOS) 102 } 103 104 return downloadURL 105 } 106 107 func (u *Update) downloadAndSaveBinary(downloadURL, binaryName string) { 108 resp, err := http.Get(downloadURL) 109 if err != nil { 110 utils.HandleError(err, u.Debug, nil) 111 return 112 } 113 defer resp.Body.Close() 114 115 out, err := os.Create(binaryName) 116 if err != nil { 117 utils.HandleError(err, u.Debug, nil) 118 return 119 } 120 defer out.Close() 121 122 _, err = io.Copy(out, resp.Body) 123 if err != nil { 124 utils.HandleError(err, u.Debug, nil) 125 return 126 } 127 } 128 129 func (u *Update) moveGitHelper() { 130 output, err := u.Executor.Exec("actionAndOutput", "sudo", "mv", "./"+asset, newPath) 131 if err != nil { 132 utils.HandleError(err, u.Debug, nil) 133 return 134 } 135 136 fmt.Printf("%s", string(output)) 137 } 138 139 func (u *Update) setPermissions() { 140 currentUser, err := user.Current() 141 if err != nil { 142 utils.HandleError(err, u.Debug, nil) 143 return 144 } 145 146 output, err := u.Executor.Exec("actionAndOutput", "sudo", "chown", currentUser.Username+":staff", newPath) 147 if err != nil { 148 utils.HandleError(err, u.Debug, nil) 149 return 150 } 151 152 fmt.Printf("%s", string(output)) 153 154 output, err = u.Executor.Exec("actionAndOutput", "sudo", "chmod", "+x", newPath) 155 if err != nil { 156 utils.HandleError(err, u.Debug, nil) 157 return 158 } 159 160 fmt.Printf("%s", string(output)) 161 } 162 163 func (u *Update) outputNewVersion() { 164 output, err := u.Executor.Exec("actionAndOutput", "git-helper", "version") 165 if err != nil { 166 utils.HandleError(err, u.Debug, nil) 167 return 168 } 169 fmt.Printf("Installed %s", string(output)) 170 }