// -modfile flag by trimming the ".mod" extension and appending ".sum".
// -overlay file
// read a JSON config file that provides an overlay for build operations.
-// The file is a JSON struct with a single field, named 'Replace', that
+// The file is a JSON object with a single field, named 'Replace', that
// maps each disk file path (a string) to its backing file path, so that
// a build will run as if the disk file path exists with the contents
// given by the backing file paths, or as if the disk file path does not
// exist if its backing file path is empty. Support for the -overlay flag
// has some limitations: importantly, cgo files included from outside the
// include path must be in the same directory as the Go package they are
-// included from, and overlays will not appear when binaries and tests are
-// run through go run and go test respectively.
+// included from, overlays will not appear when binaries and tests are
+// run through go run and go test respectively, and files beneath
+// GOMODCACHE may not be replaced.
// -pgo file
// specify the file path of a profile for profile-guided optimization (PGO).
// When the special name "auto" is specified, for each main package in the
return info.deleted || info.replaced && !info.dir
}
+// DirContainsReplacement reports whether the named directory is affected by a replacement,
+// either because a parent directory has been replaced, it has been replaced, or a file or
+// directory under it has been replaced.
+// It is meant to be used to detect cases where GOMODCACHE has been replaced. That replacement
+// is not supported (GOMODCACHE is meant to be immutable) and the caller will use the
+// information to return an error.
+func DirContainsReplacement(name string) (string, bool) {
+ apath := abs(name)
+
+ // Check the overlay using similar logic to what stat uses.
+ i, ok := slices.BinarySearchFunc(overlay, apath, searchcmp)
+ if ok {
+ // The named directory itself has been replaced.
+ return overlay[i].from, true
+ }
+ if i < len(overlay) && str.HasFilePathPrefix(overlay[i].from, apath) {
+ // A file or directory contained in the named directory has been replaced.
+ return overlay[i].from, true
+ }
+ if i > 0 && str.HasFilePathPrefix(apath, overlay[i-1].from) {
+ // A parent of the named directory has been replaced.
+ return overlay[i-1].from, true
+ }
+ return "", false
+}
+
// Open opens the named file in the virtual file system.
// It must be an ordinary file, not a directory.
func Open(name string) (*os.File, error) {
-modfile flag by trimming the ".mod" extension and appending ".sum".
-overlay file
read a JSON config file that provides an overlay for build operations.
- The file is a JSON struct with a single field, named 'Replace', that
+ The file is a JSON object with a single field, named 'Replace', that
maps each disk file path (a string) to its backing file path, so that
a build will run as if the disk file path exists with the contents
given by the backing file paths, or as if the disk file path does not
exist if its backing file path is empty. Support for the -overlay flag
has some limitations: importantly, cgo files included from outside the
include path must be in the same directory as the Go package they are
- included from, and overlays will not appear when binaries and tests are
- run through go run and go test respectively.
+ included from, overlays will not appear when binaries and tests are
+ run through go run and go test respectively, and files beneath
+ GOMODCACHE may not be replaced.
-pgo file
specify the file path of a profile for profile-guided optimization (PGO).
When the special name "auto" is specified, for each main package in the
if err := fsys.Init(); err != nil {
base.Fatal(err)
}
+ if from, replaced := fsys.DirContainsReplacement(cfg.GOMODCACHE); replaced {
+ base.Fatalf("go: overlay contains a replacement for %s. Files beneath GOMODCACHE (%s) must not be replaced.", from, cfg.GOMODCACHE)
+ }
// Make sure -pkgdir is absolute, because we run commands
// in different directories.