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