config/module: handle absolute file paths on Windows
Using url.Parse to parse an absolute file path on Windows yields a URL type where the Path element is prefixed by a slash. For example, parsing "file:///C:/Users/user" gives a URL type with Path:"/C:/Users/user". According to golang.org/issue/6027, the parsing is correct as is. The leading slash on the Path must be eliminated before any file operations. This commit introduces a urlParse function which wraps the url.Parse functionality and removes the leading slash in Path for absolute file paths on Windows. Fixes config/module test failures on Windows.
This commit is contained in:
parent
78d1fc742f
commit
d5a49363d7
|
@ -21,13 +21,5 @@ func (d *FileDetector) Detect(src, pwd string) (string, bool, error) {
|
|||
|
||||
src = filepath.Join(pwd, src)
|
||||
}
|
||||
// Make sure we're using "/" even on Windows. URLs are "/"-based.
|
||||
src = filepath.ToSlash(src)
|
||||
|
||||
// Make sure that we don't start with "/" since we add that below
|
||||
if src[0] == '/' {
|
||||
src = src[1:]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("file:///%s", src), true, nil
|
||||
return fmtFileURL(src), true, nil
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ func Get(dst, src string) error {
|
|||
dst = tmpDir
|
||||
}
|
||||
|
||||
u, err := url.Parse(src)
|
||||
u, err := urlParse(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -39,15 +39,11 @@ func testModule(n string) string {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var url url.URL
|
||||
url.Scheme = "file"
|
||||
url.Path = filepath.ToSlash(p)
|
||||
return url.String()
|
||||
return fmtFileURL(p)
|
||||
}
|
||||
|
||||
func testModuleURL(n string) *url.URL {
|
||||
u, err := url.Parse(testModule(n))
|
||||
u, err := urlParse(testModule(n))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package module
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func urlParse(rawURL string) (*url.URL, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Make sure we're using "/" on Windows. URLs are "/"-based.
|
||||
rawURL = filepath.ToSlash(rawURL)
|
||||
}
|
||||
u, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
return u, err
|
||||
}
|
||||
|
||||
if u.Scheme != "file" {
|
||||
return u, err
|
||||
}
|
||||
|
||||
// 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.
|
||||
if len(u.Path) > 2 && u.Path[0] == '/' && u.Path[2] == ':' {
|
||||
u.Path = u.Path[1:]
|
||||
}
|
||||
|
||||
return u, err
|
||||
}
|
||||
|
||||
func fmtFileURL(path string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Make sure we're using "/" on Windows. URLs are "/"-based.
|
||||
path = filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
// Make sure that we don't start with "/" since we add that below.
|
||||
if path[0] == '/' {
|
||||
path = path[1:]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("file:///%s", path)
|
||||
}
|
Loading…
Reference in New Issue