github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/getmodules/package.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package getmodules
     5  
     6  import (
     7  	getter "github.com/hashicorp/go-getter"
     8  )
     9  
    10  // NormalizePackageAddress uses the go-getter "detector" functionality in
    11  // order to turn a user-supplied source address into a normalized address
    12  // which always includes a prefix naming a protocol to fetch with and may
    13  // also include a transformed/normalized version of the protocol-specific
    14  // source address included afterward.
    15  //
    16  // This is part of the implementation of addrs.ParseModulePackage and of
    17  // addrs.ParseModuleSource, so for most callers it'd be better to call
    18  // one of those other functions instead. The addrs package can potentially
    19  // perform other processing in addition to just the go-getter detection.
    20  //
    21  // Note that this function expects to recieve only a package address, not
    22  // a full source address that might also include a subdirectory portion.
    23  // The caller must trim off any subdirectory portion using
    24  // getmodules.SplitPackageSubdir before calling this function, passing in
    25  // just the packageAddr return value, or the result will be incorrect.
    26  //
    27  // The detectors in go-getter can potentially introduce their own
    28  // package subdirectory portions. If that happens then this function will
    29  // return the subdirectory portion as a non-empty subDir return value,
    30  // which the caller must then use as a prefix for any subDir it already
    31  // extracted from the user's given package address.
    32  //
    33  // Some of go-getter's detectors make outgoing HTTP requests, and so
    34  // the behavior of this function may depend on the network connectivity
    35  // of the system where Terraform is running. However, most of the getters
    36  // we use are local-only, and so HTTP requests are only for some ambiguous
    37  // edge-cases, such as the BitBucket detector which has a mechanism to
    38  // detect whether to use Git or Mercurial, because earlier versions of
    39  // BitBucket used to support both.
    40  func NormalizePackageAddress(given string) (packageAddr, subDir string, err error) {
    41  	// Because we're passing go-getter no base directory here, the file
    42  	// detector will return an error if the user entered a relative filesystem
    43  	// path without a "../" or "./" prefix and thus ended up in here.
    44  	//
    45  	// go-getter's error message for that case is very poor, and so we'll
    46  	// try to heuristically detect that situation and return a better error
    47  	// message.
    48  
    49  	// NOTE: We're passing an empty string to the "current working directory"
    50  	// here because that's only relevant for relative filesystem paths,
    51  	// but Terraform handles relative filesystem paths itself outside of
    52  	// go-getter and so it'd always be an error to pass one into here.
    53  	// go-getter's "file" detector returns an error if it encounters a
    54  	// relative path when the pwd argument is empty.
    55  	//
    56  	// (Absolute filesystem paths _are_ valid though, for annoying historical
    57  	// reasons, and we treat them as remote packages even though "downloading"
    58  	// them just means a recursive copy of the source directory tree.)
    59  
    60  	result, err := getter.Detect(given, "", goGetterDetectors)
    61  	if err != nil {
    62  		// NOTE: go-getter's error messages are of very inconsistent quality
    63  		// and many are not suitable for an end-user audience, but they are all
    64  		// just strings and so we can't really do any sort of post-processing
    65  		// to improve them and thus we just accept some bad error messages for
    66  		// now.
    67  		return "", "", err
    68  	}
    69  
    70  	packageAddr, subDir = SplitPackageSubdir(result)
    71  	return packageAddr, subDir, nil
    72  }