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  }