| package getmodules |
| |
| import ( |
| "fmt" |
| "path/filepath" |
| "runtime" |
| ) |
| |
| // fileDetector is a replacement for go-getter's own file detector which |
| // better meets Terraform's needs: specifically, it rejects relative filesystem |
| // paths with a somewhat-decent error message. |
| // |
| // This is a replacement for some historical hackery we did where we tried to |
| // avoid calling into go-getter altogether in this situation. This is, |
| // therefore, a copy of getter.FileDetector but with the "not absolute path" |
| // case replaced with a similar result as Terraform's old heuristic would've |
| // returned: a custom error type that the caller can react to in order to |
| // produce a hint error message if desired. |
| type fileDetector struct{} |
| |
| func (d *fileDetector) Detect(src, pwd string) (string, bool, error) { |
| if len(src) == 0 { |
| return "", false, nil |
| } |
| |
| if !filepath.IsAbs(src) { |
| return "", true, &MaybeRelativePathErr{src} |
| } |
| |
| return fmtFileURL(src), true, nil |
| } |
| |
| func fmtFileURL(path string) string { |
| if runtime.GOOS == "windows" { |
| // Make sure we're using "/" on Windows. URLs are "/"-based. |
| path = filepath.ToSlash(path) |
| return fmt.Sprintf("file://%s", path) |
| } |
| |
| // Make sure that we don't start with "/" since we add that below. |
| if path[0] == '/' { |
| path = path[1:] |
| } |
| return fmt.Sprintf("file:///%s", path) |
| } |
| |
| // MaybeRelativePathErr is the error type returned by NormalizePackageAddress |
| // if the source address looks like it might be intended to be a relative |
| // filesystem path but without the required "./" or "../" prefix. |
| // |
| // Specifically, NormalizePackageAddress will return a pointer to this type, |
| // so the error type will be *MaybeRelativePathErr. |
| // |
| // It has a name starting with "Maybe" because in practice we can get here |
| // with any string that isn't recognized as one of the supported schemes: |
| // treating the address as a local filesystem path is our fallback for when |
| // everything else fails, but it could just as easily be a typo in an attempt |
| // to use one of the other schemes and thus not a filesystem path at all. |
| type MaybeRelativePathErr struct { |
| Addr string |
| } |
| |
| func (e *MaybeRelativePathErr) Error() string { |
| return fmt.Sprintf("Terraform cannot detect a supported external module source type for %s", e.Addr) |
| } |