@@ -11,6 +11,7 @@ import (
11
11
"net/http"
12
12
"net/url"
13
13
"os"
14
+ "regexp"
14
15
"runtime"
15
16
"slices"
16
17
"strings"
@@ -700,6 +701,21 @@ const (
700
701
ModuleSourceTypeUnknown ModuleSourceType = "unknown"
701
702
)
702
703
704
+ // Terraform supports a variety of module source types, like:
705
+ // - local paths (./ or ../)
706
+ // - absolute local paths (/)
707
+ // - git URLs (git:: or git@)
708
+ // - http URLs
709
+ // - s3 URLs
710
+ //
711
+ // and more!
712
+ //
713
+ // See https://developer.hashicorp.com/terraform/language/modules/sources for an overview.
714
+ //
715
+ // This function attempts to classify the source type of a module. It's imperfect,
716
+ // as checks that terraform actually does are pretty complicated.
717
+ // See e.g. https://github.com/hashicorp/go-getter/blob/842d6c379e5e70d23905b8f6b5a25a80290acb66/detect.go#L47
718
+ // if you're interested in the complexity.
703
719
func GetModuleSourceType (source string ) ModuleSourceType {
704
720
source = strings .TrimSpace (source )
705
721
source = strings .ToLower (source )
@@ -709,6 +725,14 @@ func GetModuleSourceType(source string) ModuleSourceType {
709
725
if strings .HasPrefix (source , "/" ) {
710
726
return ModuleSourceTypeLocalAbs
711
727
}
728
+ // Match public registry modules in the format <NAMESPACE>/<NAME>/<PROVIDER>
729
+ // Sources can have a `//...` suffix, which signifies a subdirectory.
730
+ // The allowed characters are based on
731
+ // https://developer.hashicorp.com/terraform/cloud-docs/api-docs/private-registry/modules#request-body-1
732
+ // because Hashicorp's documentation about module sources doesn't mention it.
733
+ if matched , _ := regexp .MatchString (`^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+(//.*)?$` , source ); matched {
734
+ return ModuleSourceTypePublicRegistry
735
+ }
712
736
if strings .Contains (source , "github.com" ) {
713
737
return ModuleSourceTypeGitHub
714
738
}
@@ -739,9 +763,6 @@ func GetModuleSourceType(source string) ModuleSourceType {
739
763
if strings .Contains (source , "registry.coder.com" ) {
740
764
return ModuleSourceTypeCoderRegistry
741
765
}
742
- if ! strings .Contains (source , "://" ) && ! strings .Contains (source , "." ) && strings .Contains (source , "/" ) {
743
- return ModuleSourceTypePublicRegistry
744
- }
745
766
return ModuleSourceTypeUnknown
746
767
}
747
768
0 commit comments