config/module: fix HgGetter test failures on Windows
HgGetter tests failed on windows/amd64 using Mercurial version 3.2.4: --- FAIL: TestHgGetter (0.11s) get_hg_test.go:35: err: C:\Program Files\Mercurial\hg.exe exited with 255: abort: file:// URLs can only refer to localhost --- FAIL: TestHgGetter_branch (0.11s) get_hg_test.go:62: err: C:\Program Files\Mercurial\hg.exe exited with 255: abort: file:// URLs can only refer to localhost FAIL FAIL github.com/hashicorp/terraform/config/module 5.615s This commit fixes the failures by adjusting the file:// URL to a form that Mercurial expects.
This commit is contained in:
parent
cfbf39d1de
commit
a8db835a44
|
@ -5,6 +5,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// HgGetter is a Getter implementation that will download a module from
|
||||
|
@ -16,34 +17,40 @@ func (g *HgGetter) Get(dst string, u *url.URL) error {
|
|||
return fmt.Errorf("hg must be available and on the PATH")
|
||||
}
|
||||
|
||||
newURL, err := urlParse(u.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fixWindowsDrivePath(newURL) {
|
||||
// See valid file path form on http://www.selenic.com/hg/help/urls
|
||||
newURL.Path = fmt.Sprintf("/%s", newURL.Path)
|
||||
}
|
||||
|
||||
// Extract some query parameters we use
|
||||
var rev string
|
||||
q := u.Query()
|
||||
q := newURL.Query()
|
||||
if len(q) > 0 {
|
||||
rev = q.Get("rev")
|
||||
q.Del("rev")
|
||||
|
||||
// Copy the URL
|
||||
var newU url.URL = *u
|
||||
u = &newU
|
||||
u.RawQuery = q.Encode()
|
||||
newURL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
_, err := os.Stat(dst)
|
||||
_, err = os.Stat(dst)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if err != nil {
|
||||
if err := g.clone(dst, u); err != nil {
|
||||
if err := g.clone(dst, newURL); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.pull(dst, u); err != nil {
|
||||
if err := g.pull(dst, newURL); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.update(dst, u, rev)
|
||||
return g.update(dst, newURL, rev)
|
||||
}
|
||||
|
||||
func (g *HgGetter) clone(dst string, u *url.URL) error {
|
||||
|
@ -67,3 +74,14 @@ func (g *HgGetter) update(dst string, u *url.URL, rev string) error {
|
|||
cmd.Dir = dst
|
||||
return getRunCommand(cmd)
|
||||
}
|
||||
|
||||
func fixWindowsDrivePath(u *url.URL) bool {
|
||||
// hg assumes a file:/// prefix for Windows drive letter file paths.
|
||||
// (e.g. file:///c:/foo/bar)
|
||||
// If the URL Path does not begin with a '/' character, the resulting URL
|
||||
// path will have a file:// prefix. (e.g. file://c:/foo/bar)
|
||||
// See http://www.selenic.com/hg/help/urls and the examples listed in
|
||||
// http://selenic.com/repo/hg-stable/file/1265a3a71d75/mercurial/util.py#l1936
|
||||
return runtime.GOOS == "windows" && u.Scheme == "file" &&
|
||||
len(u.Path) > 1 && u.Path[0] != '/' && u.Path[1] == ':'
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net/url"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func urlParse(rawURL string) (*url.URL, error) {
|
||||
|
@ -30,6 +31,13 @@ func urlParse(rawURL string) (*url.URL, error) {
|
|||
u.Scheme = ""
|
||||
}
|
||||
|
||||
if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") {
|
||||
// Assume we're dealing with a drive letter file path on Windows
|
||||
// where the drive letter has been parsed into the URL Host.
|
||||
u.Path = fmt.Sprintf("%s%s", u.Host, u.Path)
|
||||
u.Host = ""
|
||||
}
|
||||
|
||||
// Remove leading slash for absolute file paths on Windows.
|
||||
// For example, url.Parse yields u.Path = "/C:/Users/user" for
|
||||
// rawURL = "file:///C:/Users/user", which is an incorrect syntax.
|
||||
|
|
Loading…
Reference in New Issue