github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/addrs/module_package.go (about)

     1  package addrs
     2  
     3  import (
     4  	"strings"
     5  
     6  	svchost "github.com/hashicorp/terraform-svchost"
     7  )
     8  
     9  // A ModulePackage represents a physical location where Terraform can retrieve
    10  // a module package, which is an archive, repository, or other similar
    11  // container which delivers the source code for one or more Terraform modules.
    12  //
    13  // A ModulePackage is a string in go-getter's address syntax. By convention,
    14  // we use ModulePackage-typed values only for the result of successfully
    15  // running the go-getter "detectors", which produces an address string which
    16  // includes an explicit installation method prefix along with an address
    17  // string in the format expected by that installation method.
    18  //
    19  // Note that although the "detector" phase of go-getter does do some simple
    20  // normalization in certain cases, it isn't generally possible to compare
    21  // two ModulePackage values to decide if they refer to the same package. Two
    22  // equal ModulePackage values represent the same package, but there might be
    23  // other non-equal ModulePackage values that also refer to that package, and
    24  // there is no reliable way to determine that.
    25  //
    26  // Don't convert a user-provided string directly to ModulePackage. Instead,
    27  // use ParseModuleSource with a remote module address and then access the
    28  // ModulePackage value from the result, making sure to also handle the
    29  // selected subdirectory if any. You should convert directly to ModulePackage
    30  // only for a string that is hard-coded into the program (e.g. in a unit test)
    31  // where you've ensured that it's already in the expected syntax.
    32  type ModulePackage string
    33  
    34  func (p ModulePackage) String() string {
    35  	return string(p)
    36  }
    37  
    38  // A ModuleRegistryPackage is an extra indirection over a ModulePackage where
    39  // we use a module registry to translate a more symbolic address (and
    40  // associated version constraint given out of band) into a physical source
    41  // location.
    42  //
    43  // ModuleRegistryPackage is distinct from ModulePackage because they have
    44  // disjoint use-cases: registry package addresses are only used to query a
    45  // registry in order to find a real module package address. These being
    46  // distinct is intended to help future maintainers more easily follow the
    47  // series of steps in the module installer, with the help of the type checker.
    48  type ModuleRegistryPackage struct {
    49  	Host         svchost.Hostname
    50  	Namespace    string
    51  	Name         string
    52  	TargetSystem string
    53  }
    54  
    55  func (s ModuleRegistryPackage) String() string {
    56  	var buf strings.Builder
    57  	// Note: we're using the "display" form of the hostname here because
    58  	// for our service hostnames "for display" means something different:
    59  	// it means to render non-ASCII characters directly as Unicode
    60  	// characters, rather than using the "punycode" representation we
    61  	// use for internal processing, and so the "display" representation
    62  	// is actually what users would write in their configurations.
    63  	return s.Host.ForDisplay() + "/" + s.ForRegistryProtocol()
    64  	return buf.String()
    65  }
    66  
    67  func (s ModuleRegistryPackage) ForDisplay() string {
    68  	if s.Host == DefaultModuleRegistryHost {
    69  		return s.ForRegistryProtocol()
    70  	}
    71  	return s.Host.ForDisplay() + "/" + s.ForRegistryProtocol()
    72  }
    73  
    74  // ForRegistryProtocol returns a string representation of just the namespace,
    75  // name, and target system portions of the address, always omitting the
    76  // registry hostname and the subdirectory portion, if any.
    77  //
    78  // This is primarily intended for generating addresses to send to the
    79  // registry in question via the registry protocol, since the protocol
    80  // skips sending the registry its own hostname as part of identifiers.
    81  func (s ModuleRegistryPackage) ForRegistryProtocol() string {
    82  	var buf strings.Builder
    83  	buf.WriteString(s.Namespace)
    84  	buf.WriteByte('/')
    85  	buf.WriteString(s.Name)
    86  	buf.WriteByte('/')
    87  	buf.WriteString(s.TargetSystem)
    88  	return buf.String()
    89  }