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