Skip to content

Commit

Permalink
cmd/go: support overlaying go.mod files
Browse files Browse the repository at this point in the history
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 <matloob@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
  • Loading branch information
matloob committed Nov 20, 2020
1 parent a19c925 commit 676f0a4
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 15 deletions.
16 changes: 13 additions & 3 deletions src/cmd/go/internal/fsys/fsys.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,22 @@ func OverlayPath(path string) (string, bool) {

// Open opens the file at or overlaid on the given path.
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) {
cpath := canonicalize(path)
if node, ok := overlay[cpath]; ok {
// Opening a file in the overlay.
if node.isDir() {
return nil, &fs.PathError{Op: "Open", Path: path, Err: errors.New("fsys.Open doesn't support opening directories yet")}
return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("fsys.OpenFile doesn't support opening directories yet")}
}
// We can't open overlaid paths for write.
if perm != os.FileMode(os.O_RDONLY) {
return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("overlaid files can't be opened for write")}
}
return os.Open(node.actualFilePath)
return os.OpenFile(node.actualFilePath, flag, perm)
}
if parent, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok {
// The file is deleted explicitly in the Replace map,
Expand All @@ -344,7 +354,7 @@ func Open(path string) (*os.File, error) {
Err: fmt.Errorf("file %s does not exist: parent directory %s is replaced by a file in overlay", path, parent),
}
}
return os.Open(cpath)
return os.OpenFile(cpath, flag, perm)
}

// IsDirWithGoFiles reports whether dir is a directory containing Go files
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/go/internal/lockedfile/lockedfile_filelock.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io/fs"
"os"

"cmd/go/internal/fsys"
"cmd/go/internal/lockedfile/internal/filelock"
)

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

f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm)
f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm)
if err != nil {
return nil, err
}
Expand Down
6 changes: 4 additions & 2 deletions src/cmd/go/internal/lockedfile/lockedfile_plan9.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"os"
"strings"
"time"

"cmd/go/internal/fsys"
)

// Opening an exclusive-use file returns an error.
Expand Down Expand Up @@ -56,7 +58,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
// If the file was unpacked or created by some other program, it might not
// have the ModeExclusive bit set. Set it before we call OpenFile, so that we
// can be confident that a successful OpenFile implies exclusive use.
if fi, err := os.Stat(name); err == nil {
if fi, err := fsys.Stat(name); err == nil {
if fi.Mode()&fs.ModeExclusive == 0 {
if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil {
return nil, err
Expand All @@ -69,7 +71,7 @@ func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) {
nextSleep := 1 * time.Millisecond
const maxSleep = 500 * time.Millisecond
for {
f, err := os.OpenFile(name, flag, perm|fs.ModeExclusive)
f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive)
if err == nil {
return f, nil
}
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/go/internal/modcmd/vendor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/imports"
"cmd/go/internal/modload"

Expand Down Expand Up @@ -259,7 +260,7 @@ func matchPotentialSourceFile(dir string, info fs.FileInfo) bool {
return false
}
if strings.HasSuffix(info.Name(), ".go") {
f, err := os.Open(filepath.Join(dir, info.Name()))
f, err := fsys.Open(filepath.Join(dir, info.Name()))
if err != nil {
base.Fatalf("go mod vendor: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/go/internal/modload/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile
if isLocal {
for d := dir; d != mdir && len(d) > len(mdir); {
haveGoMod := haveGoModCache.Do(d, func() interface{} {
fi, err := os.Stat(filepath.Join(d, "go.mod"))
fi, err := fsys.Stat(filepath.Join(d, "go.mod"))
return err == nil && !fi.IsDir()
}).(bool)

Expand Down Expand Up @@ -531,7 +531,7 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
// dirInModule does not report errors for missing modules,
// so if we don't report the error now, later failures will be
// very mysterious.
if _, err := os.Stat(dir); err != nil {
if _, err := fsys.Stat(dir); err != nil {
if os.IsNotExist(err) {
// Semantically the module version itself “exists” — we just don't
// have its source code. Remove the equivalence to os.ErrNotExist,
Expand Down
10 changes: 5 additions & 5 deletions src/cmd/go/internal/modload/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func Init() {
base.Fatalf("missing $GOPATH")
}
gopath = list[0]
if _, err := os.Stat(filepath.Join(gopath, "go.mod")); err == nil {
if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil {
base.Fatalf("$GOPATH/go.mod exists but should not")
}

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

Expand Down Expand Up @@ -605,7 +605,7 @@ func setDefaultBuildMod() {
return
}

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

// Look for enclosing go.mod.
for {
if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
return dir
}
d := filepath.Dir(dir)
Expand All @@ -709,7 +709,7 @@ func findAltConfig(dir string) (root, name string) {
}
for {
for _, name := range altConfigs {
if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
if fi, err := fsys.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
return dir, name
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ func (m *Match) MatchDirs() {

if !top && cfg.ModulesEnabled {
// Ignore other modules found in subdirectories.
if fi, err := os.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() {
if fi, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() {
return filepath.SkipDir
}
}
Expand Down
Loading

0 comments on commit 676f0a4

Please sign in to comment.