aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-getter/get_hg.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter/get_hg.go')
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_hg.go131
1 files changed, 131 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/get_hg.go b/vendor/github.com/hashicorp/go-getter/get_hg.go
new file mode 100644
index 0000000..820bdd4
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/get_hg.go
@@ -0,0 +1,131 @@
1package getter
2
3import (
4 "fmt"
5 "io/ioutil"
6 "net/url"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "runtime"
11
12 urlhelper "github.com/hashicorp/go-getter/helper/url"
13)
14
15// HgGetter is a Getter implementation that will download a module from
16// a Mercurial repository.
17type HgGetter struct{}
18
19func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) {
20 return ClientModeDir, nil
21}
22
23func (g *HgGetter) Get(dst string, u *url.URL) error {
24 if _, err := exec.LookPath("hg"); err != nil {
25 return fmt.Errorf("hg must be available and on the PATH")
26 }
27
28 newURL, err := urlhelper.Parse(u.String())
29 if err != nil {
30 return err
31 }
32 if fixWindowsDrivePath(newURL) {
33 // See valid file path form on http://www.selenic.com/hg/help/urls
34 newURL.Path = fmt.Sprintf("/%s", newURL.Path)
35 }
36
37 // Extract some query parameters we use
38 var rev string
39 q := newURL.Query()
40 if len(q) > 0 {
41 rev = q.Get("rev")
42 q.Del("rev")
43
44 newURL.RawQuery = q.Encode()
45 }
46
47 _, err = os.Stat(dst)
48 if err != nil && !os.IsNotExist(err) {
49 return err
50 }
51 if err != nil {
52 if err := g.clone(dst, newURL); err != nil {
53 return err
54 }
55 }
56
57 if err := g.pull(dst, newURL); err != nil {
58 return err
59 }
60
61 return g.update(dst, newURL, rev)
62}
63
64// GetFile for Hg doesn't support updating at this time. It will download
65// the file every time.
66func (g *HgGetter) GetFile(dst string, u *url.URL) error {
67 td, err := ioutil.TempDir("", "getter-hg")
68 if err != nil {
69 return err
70 }
71 if err := os.RemoveAll(td); err != nil {
72 return err
73 }
74
75 // Get the filename, and strip the filename from the URL so we can
76 // just get the repository directly.
77 filename := filepath.Base(u.Path)
78 u.Path = filepath.ToSlash(filepath.Dir(u.Path))
79
80 // If we're on Windows, we need to set the host to "localhost" for hg
81 if runtime.GOOS == "windows" {
82 u.Host = "localhost"
83 }
84
85 // Get the full repository
86 if err := g.Get(td, u); err != nil {
87 return err
88 }
89
90 // Copy the single file
91 u, err = urlhelper.Parse(fmtFileURL(filepath.Join(td, filename)))
92 if err != nil {
93 return err
94 }
95
96 fg := &FileGetter{Copy: true}
97 return fg.GetFile(dst, u)
98}
99
100func (g *HgGetter) clone(dst string, u *url.URL) error {
101 cmd := exec.Command("hg", "clone", "-U", u.String(), dst)
102 return getRunCommand(cmd)
103}
104
105func (g *HgGetter) pull(dst string, u *url.URL) error {
106 cmd := exec.Command("hg", "pull")
107 cmd.Dir = dst
108 return getRunCommand(cmd)
109}
110
111func (g *HgGetter) update(dst string, u *url.URL, rev string) error {
112 args := []string{"update"}
113 if rev != "" {
114 args = append(args, rev)
115 }
116
117 cmd := exec.Command("hg", args...)
118 cmd.Dir = dst
119 return getRunCommand(cmd)
120}
121
122func fixWindowsDrivePath(u *url.URL) bool {
123 // hg assumes a file:/// prefix for Windows drive letter file paths.
124 // (e.g. file:///c:/foo/bar)
125 // If the URL Path does not begin with a '/' character, the resulting URL
126 // path will have a file:// prefix. (e.g. file://c:/foo/bar)
127 // See http://www.selenic.com/hg/help/urls and the examples listed in
128 // http://selenic.com/repo/hg-stable/file/1265a3a71d75/mercurial/util.py#l1936
129 return runtime.GOOS == "windows" && u.Scheme == "file" &&
130 len(u.Path) > 1 && u.Path[0] != '/' && u.Path[1] == ':'
131}