Skip to content

Commit f7248f0

Browse files
committed
cmd/go: merge module support from x/vgo repo
This CL corresponds to CL 123361, the final manual CL in that repo, making this the final manual sync. All future commits will happen in this repo (the main Go repo), and we'll update x/vgo automatically with a fixed patch+script. Change-Id: I572243309c1809727604fd704705a23c30e85d1a Reviewed-on: https://go-review.googlesource.com/123576 Run-TryBot: Russ Cox <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent f22dd66 commit f7248f0

File tree

156 files changed

+14230
-3460
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+14230
-3460
lines changed

src/cmd/go/go_test.go

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"bytes"
99
"debug/elf"
1010
"debug/macho"
11+
"flag"
1112
"fmt"
1213
"go/format"
1314
"internal/race"
@@ -112,6 +113,12 @@ func TestMain(m *testing.M) {
112113
}
113114
os.Unsetenv("GOROOT_FINAL")
114115

116+
flag.Parse()
117+
if *proxyAddr != "" {
118+
StartProxy()
119+
select {}
120+
}
121+
115122
if canRun {
116123
args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
117124
if race.Enabled {
@@ -417,7 +424,8 @@ func (tg *testgoData) doRun(args []string) error {
417424
func (tg *testgoData) run(args ...string) {
418425
tg.t.Helper()
419426
if status := tg.doRun(args); status != nil {
420-
tg.t.Logf("go %v failed unexpectedly: %v", args, status)
427+
wd, _ := os.Getwd()
428+
tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
421429
tg.t.FailNow()
422430
}
423431
}
@@ -760,24 +768,51 @@ func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
760768
}
761769
}
762770

771+
// If -testwork is specified, the test prints the name of the temp directory
772+
// and does not remove it when done, so that a programmer can
773+
// poke at the test file tree afterward.
774+
var testWork = flag.Bool("testwork", false, "")
775+
763776
// cleanup cleans up a test that runs testgo.
764777
func (tg *testgoData) cleanup() {
765778
tg.t.Helper()
766779
if tg.wd != "" {
780+
wd, _ := os.Getwd()
781+
tg.t.Logf("ended in %s", wd)
782+
767783
if err := os.Chdir(tg.wd); err != nil {
768784
// We are unlikely to be able to continue.
769785
fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
770786
os.Exit(2)
771787
}
772788
}
789+
if *testWork {
790+
tg.t.Logf("TESTWORK=%s\n", tg.path("."))
791+
return
792+
}
773793
for _, path := range tg.temps {
774-
tg.check(os.RemoveAll(path))
794+
tg.check(removeAll(path))
775795
}
776796
if tg.tempdir != "" {
777-
tg.check(os.RemoveAll(tg.tempdir))
797+
tg.check(removeAll(tg.tempdir))
778798
}
779799
}
780800

801+
func removeAll(dir string) error {
802+
// module cache has 0444 directories;
803+
// make them writable in order to remove content.
804+
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
805+
if err != nil {
806+
return nil // ignore errors walking in file system
807+
}
808+
if info.IsDir() {
809+
os.Chmod(path, 0777)
810+
}
811+
return nil
812+
})
813+
return os.RemoveAll(dir)
814+
}
815+
781816
// failSSH puts an ssh executable in the PATH that always fails.
782817
// This is to stub out uses of ssh by go get.
783818
func (tg *testgoData) failSSH() {
@@ -1745,8 +1780,8 @@ func TestGoGetTestOnlyPkg(t *testing.T) {
17451780
defer tg.cleanup()
17461781
tg.tempDir("gopath")
17471782
tg.setenv("GOPATH", tg.path("gopath"))
1748-
tg.run("get", "golang.org/x/tour/content")
1749-
tg.run("get", "-t", "golang.org/x/tour/content")
1783+
tg.run("get", "golang.org/x/tour/content...")
1784+
tg.run("get", "-t", "golang.org/x/tour/content...")
17501785
}
17511786

17521787
func TestInstalls(t *testing.T) {
@@ -3165,11 +3200,25 @@ func TestBuildDashIInstallsDependencies(t *testing.T) {
31653200
checkbar("cmd")
31663201
}
31673202

3168-
func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) {
3203+
func TestGoBuildTestOnly(t *testing.T) {
31693204
tg := testgo(t)
31703205
defer tg.cleanup()
3171-
tg.runFail("build", "./testdata/testonly")
3172-
tg.grepStderr("no non-test Go files in", "go build ./testdata/testonly produced unexpected error")
3206+
tg.makeTempdir()
3207+
tg.setenv("GOPATH", tg.path("."))
3208+
tg.tempFile("src/testonly/t_test.go", `package testonly`)
3209+
tg.tempFile("src/testonly2/t.go", `package testonly2`)
3210+
tg.cd(tg.path("src"))
3211+
3212+
// Named explicitly, test-only packages should be reported as unbuildable/uninstallable,
3213+
// even if there is a wildcard also matching.
3214+
tg.runFail("build", "testonly", "testonly...")
3215+
tg.grepStderr("no non-test Go files in", "go build ./xtestonly produced unexpected error")
3216+
tg.runFail("install", "./testonly")
3217+
tg.grepStderr("no non-test Go files in", "go install ./testonly produced unexpected error")
3218+
3219+
// Named through a wildcards, the test-only packages should be silently ignored.
3220+
tg.run("build", "testonly...")
3221+
tg.run("install", "./testonly...")
31733222
}
31743223

31753224
func TestGoTestDetectsTestOnlyImportCycles(t *testing.T) {
@@ -6115,12 +6164,12 @@ func TestBadCommandLines(t *testing.T) {
61156164
tg.tempFile("src/@x/x.go", "package x\n")
61166165
tg.setenv("GOPATH", tg.path("."))
61176166
tg.runFail("build", "@x")
6118-
tg.grepStderr("invalid input directory name \"@x\"", "did not reject @x directory")
6167+
tg.grepStderr("invalid input directory name \"@x\"|cannot use path@version syntax", "did not reject @x directory")
61196168

61206169
tg.tempFile("src/@x/y/y.go", "package y\n")
61216170
tg.setenv("GOPATH", tg.path("."))
61226171
tg.runFail("build", "@x/y")
6123-
tg.grepStderr("invalid import path \"@x/y\"", "did not reject @x/y import path")
6172+
tg.grepStderr("invalid import path \"@x/y\"|cannot use path@version syntax", "did not reject @x/y import path")
61246173

61256174
tg.tempFile("src/-x/x.go", "package x\n")
61266175
tg.setenv("GOPATH", tg.path("."))

src/cmd/go/internal/cfg/cfg.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var (
2121
BuildA bool // -a flag
2222
BuildBuildmode string // -buildmode flag
2323
BuildContext = build.Default
24+
BuildGetmode string // -getmode flag
2425
BuildI bool // -i flag
2526
BuildLinkshared bool // -linkshared flag
2627
BuildMSan bool // -msan flag
@@ -67,6 +68,11 @@ var (
6768
Goos = BuildContext.GOOS
6869
ExeSuffix string
6970
Gopath = filepath.SplitList(BuildContext.GOPATH)
71+
72+
// ModulesEnabled specifies whether the go command is running
73+
// in module-aware mode (as opposed to GOPATH mode).
74+
// It is equal to modload.Enabled, but not all packages can import modload.
75+
ModulesEnabled bool
7076
)
7177

7278
func init() {

src/cmd/go/internal/envcmd/env.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import (
99
"encoding/json"
1010
"fmt"
1111
"os"
12+
"path/filepath"
1213
"runtime"
1314
"strings"
1415

1516
"cmd/go/internal/base"
1617
"cmd/go/internal/cache"
1718
"cmd/go/internal/cfg"
1819
"cmd/go/internal/load"
19-
"cmd/go/internal/vgo"
20+
"cmd/go/internal/modload"
2021
"cmd/go/internal/work"
2122
)
2223

@@ -112,6 +113,18 @@ func findEnv(env []cfg.EnvVar, name string) string {
112113

113114
// ExtraEnvVars returns environment variables that should not leak into child processes.
114115
func ExtraEnvVars() []cfg.EnvVar {
116+
gomod := ""
117+
if modload.Init(); modload.ModRoot != "" {
118+
gomod = filepath.Join(modload.ModRoot, "go.mod")
119+
}
120+
return []cfg.EnvVar{
121+
{Name: "GOMOD", Value: gomod},
122+
}
123+
}
124+
125+
// ExtraEnvVarsCostly returns environment variables that should not leak into child processes
126+
// but are costly to evaluate.
127+
func ExtraEnvVarsCostly() []cfg.EnvVar {
115128
var b work.Builder
116129
b.Init()
117130
cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{})
@@ -121,6 +134,7 @@ func ExtraEnvVars() []cfg.EnvVar {
121134
return nil
122135
}
123136
cmd := b.GccCmd(".", "")
137+
124138
return []cfg.EnvVar{
125139
// Note: Update the switch in runEnv below when adding to this list.
126140
{Name: "CGO_CFLAGS", Value: strings.Join(cflags, " ")},
@@ -130,19 +144,19 @@ func ExtraEnvVars() []cfg.EnvVar {
130144
{Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")},
131145
{Name: "PKG_CONFIG", Value: b.PkgconfigCmd()},
132146
{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")},
133-
{Name: "VGOMODROOT", Value: vgo.ModRoot},
134147
}
135148
}
136149

137150
func runEnv(cmd *base.Command, args []string) {
138151
env := cfg.CmdEnv
152+
env = append(env, ExtraEnvVars()...)
139153

140-
// Do we need to call ExtraEnvVars, which is a bit expensive?
154+
// Do we need to call ExtraEnvVarsCostly, which is a bit expensive?
141155
// Only if we're listing all environment variables ("go env")
142156
// or the variables being requested are in the extra list.
143-
needExtra := true
157+
needCostly := true
144158
if len(args) > 0 {
145-
needExtra = false
159+
needCostly = false
146160
for _, arg := range args {
147161
switch arg {
148162
case "CGO_CFLAGS",
@@ -152,12 +166,12 @@ func runEnv(cmd *base.Command, args []string) {
152166
"CGO_LDFLAGS",
153167
"PKG_CONFIG",
154168
"GOGCCFLAGS":
155-
needExtra = true
169+
needCostly = true
156170
}
157171
}
158172
}
159-
if needExtra {
160-
env = append(env, ExtraEnvVars()...)
173+
if needCostly {
174+
env = append(env, ExtraEnvVarsCostly()...)
161175
}
162176

163177
if len(args) > 0 {

src/cmd/go/internal/fix/fix.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"cmd/go/internal/base"
1010
"cmd/go/internal/cfg"
1111
"cmd/go/internal/load"
12+
"cmd/go/internal/modload"
1213
"cmd/go/internal/str"
13-
"cmd/go/internal/vgo"
1414
"fmt"
1515
"os"
1616
)
@@ -34,9 +34,9 @@ See also: go fmt, go vet.
3434
func runFix(cmd *base.Command, args []string) {
3535
printed := false
3636
for _, pkg := range load.Packages(args) {
37-
if vgo.Enabled() && !pkg.Module.Top {
37+
if modload.Enabled() && !pkg.Module.Main {
3838
if !printed {
39-
fmt.Fprintf(os.Stderr, "vgo: not fixing packages in dependency modules\n")
39+
fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n")
4040
printed = true
4141
}
4242
continue

src/cmd/go/internal/fmtcmd/fmt.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import (
1616
"cmd/go/internal/base"
1717
"cmd/go/internal/cfg"
1818
"cmd/go/internal/load"
19+
"cmd/go/internal/modload"
1920
"cmd/go/internal/str"
20-
"cmd/go/internal/vgo"
2121
)
2222

2323
func init() {
@@ -60,9 +60,9 @@ func runFmt(cmd *base.Command, args []string) {
6060
}()
6161
}
6262
for _, pkg := range load.PackagesAndErrors(args) {
63-
if vgo.Enabled() && !pkg.Module.Top {
63+
if modload.Enabled() && !pkg.Module.Main {
6464
if !printed {
65-
fmt.Fprintf(os.Stderr, "vgo: not formatting packages in dependency modules\n")
65+
fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n")
6666
printed = true
6767
}
6868
continue

src/cmd/go/internal/generate/generate.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"cmd/go/internal/base"
2222
"cmd/go/internal/cfg"
2323
"cmd/go/internal/load"
24-
"cmd/go/internal/vgo"
24+
"cmd/go/internal/modload"
2525
"cmd/go/internal/work"
2626
)
2727

@@ -161,9 +161,9 @@ func runGenerate(cmd *base.Command, args []string) {
161161
// Even if the arguments are .go files, this loop suffices.
162162
printed := false
163163
for _, pkg := range load.Packages(args) {
164-
if vgo.Enabled() && !pkg.Module.Top {
164+
if modload.Enabled() && !pkg.Module.Main {
165165
if !printed {
166-
fmt.Fprintf(os.Stderr, "vgo: not generating in packages in dependency modules\n")
166+
fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n")
167167
printed = true
168168
}
169169
continue

src/cmd/go/internal/get/discovery.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func charsetReader(charset string, input io.Reader) (io.Reader, error) {
2828

2929
// parseMetaGoImports returns meta imports from the HTML in r.
3030
// Parsing ends at the end of the <head> section or the beginning of the <body>.
31-
func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
31+
func parseMetaGoImports(r io.Reader, mod ModuleMode) (imports []metaImport, err error) {
3232
d := xml.NewDecoder(r)
3333
d.CharsetReader = charsetReader
3434
d.Strict = false
@@ -39,13 +39,13 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
3939
if err == io.EOF || len(imports) > 0 {
4040
err = nil
4141
}
42-
return
42+
break
4343
}
4444
if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
45-
return
45+
break
4646
}
4747
if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
48-
return
48+
break
4949
}
5050
e, ok := t.(xml.StartElement)
5151
if !ok || !strings.EqualFold(e.Name.Local, "meta") {
@@ -55,20 +55,34 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
5555
continue
5656
}
5757
if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
58-
// Ignore VCS type "mod", which is new Go modules.
59-
// This code is for old go get and must ignore the new mod lines.
60-
// Otherwise matchGoImport will complain about two
61-
// different metaImport lines for the same Prefix.
62-
if f[1] == "mod" {
63-
continue
64-
}
6558
imports = append(imports, metaImport{
6659
Prefix: f[0],
6760
VCS: f[1],
6861
RepoRoot: f[2],
6962
})
7063
}
7164
}
65+
66+
// Extract mod entries if we are paying attention to them.
67+
var list []metaImport
68+
var have map[string]bool
69+
if mod == PreferMod {
70+
have = make(map[string]bool)
71+
for _, m := range imports {
72+
if m.VCS == "mod" {
73+
have[m.Prefix] = true
74+
list = append(list, m)
75+
}
76+
}
77+
}
78+
79+
// Append non-mod entries, ignoring those superseded by a mod entry.
80+
for _, m := range imports {
81+
if m.VCS != "mod" && !have[m.Prefix] {
82+
list = append(list, m)
83+
}
84+
}
85+
return list, nil
7286
}
7387

7488
// attrValue returns the attribute value for the case-insensitive key

0 commit comments

Comments
 (0)