github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/config/module/detect.go (about) 1 package module 2 3 import ( 4 "fmt" 5 "net/url" 6 "path/filepath" 7 ) 8 9 // Detector defines the interface that an invalid URL or a URL with a blank 10 // scheme is passed through in order to determine if its shorthand for 11 // something else well-known. 12 type Detector interface { 13 // Detect will detect whether the string matches a known pattern to 14 // turn it into a proper URL. 15 Detect(string, string) (string, bool, error) 16 } 17 18 // Detectors is the list of detectors that are tried on an invalid URL. 19 // This is also the order they're tried (index 0 is first). 20 var Detectors []Detector 21 22 func init() { 23 Detectors = []Detector{ 24 new(GitHubDetector), 25 new(BitBucketDetector), 26 new(FileDetector), 27 } 28 } 29 30 // Detect turns a source string into another source string if it is 31 // detected to be of a known pattern. 32 // 33 // This is safe to be called with an already valid source string: Detect 34 // will just return it. 35 func Detect(src string, pwd string) (string, error) { 36 getForce, getSrc := getForcedGetter(src) 37 38 // Separate out the subdir if there is one, we don't pass that to detect 39 getSrc, subDir := getDirSubdir(getSrc) 40 41 u, err := url.Parse(getSrc) 42 if err == nil && u.Scheme != "" { 43 // Valid URL 44 return src, nil 45 } 46 47 for _, d := range Detectors { 48 result, ok, err := d.Detect(getSrc, pwd) 49 if err != nil { 50 return "", err 51 } 52 if !ok { 53 continue 54 } 55 56 var detectForce string 57 detectForce, result = getForcedGetter(result) 58 result, detectSubdir := getDirSubdir(result) 59 60 // If we have a subdir from the detection, then prepend it to our 61 // requested subdir. 62 if detectSubdir != "" { 63 if subDir != "" { 64 subDir = filepath.Join(detectSubdir, subDir) 65 } else { 66 subDir = detectSubdir 67 } 68 } 69 if subDir != "" { 70 u, err := url.Parse(result) 71 if err != nil { 72 return "", fmt.Errorf("Error parsing URL: %s", err) 73 } 74 u.Path += "//" + subDir 75 result = u.String() 76 } 77 78 // Preserve the forced getter if it exists. We try to use the 79 // original set force first, followed by any force set by the 80 // detector. 81 if getForce != "" { 82 result = fmt.Sprintf("%s::%s", getForce, result) 83 } else if detectForce != "" { 84 result = fmt.Sprintf("%s::%s", detectForce, result) 85 } 86 87 return result, nil 88 } 89 90 return "", fmt.Errorf("invalid source string: %s", src) 91 }