github.com/arvindram03/terraform@v0.3.7-0.20150212015210-408f838db36d/config/module/get_hg.go (about)

     1  package module
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"os"
     7  	"os/exec"
     8  	"runtime"
     9  )
    10  
    11  // HgGetter is a Getter implementation that will download a module from
    12  // a Mercurial repository.
    13  type HgGetter struct{}
    14  
    15  func (g *HgGetter) Get(dst string, u *url.URL) error {
    16  	if _, err := exec.LookPath("hg"); err != nil {
    17  		return fmt.Errorf("hg must be available and on the PATH")
    18  	}
    19  
    20  	newURL, err := urlParse(u.String())
    21  	if err != nil {
    22  		return err
    23  	}
    24  	if fixWindowsDrivePath(newURL) {
    25  		// See valid file path form on http://www.selenic.com/hg/help/urls
    26  		newURL.Path = fmt.Sprintf("/%s", newURL.Path)
    27  	}
    28  
    29  	// Extract some query parameters we use
    30  	var rev string
    31  	q := newURL.Query()
    32  	if len(q) > 0 {
    33  		rev = q.Get("rev")
    34  		q.Del("rev")
    35  
    36  		newURL.RawQuery = q.Encode()
    37  	}
    38  
    39  	_, err = os.Stat(dst)
    40  	if err != nil && !os.IsNotExist(err) {
    41  		return err
    42  	}
    43  	if err != nil {
    44  		if err := g.clone(dst, newURL); err != nil {
    45  			return err
    46  		}
    47  	}
    48  
    49  	if err := g.pull(dst, newURL); err != nil {
    50  		return err
    51  	}
    52  
    53  	return g.update(dst, newURL, rev)
    54  }
    55  
    56  func (g *HgGetter) clone(dst string, u *url.URL) error {
    57  	cmd := exec.Command("hg", "clone", "-U", u.String(), dst)
    58  	return getRunCommand(cmd)
    59  }
    60  
    61  func (g *HgGetter) pull(dst string, u *url.URL) error {
    62  	cmd := exec.Command("hg", "pull")
    63  	cmd.Dir = dst
    64  	return getRunCommand(cmd)
    65  }
    66  
    67  func (g *HgGetter) update(dst string, u *url.URL, rev string) error {
    68  	args := []string{"update"}
    69  	if rev != "" {
    70  		args = append(args, rev)
    71  	}
    72  
    73  	cmd := exec.Command("hg", args...)
    74  	cmd.Dir = dst
    75  	return getRunCommand(cmd)
    76  }
    77  
    78  func fixWindowsDrivePath(u *url.URL) bool {
    79  	// hg assumes a file:/// prefix for Windows drive letter file paths.
    80  	// (e.g. file:///c:/foo/bar)
    81  	// If the URL Path does not begin with a '/' character, the resulting URL
    82  	// path will have a file:// prefix. (e.g. file://c:/foo/bar)
    83  	// See http://www.selenic.com/hg/help/urls and the examples listed in
    84  	// http://selenic.com/repo/hg-stable/file/1265a3a71d75/mercurial/util.py#l1936
    85  	return runtime.GOOS == "windows" && u.Scheme == "file" &&
    86  		len(u.Path) > 1 && u.Path[0] != '/' && u.Path[1] == ':'
    87  }