mirror of https://github.com/hashicorp/terraform
parent
799ffbb3ac
commit
a35a9262d4
@ -0,0 +1,50 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Detector defines the interface that an invalid URL or a URL with a blank
|
||||
// scheme is passed through in order to determine if its shorthand for
|
||||
// something else well-known.
|
||||
type Detector interface {
|
||||
// Detect will detect whether the string matches a known pattern to
|
||||
// turn it into a proper URL.
|
||||
Detect(string, string) (string, bool, error)
|
||||
}
|
||||
|
||||
// Detectors is the list of detectors that are tried on an invalid URL.
|
||||
// This is also the order they're tried (index 0 is first).
|
||||
var Detectors []Detector
|
||||
|
||||
func init() {
|
||||
Detectors = []Detector{
|
||||
new(FileDetector),
|
||||
}
|
||||
}
|
||||
|
||||
// Detect turns a source string into another source string if it is
|
||||
// detected to be of a known pattern.
|
||||
//
|
||||
// This is safe to be called with an already valid source string: Detect
|
||||
// will just return it.
|
||||
func Detect(src string, pwd string) (string, error) {
|
||||
u, err := url.Parse(src)
|
||||
if err == nil && u.Scheme != "" {
|
||||
// Valid URL
|
||||
return src, nil
|
||||
}
|
||||
|
||||
for _, d := range Detectors {
|
||||
result, ok, err := d.Detect(src, pwd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ok {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("invalid source string: %s", src)
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// FileDetector implements Detector to detect file paths.
|
||||
type FileDetector struct{}
|
||||
|
||||
func (d *FileDetector) Detect(src, pwd string) (string, bool, error) {
|
||||
if len(src) == 0 {
|
||||
return "", false, nil
|
||||
}
|
||||
|
||||
// Make sure we're using "/" even on Windows. URLs are "/"-based.
|
||||
src = filepath.ToSlash(src)
|
||||
if !filepath.IsAbs(src) {
|
||||
src = filepath.Join(pwd, 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
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileDetector(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Output string
|
||||
}{
|
||||
{"./foo", "file:///pwd/foo"},
|
||||
{"foo", "file:///pwd/foo"},
|
||||
{"/foo", "file:///foo"},
|
||||
}
|
||||
|
||||
pwd := "/pwd"
|
||||
f := new(FileDetector)
|
||||
for i, tc := range cases {
|
||||
output, ok, err := f.Detect(tc.Input, pwd)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if !ok {
|
||||
t.Fatal("not ok")
|
||||
}
|
||||
|
||||
if output != tc.Output {
|
||||
t.Fatalf("%d: bad: %#v", i, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue