Skip to content
Permalink
Browse files

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 <rsc@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
  • Loading branch information...
rsc committed Jul 12, 2018
1 parent f22dd66 commit f7248f05946c1804b5519d0b3eb0db054dc9c5d6
Showing with 14,230 additions and 3,460 deletions.
  1. +59 −10 src/cmd/go/go_test.go
  2. +6 −0 src/cmd/go/internal/cfg/cfg.go
  3. +22 −8 src/cmd/go/internal/envcmd/env.go
  4. +3 −3 src/cmd/go/internal/fix/fix.go
  5. +3 −3 src/cmd/go/internal/fmtcmd/fmt.go
  6. +3 −3 src/cmd/go/internal/generate/generate.go
  7. +25 −11 src/cmd/go/internal/get/discovery.go
  8. +48 −19 src/cmd/go/internal/get/get.go
  9. +18 −1 src/cmd/go/internal/get/pkg_test.go
  10. +46 −37 src/cmd/go/internal/get/vcs.go
  11. +35 −35 src/cmd/go/internal/get/vcs_test.go
  12. +9 −1 src/cmd/go/internal/help/help.go
  13. +5 −3 src/cmd/go/internal/help/helpdoc.go
  14. +199 −46 src/cmd/go/internal/list/list.go
  15. +23 −1 src/cmd/go/internal/load/flag.go
  16. +113 −59 src/cmd/go/internal/load/pkg.go
  17. +1 −1 src/cmd/go/internal/load/search.go
  18. +532 −0 src/cmd/go/internal/modcmd/mod.go
  19. +178 −0 src/cmd/go/internal/modcmd/vendor.go
  20. +7 −36 src/cmd/go/internal/{vgo → modcmd}/verify.go
  21. +35 −26 src/cmd/go/internal/{modfetch → modconv}/convert.go
  22. +54 −15 src/cmd/go/internal/{modfetch → modconv}/convert_test.go
  23. +5 −2 src/cmd/go/internal/modconv/dep.go
  24. +7 −5 src/cmd/go/internal/modconv/glide.go
  25. +5 −4 src/cmd/go/internal/modconv/glock.go
  26. +5 −4 src/cmd/go/internal/modconv/godeps.go
  27. +2 −8 src/cmd/go/internal/modconv/modconv.go
  28. +2 −5 src/cmd/go/internal/modconv/modconv_test.go
  29. +5 −4 src/cmd/go/internal/modconv/tsv.go
  30. +5 −4 src/cmd/go/internal/modconv/vconf.go
  31. +5 −4 src/cmd/go/internal/modconv/vjson.go
  32. +5 −4 src/cmd/go/internal/modconv/vmanifest.go
  33. +7 −5 src/cmd/go/internal/modconv/vyml.go
  34. +0 −22 src/cmd/go/internal/modfetch/bitbucket/fetch.go
  35. +409 −0 src/cmd/go/internal/modfetch/cache.go
  36. +25 −0 src/cmd/go/internal/modfetch/cache_test.go
  37. +32 −13 src/cmd/go/internal/modfetch/codehost/codehost.go
  38. +466 −0 src/cmd/go/internal/modfetch/codehost/git.go
  39. +174 −54 src/cmd/go/internal/modfetch/{gitrepo/fetch_test.go → codehost/git_test.go}
  40. +140 −0 src/cmd/go/internal/modfetch/codehost/shell.go
  41. +506 −0 src/cmd/go/internal/modfetch/codehost/vcs.go
  42. +175 −133 src/cmd/go/internal/modfetch/coderepo.go
  43. +104 −154 src/cmd/go/internal/modfetch/coderepo_test.go
  44. +0 −178 src/cmd/go/internal/modfetch/domain.go
  45. +302 −0 src/cmd/go/internal/modfetch/fetch.go
  46. +0 −24 src/cmd/go/internal/modfetch/github/fetch.go
  47. +0 −445 src/cmd/go/internal/modfetch/gitrepo/fetch.go
  48. +0 −25 src/cmd/go/internal/modfetch/googlesource/fetch.go
  49. +0 −22 src/cmd/go/internal/modfetch/gopkgin.go
  50. +2 −1 src/cmd/go/internal/modfetch/proxy.go
  51. +0 −84 src/cmd/go/internal/modfetch/query.go
  52. +267 −58 src/cmd/go/internal/modfetch/repo.go
  53. +28 −5 src/cmd/go/internal/modfetch/unzip.go
  54. +176 −6 src/cmd/go/internal/modfile/read.go
  55. +44 −0 src/cmd/go/internal/modfile/read_test.go
  56. +257 −79 src/cmd/go/internal/modfile/rule.go
  57. +90 −0 src/cmd/go/internal/modfile/rule_test.go
  58. +2 −0 src/cmd/go/internal/modfile/testdata/replace2.golden
  59. +2 −0 src/cmd/go/internal/modfile/testdata/replace2.in
  60. +606 −0 src/cmd/go/internal/modget/get.go
  61. +39 −3 src/cmd/go/internal/modinfo/info.go
  62. +220 −0 src/cmd/go/internal/modload/build.go
  63. +324 −0 src/cmd/go/internal/modload/help.go
  64. +267 −0 src/cmd/go/internal/modload/import.go
  65. +59 −0 src/cmd/go/internal/modload/import_test.go
  66. +182 −68 src/cmd/go/internal/{vgo → modload}/init.go
  67. +109 −0 src/cmd/go/internal/modload/list.go
  68. +891 −0 src/cmd/go/internal/modload/load.go
  69. +187 −0 src/cmd/go/internal/modload/query.go
  70. +151 −0 src/cmd/go/internal/modload/query_test.go
  71. +106 −0 src/cmd/go/internal/modload/search.go
  72. +37 −2 src/cmd/go/internal/module/module.go
  73. +119 −59 src/cmd/go/internal/mvs/mvs.go
  74. +109 −13 src/cmd/go/internal/mvs/mvs_test.go
  75. +150 −0 src/cmd/go/internal/par/work.go
  76. +53 −0 src/cmd/go/internal/par/work_test.go
  77. +17 −1 src/cmd/go/internal/search/search.go
  78. +37 −0 src/cmd/go/internal/semver/semver.go
  79. +59 −0 src/cmd/go/internal/semver/semver_test.go
  80. +22 −3 src/cmd/go/internal/str/path.go
  81. +140 −0 src/cmd/go/internal/txtar/archive.go
  82. +67 −0 src/cmd/go/internal/txtar/archive_test.go
  83. +0 −115 src/cmd/go/internal/vgo/build.go
  84. +0 −232 src/cmd/go/internal/vgo/fetch.go
  85. +0 −152 src/cmd/go/internal/vgo/get.go
  86. +0 −153 src/cmd/go/internal/vgo/list.go
  87. +0 −575 src/cmd/go/internal/vgo/load.go
  88. +0 −196 src/cmd/go/internal/vgo/search.go
  89. +0 −156 src/cmd/go/internal/vgo/vendor.go
  90. +1 −1 src/cmd/go/internal/web2/web.go
  91. +2 −2 src/cmd/go/internal/work/action.go
  92. +34 −11 src/cmd/go/internal/work/build.go
  93. +2 −9 src/cmd/go/internal/work/exec.go
  94. +13 −0 src/cmd/go/internal/work/init.go
  95. +36 −0 src/cmd/go/main.go
  96. +1,319 −0 src/cmd/go/mod_test.go
  97. +234 −0 src/cmd/go/proxy_test.go
  98. +154 −0 src/cmd/go/testdata/addmod.go
  99. +36 −0 src/cmd/go/testdata/mod/README
  100. +9 −0 src/cmd/go/testdata/mod/example.com_v1.0.0.txt
  101. +45 −0 src/cmd/go/testdata/mod/golang.org_x_text_v0.0.0-20170915032832-14c0d48ead0c.txt
  102. +45 −0 src/cmd/go/testdata/mod/golang.org_x_text_v0.3.0.txt
  103. +60 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005133-e7a685a342c0.txt
  104. +86 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005840-23179ee8a569.txt
  105. +100 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180628003336-dd9747d19b04.txt
  106. +86 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709153244-fd906ed3b100.txt
  107. +98 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709160352-0d003b9c4bfa.txt
  108. +104 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162749-b44a0b17b2d1.txt
  109. +104 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162816-fe488b867524.txt
  110. +98 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162918-a91498bed0a7.txt
  111. +104 −0 src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180710144737-5d9f230bcfba.txt
  112. +35 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.0.0.txt
  113. +48 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.1.0.txt
  114. +61 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.2.0.txt
  115. +60 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.2.1.txt
  116. +73 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.3.0.txt
  117. +79 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.4.0.txt
  118. +79 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.5.0.txt
  119. +86 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.5.1.txt
  120. +98 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.5.2.txt
  121. +100 −0 src/cmd/go/testdata/mod/rsc.io_quote_v1.5.3-pre1.txt
  122. +86 −0 src/cmd/go/testdata/mod/rsc.io_quote_v2.0.0.txt
  123. +86 −0 src/cmd/go/testdata/mod/rsc.io_quote_v2_v2.0.1.txt
  124. +45 −0 src/cmd/go/testdata/mod/rsc.io_quote_v3_v3.0.0.txt
  125. +20 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.0.0.txt
  126. +138 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.0.txt
  127. +134 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt
  128. +201 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.0.txt
  129. +201 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.1.txt
  130. +140 −0 src/cmd/go/testdata/mod/rsc.io_sampler_v1.99.99.txt
  131. +166 −0 src/cmd/go/testdata/rsc.io_quote_0d003b9.txt
  132. +151 −0 src/cmd/go/testdata/rsc.io_quote_5d9f230.txt
  133. +148 −0 src/cmd/go/testdata/rsc.io_quote_a91498b.txt
  134. +169 −0 src/cmd/go/testdata/rsc.io_quote_b44a0b1.txt
  135. +151 −0 src/cmd/go/testdata/rsc.io_quote_fe488b8.txt
  136. +79 −0 src/cmd/go/testdata/savedir.go
  137. +7 −0 src/cmd/go/testdata/testcover/pkg1/a.go
  138. +7 −0 src/cmd/go/testdata/testcover/pkg2/a.go
  139. +1 −0 src/cmd/go/testdata/testcover/pkg2/a_test.go
  140. +7 −0 src/cmd/go/testdata/testcover/pkg3/a.go
  141. +7 −0 src/cmd/go/testdata/testcover/pkg3/a_test.go
  142. +6 −0 src/cmd/go/testdata/testonly2/t.go
  143. +160 −0 src/cmd/go/testdata/vendormod.txt
  144. +0 −16 src/cmd/go/testdata/vendormod/go.mod
  145. +0 −3 src/cmd/go/testdata/vendormod/v1.go
  146. +0 −5 src/cmd/go/testdata/vendormod/v2.go
  147. +0 −5 src/cmd/go/testdata/vendormod/v3.go
  148. +0 −1 src/cmd/go/testdata/vendormod/w/go.mod
  149. +0 −1 src/cmd/go/testdata/vendormod/w/w.go
  150. +0 −1 src/cmd/go/testdata/vendormod/x/go.mod
  151. +0 −1 src/cmd/go/testdata/vendormod/x/x.go
  152. +0 −1 src/cmd/go/testdata/vendormod/y/go.mod
  153. +0 −1 src/cmd/go/testdata/vendormod/y/y.go
  154. +0 −1 src/cmd/go/testdata/vendormod/z/go.mod
  155. +0 −1 src/cmd/go/testdata/vendormod/z/z.go
  156. +2 −2 src/cmd/go/vendor_test.go
@@ -8,6 +8,7 @@ import (
"bytes"
"debug/elf"
"debug/macho"
"flag"
"fmt"
"go/format"
"internal/race"
@@ -112,6 +113,12 @@ func TestMain(m *testing.M) {
}
os.Unsetenv("GOROOT_FINAL")

flag.Parse()
if *proxyAddr != "" {
StartProxy()
select {}
}

if canRun {
args := []string{"build", "-tags", "testgo", "-o", "testgo" + exeSuffix}
if race.Enabled {
@@ -417,7 +424,8 @@ func (tg *testgoData) doRun(args []string) error {
func (tg *testgoData) run(args ...string) {
tg.t.Helper()
if status := tg.doRun(args); status != nil {
tg.t.Logf("go %v failed unexpectedly: %v", args, status)
wd, _ := os.Getwd()
tg.t.Logf("go %v failed unexpectedly in %s: %v", args, wd, status)
tg.t.FailNow()
}
}
@@ -760,24 +768,51 @@ func (tg *testgoData) wantNotStale(pkg, reason, msg string) {
}
}

// If -testwork is specified, the test prints the name of the temp directory
// and does not remove it when done, so that a programmer can
// poke at the test file tree afterward.
var testWork = flag.Bool("testwork", false, "")

// cleanup cleans up a test that runs testgo.
func (tg *testgoData) cleanup() {
tg.t.Helper()
if tg.wd != "" {
wd, _ := os.Getwd()
tg.t.Logf("ended in %s", wd)

if err := os.Chdir(tg.wd); err != nil {
// We are unlikely to be able to continue.
fmt.Fprintln(os.Stderr, "could not restore working directory, crashing:", err)
os.Exit(2)
}
}
if *testWork {
tg.t.Logf("TESTWORK=%s\n", tg.path("."))
return
}
for _, path := range tg.temps {
tg.check(os.RemoveAll(path))
tg.check(removeAll(path))
}
if tg.tempdir != "" {
tg.check(os.RemoveAll(tg.tempdir))
tg.check(removeAll(tg.tempdir))
}
}

func removeAll(dir string) error {
// module cache has 0444 directories;
// make them writable in order to remove content.
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil // ignore errors walking in file system
}
if info.IsDir() {
os.Chmod(path, 0777)
}
return nil
})
return os.RemoveAll(dir)
}

// failSSH puts an ssh executable in the PATH that always fails.
// This is to stub out uses of ssh by go get.
func (tg *testgoData) failSSH() {
@@ -1745,8 +1780,8 @@ func TestGoGetTestOnlyPkg(t *testing.T) {
defer tg.cleanup()
tg.tempDir("gopath")
tg.setenv("GOPATH", tg.path("gopath"))
tg.run("get", "golang.org/x/tour/content")
tg.run("get", "-t", "golang.org/x/tour/content")
tg.run("get", "golang.org/x/tour/content...")
tg.run("get", "-t", "golang.org/x/tour/content...")
}

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

func TestGoBuildInTestOnlyDirectoryFailsWithAGoodError(t *testing.T) {
func TestGoBuildTestOnly(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.runFail("build", "./testdata/testonly")
tg.grepStderr("no non-test Go files in", "go build ./testdata/testonly produced unexpected error")
tg.makeTempdir()
tg.setenv("GOPATH", tg.path("."))
tg.tempFile("src/testonly/t_test.go", `package testonly`)
tg.tempFile("src/testonly2/t.go", `package testonly2`)
tg.cd(tg.path("src"))

// Named explicitly, test-only packages should be reported as unbuildable/uninstallable,
// even if there is a wildcard also matching.
tg.runFail("build", "testonly", "testonly...")
tg.grepStderr("no non-test Go files in", "go build ./xtestonly produced unexpected error")
tg.runFail("install", "./testonly")
tg.grepStderr("no non-test Go files in", "go install ./testonly produced unexpected error")

// Named through a wildcards, the test-only packages should be silently ignored.
tg.run("build", "testonly...")
tg.run("install", "./testonly...")
}

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

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

tg.tempFile("src/-x/x.go", "package x\n")
tg.setenv("GOPATH", tg.path("."))
@@ -21,6 +21,7 @@ var (
BuildA bool // -a flag
BuildBuildmode string // -buildmode flag
BuildContext = build.Default
BuildGetmode string // -getmode flag
BuildI bool // -i flag
BuildLinkshared bool // -linkshared flag
BuildMSan bool // -msan flag
@@ -67,6 +68,11 @@ var (
Goos = BuildContext.GOOS
ExeSuffix string
Gopath = filepath.SplitList(BuildContext.GOPATH)

// ModulesEnabled specifies whether the go command is running
// in module-aware mode (as opposed to GOPATH mode).
// It is equal to modload.Enabled, but not all packages can import modload.
ModulesEnabled bool
)

func init() {
@@ -9,14 +9,15 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"

"cmd/go/internal/base"
"cmd/go/internal/cache"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/vgo"
"cmd/go/internal/modload"
"cmd/go/internal/work"
)

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

// ExtraEnvVars returns environment variables that should not leak into child processes.
func ExtraEnvVars() []cfg.EnvVar {
gomod := ""
if modload.Init(); modload.ModRoot != "" {
gomod = filepath.Join(modload.ModRoot, "go.mod")
}
return []cfg.EnvVar{
{Name: "GOMOD", Value: gomod},
}
}

// ExtraEnvVarsCostly returns environment variables that should not leak into child processes
// but are costly to evaluate.
func ExtraEnvVarsCostly() []cfg.EnvVar {
var b work.Builder
b.Init()
cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{})
@@ -121,6 +134,7 @@ func ExtraEnvVars() []cfg.EnvVar {
return nil
}
cmd := b.GccCmd(".", "")

return []cfg.EnvVar{
// Note: Update the switch in runEnv below when adding to this list.
{Name: "CGO_CFLAGS", Value: strings.Join(cflags, " ")},
@@ -130,19 +144,19 @@ func ExtraEnvVars() []cfg.EnvVar {
{Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")},
{Name: "PKG_CONFIG", Value: b.PkgconfigCmd()},
{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")},
{Name: "VGOMODROOT", Value: vgo.ModRoot},
}
}

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

// Do we need to call ExtraEnvVars, which is a bit expensive?
// Do we need to call ExtraEnvVarsCostly, which is a bit expensive?
// Only if we're listing all environment variables ("go env")
// or the variables being requested are in the extra list.
needExtra := true
needCostly := true
if len(args) > 0 {
needExtra = false
needCostly = false
for _, arg := range args {
switch arg {
case "CGO_CFLAGS",
@@ -152,12 +166,12 @@ func runEnv(cmd *base.Command, args []string) {
"CGO_LDFLAGS",
"PKG_CONFIG",
"GOGCCFLAGS":
needExtra = true
needCostly = true
}
}
}
if needExtra {
env = append(env, ExtraEnvVars()...)
if needCostly {
env = append(env, ExtraEnvVarsCostly()...)
}

if len(args) > 0 {
@@ -9,8 +9,8 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/modload"
"cmd/go/internal/str"
"cmd/go/internal/vgo"
"fmt"
"os"
)
@@ -34,9 +34,9 @@ See also: go fmt, go vet.
func runFix(cmd *base.Command, args []string) {
printed := false
for _, pkg := range load.Packages(args) {
if vgo.Enabled() && !pkg.Module.Top {
if modload.Enabled() && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "vgo: not fixing packages in dependency modules\n")
fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n")
printed = true
}
continue
@@ -16,8 +16,8 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/modload"
"cmd/go/internal/str"
"cmd/go/internal/vgo"
)

func init() {
@@ -60,9 +60,9 @@ func runFmt(cmd *base.Command, args []string) {
}()
}
for _, pkg := range load.PackagesAndErrors(args) {
if vgo.Enabled() && !pkg.Module.Top {
if modload.Enabled() && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "vgo: not formatting packages in dependency modules\n")
fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n")
printed = true
}
continue
@@ -21,7 +21,7 @@ import (
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
"cmd/go/internal/vgo"
"cmd/go/internal/modload"
"cmd/go/internal/work"
)

@@ -161,9 +161,9 @@ func runGenerate(cmd *base.Command, args []string) {
// Even if the arguments are .go files, this loop suffices.
printed := false
for _, pkg := range load.Packages(args) {
if vgo.Enabled() && !pkg.Module.Top {
if modload.Enabled() && !pkg.Module.Main {
if !printed {
fmt.Fprintf(os.Stderr, "vgo: not generating in packages in dependency modules\n")
fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n")
printed = true
}
continue
@@ -28,7 +28,7 @@ func charsetReader(charset string, input io.Reader) (io.Reader, error) {

// parseMetaGoImports returns meta imports from the HTML in r.
// Parsing ends at the end of the <head> section or the beginning of the <body>.
func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
func parseMetaGoImports(r io.Reader, mod ModuleMode) (imports []metaImport, err error) {
d := xml.NewDecoder(r)
d.CharsetReader = charsetReader
d.Strict = false
@@ -39,13 +39,13 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
if err == io.EOF || len(imports) > 0 {
err = nil
}
return
break
}
if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
return
break
}
if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
return
break
}
e, ok := t.(xml.StartElement)
if !ok || !strings.EqualFold(e.Name.Local, "meta") {
@@ -55,20 +55,34 @@ func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
continue
}
if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
// Ignore VCS type "mod", which is new Go modules.
// This code is for old go get and must ignore the new mod lines.
// Otherwise matchGoImport will complain about two
// different metaImport lines for the same Prefix.
if f[1] == "mod" {
continue
}
imports = append(imports, metaImport{
Prefix: f[0],
VCS: f[1],
RepoRoot: f[2],
})
}
}

// Extract mod entries if we are paying attention to them.
var list []metaImport
var have map[string]bool
if mod == PreferMod {
have = make(map[string]bool)
for _, m := range imports {
if m.VCS == "mod" {
have[m.Prefix] = true
list = append(list, m)
}
}
}

// Append non-mod entries, ignoring those superseded by a mod entry.
for _, m := range imports {
if m.VCS != "mod" && !have[m.Prefix] {
list = append(list, m)
}
}
return list, nil
}

// attrValue returns the attribute value for the case-insensitive key
Oops, something went wrong.

0 comments on commit f7248f0

Please sign in to comment.
You can’t perform that action at this time.