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  }