Skip to content

Commit 676f0a4

Browse files
committed
cmd/go: support overlaying go.mod files
This change updates the lockedfile package to open files using the new fsys.OpenFile function. The logic of fsys.Open has been moved into fsys.OpenFile, and fsys.Open is now just a light wrapper around it. For #39958 Change-Id: I552f1a45ac00ac06b5812008d17a61e610b4b113 Reviewed-on: https://go-review.googlesource.com/c/go/+/266797 Trust: Michael Matloob <[email protected]> Run-TryBot: Michael Matloob <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Jay Conrod <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent a19c925 commit 676f0a4

File tree

8 files changed

+277
-15
lines changed

8 files changed

+277
-15
lines changed

src/cmd/go/internal/fsys/fsys.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,22 @@ func OverlayPath(path string) (string, bool) {
327327

328328
// Open opens the file at or overlaid on the given path.
329329
func Open(path string) (*os.File, error) {
330+
return OpenFile(path, os.O_RDONLY, 0)
331+
}
332+
333+
// OpenFile opens the file at or overlaid on the given path with the flag and perm.
334+
func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) {
330335
cpath := canonicalize(path)
331336
if node, ok := overlay[cpath]; ok {
337+
// Opening a file in the overlay.
332338
if node.isDir() {
333-
return nil, &fs.PathError{Op: "Open", Path: path, Err: errors.New("fsys.Open doesn't support opening directories yet")}
339+
return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("fsys.OpenFile doesn't support opening directories yet")}
340+
}
341+
// We can't open overlaid paths for write.
342+
if perm != os.FileMode(os.O_RDONLY) {
343+
return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("overlaid files can't be opened for write")}
334344
}
335-
return os.Open(node.actualFilePath)
345+
return os.OpenFile(node.actualFilePath, flag, perm)
336346
}
337347
if parent, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok {
338348
// The file is deleted explicitly in the Replace map,
@@ -344,7 +354,7 @@ func Open(path string) (*os.File, error) {
344354
Err: fmt.Errorf("file %s does not exist: parent directory %s is replaced by a file in overlay", path, parent),
345355
}
346356
}
347-
return os.Open(cpath)
357+
return os.OpenFile(cpath, flag, perm)
348358
}
349359

350360
// IsDirWithGoFiles reports whether dir is a directory containing Go files

src/cmd/go/internal/lockedfile/lockedfile_filelock.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io/fs"
1111
"os"
1212

13+
"cmd/go/internal/fsys"
1314
"cmd/go/internal/lockedfile/internal/filelock"
1415
)
1516

@@ -19,7 +20,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
1920
// calls for Linux and Windows anyway, so it's simpler to use that approach
2021
// consistently.
2122

22-
f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
23+
f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
2324
if err != nil {
2425
return nil, err
2526
}

src/cmd/go/internal/lockedfile/lockedfile_plan9.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"os"
1313
"strings"
1414
"time"
15+
16+
"cmd/go/internal/fsys"
1517
)
1618

1719
// Opening an exclusive-use file returns an error.
@@ -56,7 +58,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
5658
// If the file was unpacked or created by some other program, it might not
5759
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
5860
// can be confident that a successful OpenFile implies exclusive use.
59-
if fi, err := os.Stat(name); err == nil {
61+
if fi, err := fsys.Stat(name); err == nil {
6062
if fi.Mode()&fs.ModeExclusive == 0 {
6163
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
6264
return nil, err
@@ -69,7 +71,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
6971
nextSleep := 1 * time.Millisecond
7072
const maxSleep = 500 * time.Millisecond
7173
for {
72-
f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
74+
f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
7375
if err == nil {
7476
return f, nil
7577
}

src/cmd/go/internal/modcmd/vendor.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818

1919
"cmd/go/internal/base"
2020
"cmd/go/internal/cfg"
21+
"cmd/go/internal/fsys"
2122
"cmd/go/internal/imports"
2223
"cmd/go/internal/modload"
2324

@@ -259,7 +260,7 @@ func matchPotentialSourceFile(dir string, info fs.FileInfo) bool {
259260
return false
260261
}
261262
if strings.HasSuffix(info.Name(), ".go") {
262-
f, err := os.Open(filepath.Join(dir, info.Name()))
263+
f, err := fsys.Open(filepath.Join(dir, info.Name()))
263264
if err != nil {
264265
base.Fatalf("go mod vendor: %v", err)
265266
}

src/cmd/go/internal/modload/import.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile
477477
if isLocal {
478478
for d := dir; d != mdir && len(d) > len(mdir); {
479479
haveGoMod := haveGoModCache.Do(d, func() interface{} {
480-
fi, err := os.Stat(filepath.Join(d, "go.mod"))
480+
fi, err := fsys.Stat(filepath.Join(d, "go.mod"))
481481
return err == nil && !fi.IsDir()
482482
}).(bool)
483483

@@ -531,7 +531,7 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
531531
// dirInModule does not report errors for missing modules,
532532
// so if we don't report the error now, later failures will be
533533
// very mysterious.
534-
if _, err := os.Stat(dir); err != nil {
534+
if _, err := fsys.Stat(dir); err != nil {
535535
if os.IsNotExist(err) {
536536
// Semantically the module version itself “exists” — we just don't
537537
// have its source code. Remove the equivalence to os.ErrNotExist,

src/cmd/go/internal/modload/init.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ func Init() {
206206
base.Fatalf("missing $GOPATH")
207207
}
208208
gopath = list[0]
209-
if _, err := os.Stat(filepath.Join(gopath, "go.mod")); err == nil {
209+
if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil {
210210
base.Fatalf("$GOPATH/go.mod exists but should not")
211211
}
212212

@@ -407,7 +407,7 @@ func CreateModFile(ctx context.Context, modPath string) {
407407
modRoot = base.Cwd
408408
Init()
409409
modFilePath := ModFilePath()
410-
if _, err := os.Stat(modFilePath); err == nil {
410+
if _, err := fsys.Stat(modFilePath); err == nil {
411411
base.Fatalf("go: %s already exists", modFilePath)
412412
}
413413

@@ -605,7 +605,7 @@ func setDefaultBuildMod() {
605605
return
606606
}
607607

608-
if fi, err := os.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
608+
if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
609609
modGo := "unspecified"
610610
if index.goVersionV != "" {
611611
if semver.Compare(index.goVersionV, "v1.14") >= 0 {
@@ -685,7 +685,7 @@ func findModuleRoot(dir string) (root string) {
685685

686686
// Look for enclosing go.mod.
687687
for {
688-
if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
688+
if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
689689
return dir
690690
}
691691
d := filepath.Dir(dir)
@@ -709,7 +709,7 @@ func findAltConfig(dir string) (root, name string) {
709709
}
710710
for {
711711
for _, name := range altConfigs {
712-
if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
712+
if fi, err := fsys.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
713713
return dir, name
714714
}
715715
}

src/cmd/go/internal/search/search.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ func (m *Match) MatchDirs() {
295295

296296
if !top && cfg.ModulesEnabled {
297297
// Ignore other modules found in subdirectories.
298-
if fi, err := os.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() {
298+
if fi, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() {
299299
return filepath.SkipDir
300300
}
301301
}

0 commit comments

Comments
 (0)