internal/lsp: don't pass build flags to `go mod` commands

This is a temporary fix--golang/go#41826 is a better approach.

Fixes golang/go#41803

Change-Id: Ia055c5e171fe5d4f6d67e9e2e9e7c85fe254605e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/260000
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/gopls/internal/regtest/modfile_test.go b/gopls/internal/regtest/modfile_test.go
index 49469bf..f7f745f 100644
--- a/gopls/internal/regtest/modfile_test.go
+++ b/gopls/internal/regtest/modfile_test.go
@@ -647,3 +647,34 @@
 		)
 	})
 }
+
+func TestModTidyWithBuildTags(t *testing.T) {
+	testenv.NeedsGo1Point(t, 14)
+
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.14
+-- main.go --
+// +build bob
+
+package main
+
+import "example.com/blah"
+
+func main() {
+	blah.SaySomething()
+}
+`
+	withOptions(
+		WithProxyFiles(workspaceProxy),
+		EditorConfig{
+			BuildFlags: []string{"-tags", "bob"},
+		},
+	).run(t, mod, func(t *testing.T, env *Env) {
+		env.Await(
+			env.DiagnosticAtRegexp("main.go", `"example.com/blah"`),
+		)
+	})
+}
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 4697bb3..5e11c52 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -216,6 +216,13 @@
 func (s *snapshot) goCommandInvocation(ctx context.Context, cfg *packages.Config, allowTempModfile bool, verb string, args []string) (tmpURI span.URI, runner *gocommand.Runner, inv *gocommand.Invocation, cleanup func(), err error) {
 	cleanup = func() {} // fallback
 	modURI := s.GoModForFile(ctx, span.URIFromPath(cfg.Dir))
+	var buildFlags []string
+	// `go mod`, `go env`, and `go version` don't take build flags.
+	switch verb {
+	case "mod", "env", "version":
+	default:
+		buildFlags = append(cfg.BuildFlags, buildFlags...)
+	}
 	if allowTempModfile && s.view.workspaceMode&tempModfile != 0 {
 		if modURI == "" {
 			return "", nil, nil, cleanup, fmt.Errorf("no go.mod file found in %s", cfg.Dir)
@@ -231,9 +238,13 @@
 		if err != nil {
 			return "", nil, nil, cleanup, err
 		}
-		cfg.BuildFlags = append(cfg.BuildFlags, fmt.Sprintf("-modfile=%s", tmpURI.Filename()))
+		buildFlags = append(buildFlags, fmt.Sprintf("-modfile=%s", tmpURI.Filename()))
 	}
-	if verb != "mod" && verb != "get" {
+	// TODO(rstambler): Remove this when golang/go#41826 is resolved.
+	// Don't add -mod=mod for `go mod` or `go get`.
+	switch verb {
+	case "mod", "get":
+	default:
 		var modContent []byte
 		if modURI != "" {
 			modFH, err := s.GetFile(ctx, modURI)
@@ -250,7 +261,7 @@
 			return "", nil, nil, cleanup, err
 		}
 		if modMod {
-			cfg.BuildFlags = append([]string{"-mod=mod"}, cfg.BuildFlags...)
+			buildFlags = append([]string{"-mod=mod"}, buildFlags...)
 		}
 	}
 	runner = packagesinternal.GetGoCmdRunner(cfg)
@@ -258,7 +269,7 @@
 		Verb:       verb,
 		Args:       args,
 		Env:        cfg.Env,
-		BuildFlags: cfg.BuildFlags,
+		BuildFlags: buildFlags,
 		WorkingDir: cfg.Dir,
 	}, cleanup, nil
 }
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index 2679503..9179709 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -338,7 +338,6 @@
 	}
 	goVersion, err := s.view.session.gocmdRunner.Run(ctx, gocommand.Invocation{
 		Verb:       "version",
-		BuildFlags: buildFlags,
 		Env:        env,
 		WorkingDir: s.view.rootURI.Filename(),
 	})
diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go
index 5e977a4..4cc8b13 100644
--- a/internal/lsp/fake/editor.go
+++ b/internal/lsp/fake/editor.go
@@ -58,7 +58,8 @@
 //
 // The zero value for EditorConfig should correspond to its defaults.
 type EditorConfig struct {
-	Env map[string]string
+	Env        map[string]string
+	BuildFlags []string
 
 	// CodeLens is a map defining whether codelens are enabled, keyed by the
 	// codeLens command. CodeLens which are not present in this map are left in
@@ -185,6 +186,10 @@
 		"completionBudget":        "10s",
 	}
 
+	if e.Config.BuildFlags != nil {
+		config["buildFlags"] = e.Config.BuildFlags
+	}
+
 	if e.Config.CodeLens != nil {
 		config["codelens"] = e.Config.CodeLens
 	}