Skip to content

Commit

Permalink
cmd/go: enter vendor mode depending on new modules.txt workspace line
Browse files Browse the repository at this point in the history
modules.txt gets a new ## workspace line at the start of the file if
it's generated in workspace mode. Then, when deciding whether the go
command runs in mod=vendor, we only do so if we're in the same mode
(workspace or not) as the modules.txt specifies.

For #60056

Change-Id: If478a9891a7135614326fcb80c4c33a431e4e531
Reviewed-on: https://go-review.googlesource.com/c/go/+/513756
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Bryan Mills <[email protected]>
Run-TryBot: Bryan Mills <[email protected]>
  • Loading branch information
matloob committed Aug 11, 2023
1 parent 5abf00e commit 33cdafe
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/cmd/go/internal/modcmd/vendor.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ func RunVendor(ctx context.Context, vendorE bool, vendorO string, args []string)
w = io.MultiWriter(&buf, os.Stderr)
}

if modload.MainModules.WorkFile() != nil {
fmt.Fprintf(w, "## workspace\n")
}

replacementWritten := make(map[module.Version]bool)
for _, m := range vendorMods {
replacement := modload.Replacement(m)
Expand Down
64 changes: 54 additions & 10 deletions src/cmd/go/internal/modload/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"internal/lazyregexp"
"io"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -1408,26 +1409,69 @@ func setDefaultBuildMod() {
if fi, err := fsys.Stat(vendorDir); err == nil && fi.IsDir() {
modGo := "unspecified"
if goVersion != "" {
if gover.Compare(goVersion, "1.14") >= 0 {
// The Go version is at least 1.14, and a vendor directory exists.
// Set -mod=vendor by default.
cfg.BuildMod = "vendor"
cfg.BuildModReason = "Go version in " + versionSource + " is at least 1.14 and vendor directory exists."
return
if gover.Compare(goVersion, "1.14") < 0 {
// The go version is less than 1.14. Don't set -mod=vendor by default.
// Since a vendor directory exists, we should record why we didn't use it.
// This message won't normally be shown, but it may appear with import errors.
cfg.BuildModReason = fmt.Sprintf("Go version in "+versionSource+" is %s, so vendor directory was not used.", modGo)
} else {
modGo = goVersion
vendoredWorkspace, err := modulesTextIsForWorkspace(vendorDir)
if err != nil {
base.Fatalf("go: reading modules.txt for vendor directory: %v", err)
}
if vendoredWorkspace != (versionSource == "go.work") {
if vendoredWorkspace {
cfg.BuildModReason = "Outside workspace mode, but vendor directory is for a workspace."
} else {
cfg.BuildModReason = "In workspace mode, but vendor directory is not for a workspace"
}
} else {
// The Go version is at least 1.14, a vendor directory exists, and
// the modules.txt was generated in the same mode the command is running in.
// Set -mod=vendor by default.
cfg.BuildMod = "vendor"
cfg.BuildModReason = "Go version in " + versionSource + " is at least 1.14 and vendor directory exists."
return
}
}
modGo = goVersion
}

// Since a vendor directory exists, we should record why we didn't use it.
// This message won't normally be shown, but it may appear with import errors.
cfg.BuildModReason = fmt.Sprintf("Go version in "+versionSource+" is %s, so vendor directory was not used.", modGo)
}
}

cfg.BuildMod = "readonly"
}

func modulesTextIsForWorkspace(vendorDir string) (bool, error) {
f, err := fsys.Open(filepath.Join(vendorDir, "modules.txt"))
if errors.Is(err, os.ErrNotExist) {
// Some vendor directories exist that don't contain modules.txt.
// This mostly happens when converting to modules.
// We want to preserve the behavior that mod=vendor is set (even though
// readVendorList does nothing in that case).
return false, nil
}
if err != nil {
return false, err
}
var buf [512]byte
n, err := f.Read(buf[:])
if err != nil && err != io.EOF {
return false, err
}
line, _, _ := strings.Cut(string(buf[:n]), "\n")
if annotations, ok := strings.CutPrefix(line, "## "); ok {
for _, entry := range strings.Split(annotations, ";") {
entry = strings.TrimSpace(entry)
if entry == "workspace" {
return true, nil
}
}
}
return false, nil
}

func mustHaveCompleteRequirements() bool {
return cfg.BuildMod != "mod" && !inWorkspaceMode()
}
Expand Down
62 changes: 62 additions & 0 deletions src/cmd/go/testdata/script/work_vendor_modules_txt_conditional.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# This test checks to see if we only start in workspace vendor
# mode if the modules.txt specifies ## workspace (and only in
# standard vendor if it doesn't).

# vendor directory produced for workspace, workspace mode
# runs in mod=vendor
go work vendor
cmp vendor/modules.txt want_workspace_modules_txt
go list -f {{.Dir}} example.com/b
stdout $GOPATH[\\/]src[\\/]vendor[\\/]example.com[\\/]b

# vendor directory produced for workspace, module mode
# runs in mod=readonly
env GOWORK=off
go list -f {{.Dir}} example.com/b
stdout $GOPATH[\\/]src[\\/]b

# vendor directory produced for module, module mode
# runs in mod=vendor
go mod vendor
cmp vendor/modules.txt want_module_modules_txt
go list -f {{.Dir}} example.com/b
stdout $GOPATH[\\/]src[\\/]vendor[\\/]example.com[\\/]b

# vendor directory produced for module, workspace mode
# runs in mod=readonly
env GOWORK=
go list -f {{.Dir}} example.com/b
stdout $GOPATH[\\/]src[\\/]b

-- want_workspace_modules_txt --
## workspace
# example.com/b v0.0.0 => ./b
## explicit; go 1.21
example.com/b
# example.com/b => ./b
-- want_module_modules_txt --
# example.com/b v0.0.0 => ./b
## explicit; go 1.21
example.com/b
# example.com/b => ./b
-- go.work --
go 1.21

use .
-- go.mod --
module example.com/a

go 1.21

require example.com/b v0.0.0
replace example.com/b => ./b
-- a.go --
package a

import _ "example.com/b"
-- b/go.mod --
module example.com/b

go 1.21
-- b/b.go --
package b
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ cp modules.txt.extra_replacement vendor/modules.txt
cmpenv stderr extra_replacement_error.txt

-- modules.txt.want --
## workspace
# example.com/p v1.0.0 => ./p
## explicit; go 1.21
# example.com/q v1.0.0 => ./q
## explicit; go 1.21
-- modules.txt.required_but_not_explicit --
## workspace
# example.com/p v1.0.0 => ./p
## go 1.21
# example.com/q v1.0.0 => ./q
Expand All @@ -45,6 +47,7 @@ go: inconsistent vendoring in $GOPATH${/}src:
To sync the vendor directory, run:
go work vendor
-- modules.txt.missing_replacement --
## workspace
# example.com/p v1.0.0
## explicit; go 1.21
# example.com/q v1.0.0 => ./q
Expand All @@ -57,6 +60,7 @@ go: inconsistent vendoring in $GOPATH${/}src:
To sync the vendor directory, run:
go work vendor
-- modules.txt.different_replacement --
## workspace
# example.com/p v1.0.0 => ./r
## explicit; go 1.21
# example.com/q v1.0.0 => ./q
Expand All @@ -69,6 +73,7 @@ go: inconsistent vendoring in $GOPATH${/}src:
To sync the vendor directory, run:
go work vendor
-- modules.txt.extra_explicit --
## workspace
# example.com/p v1.0.0 => ./p
## explicit; go 1.21
# example.com/q v1.0.0 => ./q
Expand All @@ -84,6 +89,7 @@ go: inconsistent vendoring in $GOPATH${/}src:
To sync the vendor directory, run:
go work vendor
-- modules.txt.extra_replacement --
## workspace
# example.com/p v1.0.0 => ./p
## explicit; go 1.21
# example.com/q v1.0.0 => ./q
Expand Down
1 change: 1 addition & 0 deletions src/cmd/go/testdata/script/work_vendor_prune.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ go run example.com/p
stdout 'version 1.1.0'

-- modules.txt.want --
## workspace
# example.com/b v1.0.0 => ./b
## explicit; go 1.18
example.com/b
Expand Down
1 change: 1 addition & 0 deletions src/cmd/go/testdata/script/work_vendor_prune_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ stdout $GOPATH[\\/]src[\\/]vendor[\\/]example.com[\\/]z
cmp $GOPATH/src/vendor/example.com/q/q.go q1_1_0/q.go

-- modules.txt.want --
## workspace
# example.com/b v1.0.0 => ./b
## explicit; go 1.18
example.com/b
Expand Down

0 comments on commit 33cdafe

Please sign in to comment.