Skip to content

Commit

Permalink
internal/lsp: modify how we check for go 1.14 for modfiles
Browse files Browse the repository at this point in the history
When the tempModfile flag was enabled, there would be some go
commands that would run without the -modfile flag. This change adds
the config's buildFlags to the invokeGo command in go/packages and
updates how we are checking if the go version is 1.14 within the
modfileFlagExists function.

Fixes golang/go#36247

Change-Id: I436666c3fcad33e85ba00aec5f227fe4a0e638b8
Reviewed-on: https://go-review.googlesource.com/c/tools/+/212477
Run-TryBot: Rohan Challa <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Rebecca Stambler <[email protected]>
  • Loading branch information
ridersofrohan committed Jan 8, 2020
1 parent 11e9d9c commit acbc0e3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 17 deletions.
11 changes: 7 additions & 4 deletions go/packages/golist.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driv

// Run "go list" for complete
// information on the specified packages.
buf, err := invokeGo(cfg, golistargs(cfg, words)...)
buf, err := invokeGo(cfg, "list", golistargs(cfg, words)...)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -877,7 +877,7 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
func golistargs(cfg *Config, words []string) []string {
const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
fullargs := []string{
"list", "-e", "-json",
"-e", "-json",
fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypesInfo|NeedTypesSizes) != 0),
fmt.Sprintf("-test=%t", cfg.Tests),
fmt.Sprintf("-export=%t", usesExportData(cfg)),
Expand All @@ -893,10 +893,13 @@ func golistargs(cfg *Config, words []string) []string {
}

// invokeGo returns the stdout of a go command invocation.
func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
func invokeGo(cfg *Config, verb string, args ...string) (*bytes.Buffer, error) {
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
cmd := exec.CommandContext(cfg.Context, "go", args...)
goArgs := []string{verb}
goArgs = append(goArgs, cfg.BuildFlags...)
goArgs = append(goArgs, args...)
cmd := exec.CommandContext(cfg.Context, "go", goArgs...)
// On darwin the cwd gets resolved to the real path, which breaks anything that
// expects the working directory to keep the original path, including the
// go command when dealing with modules.
Expand Down
38 changes: 25 additions & 13 deletions internal/lsp/cache/modfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,37 @@ import (
errors "golang.org/x/xerrors"
)

// Borrowed from (internal/imports/mod.go:620)
// This function will return the main go.mod file for this folder if it exists and whether the -modfile
// flag exists for this version of go.
func modfileFlagExists(ctx context.Context, folder string, env []string) (string, bool, error) {
const format = `{{.GoMod}}
{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
`
stdout, err := source.InvokeGo(ctx, folder, env, "list", "-m", "-f", format)
var tempEnv []string
for i := range env {
tempEnv = append(tempEnv, env[i])
if strings.Contains(env[i], "GO111MODULE") {
tempEnv[i] = "GO111MODULE=off"
}
}
// Borrowed from (internal/imports/mod.go:620)
const format = `{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}`
// Check the go version by running "go list" with modules off.
stdout, err := source.InvokeGo(ctx, folder, tempEnv, "list", "-f", format)
if err != nil {
return "", false, err
}
lines := strings.Split(stdout.String(), "\n")
if len(lines) < 2 {
return "", false, errors.Errorf("unexpected stdout: %q", stdout)
}
return lines[0], lines[1] == "go1.14", nil
// Get the go.mod file associated with this module.
b, err := source.InvokeGo(ctx, folder, env, "env", "GOMOD")
if err != nil {
return "", false, err
}
modfile := strings.TrimSpace(b.String())
if modfile == os.DevNull {
return "", false, errors.Errorf("go env GOMOD did not detect a go.mod file in this folder")
}
return modfile, lines[0] == "go1.14", nil
}

// The function getModfiles will return the go.mod files associated with the directory that is passed in.
Expand All @@ -51,22 +66,19 @@ func getModfiles(ctx context.Context, folder string, options source.Options) (*m
if modfile == "" || modfile == os.DevNull {
return nil, errors.Errorf("go env GOMOD cannot detect a go.mod file in this folder")
}
f, err := ioutil.TempFile("", "go.*.mod")
tempFile, err := ioutil.TempFile("", "go.*.mod")
if err != nil {
return nil, err
}
defer f.Close()
defer tempFile.Close()
// Copy the current go.mod file into the temporary go.mod file.
origFile, err := os.Open(modfile)
if err != nil {
return nil, err
}
defer origFile.Close()
if _, err := io.Copy(f, origFile); err != nil {
return nil, err
}
if err := f.Close(); err != nil {
if _, err := io.Copy(tempFile, origFile); err != nil {
return nil, err
}
return &modfiles{real: modfile, temp: f.Name()}, nil
return &modfiles{real: modfile, temp: tempFile.Name()}, nil
}

0 comments on commit acbc0e3

Please sign in to comment.