Skip to content
This repository was archived by the owner on Jan 31, 2024. It is now read-only.

Commit 097700a

Browse files
author
Henry Wong
committed
[elastic] Move the deps download into 'intialize' request handle
The original implementation relies on 'go list' to download the deps. And 'go list' will be called by the request handler indirectly. This approach is unpredictable and 'go list' is black box to us. So it's better download the deps manually in 'ManageDeps', i.e. inside 'initialize' request handler. If the client sends the initialize option `installGoDependency: true`, download the deps in `initialize` handler. If the client doesn't send the initialize option `installGoDependency: true`, disable the network access by `GOPROXY=off` and find the deps from vendor folder.
1 parent 2702523 commit 097700a

File tree

8 files changed

+43
-5
lines changed

8 files changed

+43
-5
lines changed

go/internal/packagesdriver/sizes.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/json"
1212
"fmt"
1313
"go/types"
14+
"golang.org/x/tools/internal/lsp/protocol"
1415
"log"
1516
"os"
1617
"os/exec"
@@ -125,6 +126,7 @@ func InvokeGo(ctx context.Context, env []string, dir string, usesExportData bool
125126
cmd.Dir = dir
126127
cmd.Stdout = stdout
127128
cmd.Stderr = stderr
129+
protocol.AdjustGoListForVendorMode(&(cmd.Env), &(cmd.Args))
128130
if err := cmd.Run(); err != nil {
129131
exitErr, ok := err.(*exec.ExitError)
130132
if !ok {

go/packages/golist.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"encoding/json"
1010
"fmt"
1111
"go/types"
12+
"golang.org/x/tools/internal/lsp/protocol"
1213
"hash/fnv"
1314
"io/ioutil"
1415
"log"
@@ -860,7 +861,7 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
860861
defer func(start time.Time) {
861862
cfg.Logf("%s for %v, stderr: <<%s>>\n", time.Since(start), cmdDebugStr(cmd, args...), stderr)
862863
}(time.Now())
863-
864+
protocol.AdjustGoListForVendorMode(&(cmd.Env), &(cmd.Args))
864865
if err := cmd.Run(); err != nil {
865866
// Check for 'go' executable not being found.
866867
if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {

internal/lsp/cache/session.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ func (s *session) NewView(ctx context.Context, name string, folder span.URI) sou
9393
},
9494
ignoredURIs: make(map[span.URI]struct{}),
9595
}
96+
if enableVendor, ok := ctx.Value("ENABLEVENDOR").(bool); ok && enableVendor {
97+
// Set 'GOPROXY=off' to disable the network access
98+
v.env = append(v.env, "GOPROXY=off")
99+
v.env = append(v.env, "ENABLEVENDOR=on")
100+
}
96101
// Preemptively build the builtin package,
97102
// so we immediately add builtin.go to the list of ignored files.
98103
v.buildBuiltinPkg(ctx)

internal/lsp/elasticserver.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,8 @@ type WorkspaceFolderMeta struct {
189189
// manageDeps will try its best to convert the folders to modules. The core functions, like deps downloading and deps
190190
// management, will be implemented in the package 'cache'.
191191
func (s ElasticServer) ManageDeps(folders *[]protocol.WorkspaceFolder) error {
192-
// Note: For the upstream go langserver, granularity of the workspace folders is repository. But for the elastic go
193-
// language server, there are repositories contain multiple modules. In order to handle the modules separately, we
194-
// consider different modules as different workspace folders, so we can manage the dependency of different modules
195-
// separately.
192+
// In order to handle the modules separately, we consider different modules as different workspace folders, so we
193+
// can manage the dependency of different modules separately.
196194
for _, folder := range *folders {
197195
metadata := &WorkspaceFolderMeta{}
198196
if folder.URI != "" {

internal/lsp/general.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ func (s *Server) initialize(ctx context.Context, params *protocol.InitializePara
3838
if opt, ok := opts["noIncrementalSync"].(bool); ok && opt {
3939
s.textDocumentSyncKind = protocol.Full
4040
}
41+
if opt, ok := opts["installGoDependency"].(bool); ok && opt {
42+
s.installGoDependency = true
43+
}
4144
}
4245

4346
// Default to using synopsis as a default for hover information.

internal/lsp/protocol/elasticserver.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ type ElasticServer interface {
1414
ManageDeps(folders *[]WorkspaceFolder) error
1515
}
1616

17+
func AdjustGoListForVendorMode(env *[]string, args *[]string) {
18+
l := len(*env)
19+
for i := range *env {
20+
if (*env)[l-i-1] == "ENABLEVENDOR=on" {
21+
// If 'ENABLEVENDOR' is on, append '-mod=vendor' to go list command
22+
for j := range *args {
23+
if (j+2 < len(*args)) && (*args)[j] == "go" && (*args)[j+1] == "list" {
24+
*args = append((*args)[:j+2], append([]string{"-mod=vendor"}, (*args)[j+2:]...)...)
25+
break
26+
}
27+
}
28+
return
29+
}
30+
}
31+
}
32+
1733
type elasticServerHandler struct {
1834
canceller
1935
server ElasticServer

internal/lsp/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ type Server struct {
8888
preferredContentFormat protocol.MarkupKind
8989
disabledAnalyses map[string]struct{}
9090
wantSuggestedFixes bool
91+
installGoDependency bool
9192

9293
supportedCodeActions map[source.FileKind]map[protocol.CodeActionKind]bool
9394

internal/lsp/workspace.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"context"
99

1010
"golang.org/x/tools/internal/lsp/protocol"
11+
"golang.org/x/tools/internal/lsp/telemetry/log"
1112
"golang.org/x/tools/internal/span"
1213
errors "golang.org/x/xerrors"
14+
"os/exec"
1315
)
1416

1517
func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFoldersChangeEvent) error {
@@ -31,6 +33,16 @@ func (s *Server) changeFolders(ctx context.Context, event protocol.WorkspaceFold
3133
}
3234

3335
func (s *Server) addView(ctx context.Context, name string, uri span.URI) error {
36+
if s.installGoDependency {
37+
cmd := exec.Command("go", "mod", "download")
38+
cmd.Dir = uri.Filename()
39+
if err := cmd.Run(); err != nil {
40+
log.Error(ctx, "failed to download the dependencies", err)
41+
}
42+
} else {
43+
// If we disable the go dependency download, trying to find the deps from the vendor folder.
44+
ctx = context.WithValue(ctx, "ENABLEVENDOR", true)
45+
}
3446
view := s.session.NewView(ctx, name, uri)
3547
s.stateMu.Lock()
3648
state := s.state

0 commit comments

Comments
 (0)