Skip to content

Commit

Permalink
cmd/go: set cfg.BuildMod to "readonly" by default with no module root
Browse files Browse the repository at this point in the history
modload.Init now sets the default value for -mod if it wasn't set
explicitly. This happens before go.mod is loaded, so
modload.LoadModFile sets the default value again in order to enable
automatic vendoring.

Previously, cfg.BuildMod wasn't set at all if LoadModFile wasn't
called, as is the case for commands that run outside of a module
root. This problem only affected 'go install pkg@version' since other
commands are either forbidden in module mode or run with -mod=mod
(like 'go get' and 'go mod' subcommands).

This change also suppresses "missing sum" errors when -mod=readonly is
enabled and there is no module root.

Fixes #43278
Related #40278

Change-Id: I6071cc42bc5e24d0d7e84556e5bfd8e368e0019d
Reviewed-on: https://go-review.googlesource.com/c/go/+/279490
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
  • Loading branch information
Jay Conrod committed Jan 5, 2021
1 parent 0b0d004 commit 3e1e13c
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/cmd/go/internal/modload/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (e *ImportMissingError) Error() string {
if e.QueryErr != nil {
return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr)
}
if cfg.BuildMod == "mod" {
if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && allowMissingModuleImports) {
return "cannot find module providing package " + e.Path
}

Expand Down Expand Up @@ -365,7 +365,7 @@ func queryImport(ctx context.Context, path string) (module.Version, error) {
return module.Version{}, &ImportMissingError{Path: path, isStd: true}
}

if cfg.BuildMod == "readonly" {
if cfg.BuildMod == "readonly" && !allowMissingModuleImports {
// In readonly mode, we can't write go.mod, so we shouldn't try to look up
// the module. If readonly mode was enabled explicitly, include that in
// the error message.
Expand Down Expand Up @@ -547,7 +547,7 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
mod = r
}

if cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
if HasModRoot() && cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
return "", false, module.VersionError(mod, &sumMissingError{})
}

Expand Down
13 changes: 9 additions & 4 deletions src/cmd/go/internal/modload/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,15 @@ var importTests = []struct {
func TestQueryImport(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
testenv.MustHaveExecPath(t, "git")
defer func(old bool) {
allowMissingModuleImports = old
}(allowMissingModuleImports)
AllowMissingModuleImports()

oldAllowMissingModuleImports := allowMissingModuleImports
oldRootMode := RootMode
defer func() {
allowMissingModuleImports = oldAllowMissingModuleImports
RootMode = oldRootMode
}()
allowMissingModuleImports = true
RootMode = NoRoot

ctx := context.Background()

Expand Down
16 changes: 8 additions & 8 deletions src/cmd/go/internal/modload/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ func Init() {
}

// We're in module mode. Set any global variables that need to be set.
cfg.ModulesEnabled = true
setDefaultBuildMod()
list := filepath.SplitList(cfg.BuildContext.GOPATH)
if len(list) == 0 || list[0] == "" {
base.Fatalf("missing $GOPATH")
Expand All @@ -211,8 +213,6 @@ func Init() {
base.Fatalf("$GOPATH/go.mod exists but should not")
}

cfg.ModulesEnabled = true

if modRoot == "" {
// We're in module mode, but not inside a module.
//
Expand Down Expand Up @@ -348,8 +348,8 @@ func die() {
// ensuring requirements are consistent. WriteGoMod should be called later to
// write changes out to disk or report errors in readonly mode.
//
// As a side-effect, LoadModFile sets a default for cfg.BuildMod if it does not
// already have an explicit value.
// As a side-effect, LoadModFile may change cfg.BuildMod to "vendor" if
// -mod wasn't set explicitly and automatic vendoring should be enabled.
func LoadModFile(ctx context.Context) {
if len(buildList) > 0 {
return
Expand Down Expand Up @@ -387,7 +387,7 @@ func LoadModFile(ctx context.Context) {
base.Fatalf("go: %v", err)
}

setDefaultBuildMod()
setDefaultBuildMod() // possibly enable automatic vendoring
modFileToBuildList()
if cfg.BuildMod == "vendor" {
readVendorList()
Expand Down Expand Up @@ -586,8 +586,8 @@ func modFileToBuildList() {
buildList = list
}

// setDefaultBuildMod sets a default value for cfg.BuildMod
// if it is currently empty.
// setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
// wasn't provided. setDefaultBuildMod may be called multiple times.
func setDefaultBuildMod() {
if cfg.BuildModExplicit {
// Don't override an explicit '-mod=' argument.
Expand All @@ -608,7 +608,7 @@ func setDefaultBuildMod() {

if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
modGo := "unspecified"
if index.goVersionV != "" {
if index != nil && index.goVersionV != "" {
if semver.Compare(index.goVersionV, "v1.14") >= 0 {
// The Go version is at least 1.14, and a vendor directory exists.
// Set -mod=vendor by default.
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/go/internal/modload/modfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
if actual.Path == "" {
actual = m
}
if cfg.BuildMod == "readonly" && actual.Version != "" {
if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" {
key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
if !modfetch.HaveSum(key) {
suggestion := fmt.Sprintf("; try 'go mod download %s' to add it", m.Path)
Expand Down
5 changes: 5 additions & 0 deletions src/cmd/go/testdata/script/mod_install_pkg_version.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ stdout '^\tmod\texample.com/cmd\tv1.0.0\t'
go install example.com/cmd/a@v1.9.0
go version -m $GOPATH/bin/a$GOEXE
stdout '^\tmod\texample.com/cmd\tv1.9.0\t'
env GO111MODULE=

# 'go install pkg@version' succeeds when -mod=readonly is set explicitly.
# Verifies #43278.
go install -mod=readonly example.com/cmd/a@v1.0.0

-- m/go.mod --
module m
Expand Down

0 comments on commit 3e1e13c

Please sign in to comment.