Skip to content

Commit

Permalink
internal/lsp: add a configuration to limit workspace scope to root URI
Browse files Browse the repository at this point in the history
Some users may intentionally be opening subdirectories to avoid having
gopls load the whole module. Allow this via a configuration.

Fixes golang/go#40567

Change-Id: I6167f62a74a1c0b7cf07c1cb247adda839ee41f2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/247617
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
  • Loading branch information
stamblerre committed Aug 11, 2020
1 parent 64be3c5 commit 48de4c8
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 6 deletions.
11 changes: 10 additions & 1 deletion gopls/doc/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,28 @@ Default: `false`.

This controls where points documentation for given package in `textDocument/documentLink`.
It might be one of:

* `"godoc.org"`
* `"pkg.go.dev"`
If company chooses to use its own `godoc.org`, its address can be used as well.

Default: `"pkg.go.dev"`.

### **local** string
### **local** *string*

This is the equivalent of the `goimports -local` flag, which puts imports beginning with this string after 3rd-party packages.
It should be the prefix of the import path whose imports should be grouped separately.

Default: `""`.

### **expandWorkspaceToModule** *boolean*

This is true if `gopls` should expand the scope of the workspace to include the
modules containing the workspace folders. Set this to false to avoid loading
your entire module. This is particularly useful for those working in a monorepo.

Default: `true`.

## Experimental

The below settings are considered experimental. They may be deprecated or changed in the future. They are typically used to test experimental opt-in features or to disable features.
Expand Down
2 changes: 1 addition & 1 deletion internal/lsp/cache/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (s *Session) createView(ctx context.Context, name string, folder span.URI,
v.session.cache.options(&v.options)
}
// Set the module-specific information.
if err := v.setBuildInformation(ctx, folder, options.Env, v.options.TempModfile); err != nil {
if err := v.setBuildInformation(ctx, folder, options); err != nil {
return nil, nil, func() {}, err
}

Expand Down
8 changes: 4 additions & 4 deletions internal/lsp/cache/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,12 @@ func (v *View) maybeReinitialize() {
v.initializeOnce = &once
}

func (v *View) setBuildInformation(ctx context.Context, folder span.URI, env []string, modfileFlagEnabled bool) error {
func (v *View) setBuildInformation(ctx context.Context, folder span.URI, options source.Options) error {
if err := checkPathCase(folder.Filename()); err != nil {
return fmt.Errorf("invalid workspace configuration: %w", err)
}
// Make sure to get the `go env` before continuing with initialization.
modFile, err := v.setGoEnv(ctx, env)
modFile, err := v.setGoEnv(ctx, options.Env)
if err != nil {
return err
}
Expand All @@ -763,7 +763,7 @@ func (v *View) setBuildInformation(ctx context.Context, folder span.URI, env []s
}

v.root = v.folder
if v.modURI != "" {
if options.ExpandWorkspaceToModule && v.modURI != "" {
v.root = span.URIFromPath(filepath.Dir(v.modURI.Filename()))
}

Expand All @@ -772,7 +772,7 @@ func (v *View) setBuildInformation(ctx context.Context, folder span.URI, env []s
v.setBuildConfiguration()

// The user has disabled the use of the -modfile flag or has no go.mod file.
if !modfileFlagEnabled || v.modURI == "" {
if !options.TempModfile || v.modURI == "" {
return nil
}
if modfileFlag, err := v.modfileFlagExists(ctx, v.Options().Env); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/lsp/fake/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ type EditorConfig struct {
// config option.
SymbolMatcher *string

// LimitWorkspaceScope is true if the user does not want to expand their
// workspace scope to the entire module.
LimitWorkspaceScope bool

// WithoutWorkspaceFolders is used to simulate opening a single file in the
// editor, without a workspace root. In that case, the client sends neither
// workspace folders nor a root URI.
Expand Down Expand Up @@ -170,6 +174,7 @@ func (e *Editor) configuration() map[string]interface{} {
config := map[string]interface{}{
"verboseWorkDoneProgress": true,
"env": e.overlayEnv(),
"expandWorkspaceToModule": !e.Config.LimitWorkspaceScope,
}

if e.Config.CodeLens != nil {
Expand Down
30 changes: 30 additions & 0 deletions internal/lsp/regtest/diagnostics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1118,3 +1118,33 @@ func main() {}
)
})
}

// This tests the functionality of the "limitWorkspaceScope"
func TestLimitWorkspaceScope(t *testing.T) {
const mod = `
-- go.mod --
module mod.com
-- a/main.go --
package main
func main() {}
-- main.go --
package main
func main() {
var x int
}
`
withOptions(WithRootPath("a")).run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
env.Await(
env.DiagnosticAtRegexp("main.go", "x"),
)
})
withOptions(WithRootPath("a"), WithLimitWorkspaceScope()).run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("a/main.go")
env.Await(
NoDiagnostics("main.go"),
)
})
}
7 changes: 7 additions & 0 deletions internal/lsp/regtest/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ func WithGOPROXY(goproxy string) RunOption {
})
}

// WithLimitWorkspaceScope sets the LimitWorkspaceScope configuration.
func WithLimitWorkspaceScope() RunOption {
return optionSetter(func(opts *runConfig) {
opts.editor.LimitWorkspaceScope = true
})
}

type TestFunc func(t *testing.T, env *Env)

// Run executes the test function in the default configured gopls execution
Expand Down
8 changes: 8 additions & 0 deletions internal/lsp/source/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func DefaultOptions() Options {
CommandRegenerateCgo.Name: true,
CommandToggleDetails.Name: false,
},
ExpandWorkspaceToModule: true,
},
DebuggingOptions: DebuggingOptions{
CompletionBudget: 100 * time.Millisecond,
Expand Down Expand Up @@ -226,6 +227,10 @@ type UserOptions struct {

// Gofumpt indicates if we should run gofumpt formatting.
Gofumpt bool

// ExpandWorkspaceToModule is true if we should expand the scope of the
// workspace to include the modules containing the workspace folders.
ExpandWorkspaceToModule bool
}

type ImportShortcut int
Expand Down Expand Up @@ -576,6 +581,9 @@ func (o *Options) set(name string, value interface{}) OptionResult {
case "gofumpt":
result.setBool(&o.Gofumpt)

case "expandWorkspaceToModule":
result.setBool(&o.ExpandWorkspaceToModule)

// Replaced settings.
case "experimentalDisabledAnalyses":
result.State = OptionDeprecated
Expand Down

0 comments on commit 48de4c8

Please sign in to comment.