github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/getmodules/file_detector.go (about) 1 package getmodules 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "runtime" 7 ) 8 9 // fileDetector is a replacement for go-getter's own file detector which 10 // better meets Durgaform's needs: specifically, it rejects relative filesystem 11 // paths with a somewhat-decent error message. 12 // 13 // This is a replacement for some historical hackery we did where we tried to 14 // avoid calling into go-getter altogether in this situation. This is, 15 // therefore, a copy of getter.FileDetector but with the "not absolute path" 16 // case replaced with a similar result as Durgaform's old heuristic would've 17 // returned: a custom error type that the caller can react to in order to 18 // produce a hint error message if desired. 19 type fileDetector struct{} 20 21 func (d *fileDetector) Detect(src, pwd string) (string, bool, error) { 22 if len(src) == 0 { 23 return "", false, nil 24 } 25 26 if !filepath.IsAbs(src) { 27 return "", true, &MaybeRelativePathErr{src} 28 } 29 30 return fmtFileURL(src), true, nil 31 } 32 33 func fmtFileURL(path string) string { 34 if runtime.GOOS == "windows" { 35 // Make sure we're using "/" on Windows. URLs are "/"-based. 36 path = filepath.ToSlash(path) 37 return fmt.Sprintf("file://%s", path) 38 } 39 40 // Make sure that we don't start with "/" since we add that below. 41 if path[0] == '/' { 42 path = path[1:] 43 } 44 return fmt.Sprintf("file:///%s", path) 45 } 46 47 // MaybeRelativePathErr is the error type returned by NormalizePackageAddress 48 // if the source address looks like it might be intended to be a relative 49 // filesystem path but without the required "./" or "../" prefix. 50 // 51 // Specifically, NormalizePackageAddress will return a pointer to this type, 52 // so the error type will be *MaybeRelativePathErr. 53 // 54 // It has a name starting with "Maybe" because in practice we can get here 55 // with any string that isn't recognized as one of the supported schemes: 56 // treating the address as a local filesystem path is our fallback for when 57 // everything else fails, but it could just as easily be a typo in an attempt 58 // to use one of the other schemes and thus not a filesystem path at all. 59 type MaybeRelativePathErr struct { 60 Addr string 61 } 62 63 func (e *MaybeRelativePathErr) Error() string { 64 return fmt.Sprintf("Durgaform cannot detect a supported external module source type for %s", e.Addr) 65 }