github.com/hwaf/hwaf@v0.0.0-20140814122253-5465f73b20f1/cmd_self_update.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "runtime" 12 "strings" 13 14 "github.com/gonuts/commander" 15 "github.com/gonuts/flag" 16 ) 17 18 func hwaf_make_cmd_self_update() *commander.Command { 19 cmd := &commander.Command{ 20 Run: hwaf_run_cmd_self_update, 21 UsageLine: "update [options]", 22 Short: "update hwaf itself", 23 Long: ` 24 update updates hwaf internal files and the hwaf binary itself. 25 26 ex: 27 $ hwaf self update 28 `, 29 Flag: *flag.NewFlagSet("hwaf-self-update", flag.ExitOnError), 30 } 31 cmd.Flag.Bool("v", false, "enable verbose output") 32 33 return cmd 34 } 35 36 func hwaf_run_cmd_self_update(cmd *commander.Command, args []string) error { 37 var err error 38 n := "hwaf-self-" + cmd.Name() 39 40 switch len(args) { 41 case 0: 42 // ok 43 default: 44 return fmt.Errorf("%s: does NOT take any argument", n) 45 } 46 47 verbose := cmd.Flag.Lookup("v").Value.Get().(bool) 48 49 if verbose { 50 fmt.Printf("%s...\n", n) 51 } 52 53 old, err := exec.LookPath(os.Args[0]) 54 if err != nil { 55 return err 56 } 57 58 if os.Getenv("GOPATH") != "" { 59 // use go get... 60 pwd := "" 61 pwd, err = os.Getwd() 62 if err != nil { 63 return err 64 } 65 gopaths := strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) 66 gopath := "" 67 hwafpkg := filepath.Join("github.com", "hwaf", "hwaf") 68 for _, v := range gopaths { 69 if path_exists(filepath.Join(v, "src", hwafpkg)) { 70 gopath = v 71 break 72 } 73 } 74 if gopath == "" { 75 // hwaf package not installed... 76 gopath = gopaths[0] 77 gosrc := filepath.Join(gopath, "src") 78 if !path_exists(gosrc) { 79 err = os.MkdirAll(gosrc, 0700) 80 if err != nil { 81 return err 82 } 83 } 84 err = os.Chdir(gosrc) 85 if err != nil { 86 return err 87 } 88 // first try r/w repository 89 git := exec.Command( 90 "git", "clone", "git@github.com:hwaf/hwaf", 91 "github.com/hwaf/hwaf", 92 ) 93 94 if verbose { 95 git.Stdout = os.Stdout 96 git.Stderr = os.Stderr 97 } 98 99 if git.Run() != nil { 100 git := exec.Command( 101 "git", "clone", 102 "git://github.com/hwaf/hwaf", 103 "github.com/hwaf/hwaf", 104 ) 105 if verbose { 106 git.Stdout = os.Stdout 107 git.Stderr = os.Stderr 108 } 109 err = git.Run() 110 if err != nil { 111 return err 112 } 113 } 114 err = os.Chdir(pwd) 115 if err != nil { 116 return err 117 } 118 } 119 gosrc := filepath.Join(gopath, "src", hwafpkg) 120 err = os.Chdir(gosrc) 121 if err != nil { 122 return err 123 } 124 125 // fetch... 126 git := exec.Command("git", "fetch", "--all") 127 if verbose { 128 git.Stdout = os.Stdout 129 git.Stderr = os.Stderr 130 } 131 err = git.Run() 132 if err != nil { 133 return err 134 } 135 136 // update... 137 git = exec.Command("git", "checkout", "master") 138 if verbose { 139 git.Stdout = os.Stdout 140 git.Stderr = os.Stderr 141 } 142 err = git.Run() 143 if err != nil { 144 return err 145 } 146 git = exec.Command("git", "pull", "origin", "master") 147 if verbose { 148 git.Stdout = os.Stdout 149 git.Stderr = os.Stderr 150 } 151 err = git.Run() 152 if err != nil { 153 return err 154 } 155 156 // make sure we have all deps 157 goget := exec.Command("go", "get", "-d", ".") 158 if verbose { 159 goget.Stdout = os.Stdout 160 goget.Stderr = os.Stderr 161 } 162 err = goget.Run() 163 if err != nil { 164 return err 165 } 166 167 // rebuild 168 goget = exec.Command("go", "build", ".") 169 if verbose { 170 goget.Stdout = os.Stdout 171 goget.Stderr = os.Stderr 172 } 173 err = goget.Run() 174 if err != nil { 175 return err 176 } 177 178 // self init 179 bin := filepath.Join(gosrc, "hwaf") 180 hwaf := exec.Command(bin, "self", "init", fmt.Sprintf("-v=%v", verbose)) 181 hwaf.Stderr = os.Stderr 182 hwaf.Stdout = os.Stdout 183 err = hwaf.Run() 184 if err != nil { 185 return err 186 } 187 188 // replace current binary 189 mv := exec.Command("/bin/mv", "-f", bin, old) 190 mv.Stderr = os.Stderr 191 mv.Stdout = os.Stdout 192 err = mv.Run() 193 if err != nil { 194 return err 195 } 196 197 if verbose { 198 fmt.Printf("%s... [ok]\n", n) 199 } 200 return err 201 } 202 203 url := fmt.Sprintf( 204 "http://cern.ch/hwaf/downloads/bin/hwaf-%s-%s", 205 runtime.GOOS, runtime.GOARCH, 206 ) 207 tmp, err := ioutil.TempFile("", "hwaf-self-update-") 208 if err != nil { 209 return err 210 } 211 defer tmp.Close() 212 213 // make it executable 214 err = tmp.Chmod(0777) 215 if err != nil { 216 return err 217 } 218 219 // download new file 220 resp, err := http.Get(url) 221 if err != nil { 222 return err 223 } 224 defer resp.Body.Close() 225 226 if resp.StatusCode != 200 { 227 err = fmt.Errorf("could not d/l [%s] (reason: %q)\n", url, resp.Status) 228 if err != nil { 229 return err 230 } 231 } 232 233 nbytes, err := io.Copy(tmp, resp.Body) 234 if err != nil { 235 return err 236 } 237 238 if nbytes <= 0 { 239 err = fmt.Errorf("could not copy hwaf from [%s]", url) 240 if err != nil { 241 return err 242 } 243 } 244 245 err = tmp.Sync() 246 if err != nil { 247 return err 248 } 249 250 err = tmp.Close() 251 if err != nil { 252 return err 253 } 254 255 // self-init 256 hwaf := exec.Command( 257 tmp.Name(), 258 "self", "init", fmt.Sprintf("-v=%v", verbose), 259 ) 260 hwaf.Stderr = os.Stderr 261 hwaf.Stdout = os.Stdout 262 err = hwaf.Run() 263 if err != nil { 264 return err 265 } 266 267 // replace current binary 268 mv := exec.Command("/bin/mv", "-f", tmp.Name(), old) 269 mv.Stderr = os.Stderr 270 mv.Stdout = os.Stdout 271 err = mv.Run() 272 if err != nil { 273 return err 274 } 275 276 if verbose { 277 fmt.Printf("%s: [%s] updated\n", n, old) 278 fmt.Printf("%s... [ok]\n", n) 279 } 280 281 return err 282 } 283 284 // EOF