]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modload: respect overlays when loading go.work files
authorMichael Matloob <matloob@golang.org>
Mon, 3 Jun 2024 22:42:12 +0000 (18:42 -0400)
committerGopher Robot <gobot@golang.org>
Thu, 6 Jun 2024 18:35:34 +0000 (18:35 +0000)
Before this change, we didn't initialize the overlays in the fsys
package or use the fsys logic to read the files, so overlays were not
respected for go.work files. Initialize fsys before loading the go.work
file (initialization is idempotent) and use the new fsys.ReadFile
function to read the file instead of os.ReadFile.

fsys.ReadFile just opens the file with fsys.Open and then calls
io.ReadAll on it. (This is less efficient than what os.ReadFile does:
os.ReadFile reads into a buffer it allocated that's the file's size
while io.ReadAll doesn't know how big the file is so it just reads in
512 byte chunks.)

Change-Id: Ic40bcbb483a16c5d4dd1d896306ea99a16f370f3
Reviewed-on: https://go-review.googlesource.com/c/go/+/590755
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Matloob <matloob@golang.org>

src/cmd/go/internal/fsys/fsys.go
src/cmd/go/internal/modload/init.go
src/cmd/go/testdata/script/work_overlay.txt [new file with mode: 0644]

index 06159dbbb7343215b01618dd81627e0de03e80c8..c5889a273954c62aee9b64e821c83190e07afd48 100644 (file)
@@ -11,6 +11,7 @@ import (
        "errors"
        "fmt"
        "internal/godebug"
+       "io"
        "io/fs"
        "log"
        "os"
@@ -403,12 +404,6 @@ func Open(path string) (*os.File, error) {
        return openFile(path, os.O_RDONLY, 0)
 }
 
-// OpenFile opens the file at or overlaid on the given path with the flag and perm.
-func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) {
-       Trace("OpenFile", path)
-       return openFile(path, flag, perm)
-}
-
 func openFile(path string, flag int, perm os.FileMode) (*os.File, error) {
        cpath := canonicalize(path)
        if node, ok := overlay[cpath]; ok {
@@ -435,6 +430,17 @@ func openFile(path string, flag int, perm os.FileMode) (*os.File, error) {
        return os.OpenFile(cpath, flag, perm)
 }
 
+// ReadFile reads the file at or overlaid on the given path.
+func ReadFile(path string) ([]byte, error) {
+       f, err := Open(path)
+       if err != nil {
+               return nil, err
+       }
+       defer f.Close()
+
+       return io.ReadAll(f)
+}
+
 // IsDirWithGoFiles reports whether dir is a directory containing Go files
 // either on disk or in the overlay.
 func IsDirWithGoFiles(dir string) (bool, error) {
index 4ba1bf98ee65d3799116d493359aee051fea3292..4b196825364ffb8286c61224bdcaf8342d79ed19 100644 (file)
@@ -343,6 +343,10 @@ func BinDir() string {
 // operate in workspace mode. It should not be called by other commands,
 // for example 'go mod tidy', that don't operate in workspace mode.
 func InitWorkfile() {
+       // Initialize fsys early because we need overlay to read go.work file.
+       if err := fsys.Init(base.Cwd()); err != nil {
+               base.Fatal(err)
+       }
        workFilePath = FindGoWork(base.Cwd())
 }
 
@@ -708,7 +712,8 @@ func loadWorkFile(path string) (workFile *modfile.WorkFile, modRoots []string, e
 
 // ReadWorkFile reads and parses the go.work file at the given path.
 func ReadWorkFile(path string) (*modfile.WorkFile, error) {
-       workData, err := os.ReadFile(path)
+       path = base.ShortPath(path) // use short path in any errors
+       workData, err := fsys.ReadFile(path)
        if err != nil {
                return nil, err
        }
diff --git a/src/cmd/go/testdata/script/work_overlay.txt b/src/cmd/go/testdata/script/work_overlay.txt
new file mode 100644 (file)
index 0000000..161ad74
--- /dev/null
@@ -0,0 +1,41 @@
+# Test that overlays are respected when opening go.work files.
+
+# go.work in overlay, but not on disk.
+go list -overlay=overlay.json -m
+stdout example.com/a
+stdout example.com/b
+! stdout example.com/c
+
+# control case for go.work on disk and in overlay:
+# go.work is on disk but not in overlay.
+cp go.work.non-overlay go.work
+go list -m
+stdout example.com/a
+stdout example.com/b
+stdout example.com/c
+
+# go.work on disk and in overlay.
+go list -overlay=overlay.json -m
+stdout example.com/a
+stdout example.com/b
+! stdout example.com/c
+
+-- overlay.json --
+{"Replace": {"go.work": "overlaywork"}}
+-- overlaywork --
+use (
+    ./a
+    ./b
+)
+-- go.work.non-overlay --
+use (
+    ./a
+    ./b
+    ./c
+)
+-- a/go.mod --
+module example.com/a
+-- b/go.mod --
+module example.com/b
+-- c/go.mod --
+module example.com/c