github.com/hobbeswalsh/terraform@v0.3.7-0.20150619183303-ad17cf55a0fa/config/module/detect.go (about)

     1  package module
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  
     7  	"github.com/hashicorp/terraform/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(FileDetector),
    28  	}
    29  }
    30  
    31  // Detect turns a source string into another source string if it is
    32  // detected to be of a known pattern.
    33  //
    34  // This is safe to be called with an already valid source string: Detect
    35  // will just return it.
    36  func Detect(src string, pwd string) (string, error) {
    37  	getForce, getSrc := getForcedGetter(src)
    38  
    39  	// Separate out the subdir if there is one, we don't pass that to detect
    40  	getSrc, subDir := getDirSubdir(getSrc)
    41  
    42  	u, err := url.Parse(getSrc)
    43  	if err == nil && u.Scheme != "" {
    44  		// Valid URL
    45  		return src, nil
    46  	}
    47  
    48  	for _, d := range Detectors {
    49  		result, ok, err := d.Detect(getSrc, pwd)
    50  		if err != nil {
    51  			return "", err
    52  		}
    53  		if !ok {
    54  			continue
    55  		}
    56  
    57  		var detectForce string
    58  		detectForce, result = getForcedGetter(result)
    59  		result, detectSubdir := getDirSubdir(result)
    60  
    61  		// If we have a subdir from the detection, then prepend it to our
    62  		// requested subdir.
    63  		if detectSubdir != "" {
    64  			if subDir != "" {
    65  				subDir = filepath.Join(detectSubdir, subDir)
    66  			} else {
    67  				subDir = detectSubdir
    68  			}
    69  		}
    70  		if subDir != "" {
    71  			u, err := url.Parse(result)
    72  			if err != nil {
    73  				return "", fmt.Errorf("Error parsing URL: %s", err)
    74  			}
    75  			u.Path += "//" + subDir
    76  			result = u.String()
    77  		}
    78  
    79  		// Preserve the forced getter if it exists. We try to use the
    80  		// original set force first, followed by any force set by the
    81  		// detector.
    82  		if getForce != "" {
    83  			result = fmt.Sprintf("%s::%s", getForce, result)
    84  		} else if detectForce != "" {
    85  			result = fmt.Sprintf("%s::%s", detectForce, result)
    86  		}
    87  
    88  		return result, nil
    89  	}
    90  
    91  	return "", fmt.Errorf("invalid source string: %s", src)
    92  }