Skip to content

Commit 509ff8b

Browse files
findleyrgopherbot
authored andcommitted
gopls/doc: update workspace documentation for zero-config gopls
Rewrite the now-obsolete documentation. Notably, remove the section on experimental workspace mode, as it is long unsupported. For golang/go#57979 Change-Id: I8ba77d626d0b24b0ab34a78103985a5a881def21 Reviewed-on: https://go-review.googlesource.com/c/tools/+/566936 Reviewed-by: Hyang-Ah Hana Kim <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Robert Findley <[email protected]>
1 parent fb020a0 commit 509ff8b

File tree

2 files changed

+112
-83
lines changed

2 files changed

+112
-83
lines changed

gopls/doc/workspace.md

Lines changed: 112 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,130 @@
11
# Setting up your workspace
22

3-
`gopls` supports both Go module and GOPATH modes. However, it needs a defined
4-
scope in which language features like references, rename, and implementation
5-
should operate.
6-
7-
The following options are available for configuring this scope:
8-
9-
## Module mode
10-
11-
### One module
12-
13-
If you are working with a single module, you can open the module root (the
14-
directory containing the `go.mod` file), a subdirectory within the module,
15-
or a parent directory containing the module.
3+
**In general, `gopls` should work when you open a Go file contained in your
4+
workspace folder**. If it isn't working for you, or if you want to better
5+
understand how gopls models your workspace, please read on.
166

17-
**Note**: If you open a parent directory containing a module, it must **only**
18-
contain that single module. Otherwise, you are working with multiple modules.
7+
## Workspace builds
198

20-
### Multiple modules
21-
22-
Gopls has several alternatives for working on multiple modules simultaneously,
23-
described below. Starting with Go 1.18, Go workspaces are the preferred solution.
24-
25-
#### Go workspaces (Go 1.18+)
9+
`gopls` supports both Go module and GOPATH modes. However, it needs a defined
10+
scope in which language features like references, rename, and implementation
11+
should operate. Put differently, gopls needs to infer which `go build`
12+
invocations you would use to build your workspace, including the working
13+
directory, environment, and build flags.
14+
15+
Starting with `[email protected]`, gopls will try to guess the builds you are
16+
working on based on the set of open files. When you open a file in a workspace
17+
folder, gopls will check whether the file is contained in a module, `go.work`
18+
workspace, or GOPATH directory, and configure the build accordingly.
19+
Additionally, if you open a file that is constrained to a different operating
20+
system or architecture, for example opening `foo_windows.go` when working on
21+
Linux, gopls will create a scope with `GOOS` and `GOARCH` set to a value that
22+
matches the file.
23+
24+
For example, suppose we had a repository with three modules: `moda`, `modb`,
25+
and `modc`, and a `go.work` file using modules `moda` and `modb`. If we open
26+
the files `moda/a.go`, `modb/b.go`, `moda/a_windows.go`, and `modc/c.go`, gopls
27+
will automatically create three builds:
28+
29+
![Zero Config gopls](zeroconfig.png)
30+
31+
This allows `gopls` to _just work_ when you open a Go file, but it does come with
32+
several caveats:
33+
34+
- This causes gopls to do more work, since it is now tracking three builds
35+
instead of one. However, the recent
36+
[scalability redesign](https://go.dev/blog/gopls-scalability)
37+
allows much of this work to be avoided through efficient caching.
38+
- In some cases this may cause gopls to do more work, since gopls is now
39+
tracking three builds instead of one. However, the recent
40+
[scalability redesign](https://go.dev/blog/gopls-scalability) allows us
41+
to avoid most of this work by efficient caching.
42+
- For operations originating from a given file, including finding references
43+
and implementations, gopls executes the operation in
44+
_the default build for that file_. For example, finding references to
45+
a symbol `S` from `foo_linux.go` will return references from the Linux build,
46+
and finding references to the same symbol `S` from `foo_windows.go` will
47+
return references from the Windows build. This is done for performance
48+
reasons, as in the common case one build is sufficient, but may lead to
49+
surprising results. Issues [#65757](https://go.dev/issue/65757) and
50+
[#65755](https://go.dev/issue/65755) propose improvements to this behavior.
51+
- When selecting a `GOOS/GOARCH` combination to match a build-constrained file,
52+
`gopls` will choose the first matching combination from
53+
[this list](https://cs.opensource.google/go/x/tools/+/master:gopls/internal/cache/port.go;l=30;drc=f872b3d6f05822d290bc7bdd29db090fd9d89f5c).
54+
In some cases, that may be surprising.
55+
- When working in a `GOOS/GOARCH` constrained file that does not match your
56+
default toolchain, `CGO_ENABLED=0` is implicitly set. This means that `gopls`
57+
will not work in files including `import "C"`. Issue
58+
[#65758](https://go.dev/issue/65758) may lead to improvements in this
59+
behavior.
60+
- `gopls` is not able to guess build flags that include arbitrary user-defined
61+
build constraints. For example, if you are trying to work on a file that is
62+
constrained by the build directive `//go:build special`, gopls will not guess
63+
that it needs to create a build with `"buildFlags": ["-tags=special"]`. Issue
64+
[#65089](https://go.dev/issue/65089) proposes a heuristic by which gopls
65+
could handle this automatically.
66+
67+
We hope that you provide feedback on this behavior by upvoting or commenting
68+
the issues mentioned above, or opening a [new issue](https://go.dev/issue/new)
69+
for other improvements you'd like to see.
70+
71+
## When to use a `go.work` file for development
2672

2773
Starting with Go 1.18, the `go` command has native support for multi-module
28-
workspaces, via [`go.work`](https://go.dev/ref/mod#workspaces) files. These
29-
files are recognized by gopls starting with `[email protected]`.
30-
31-
The easiest way to work on multiple modules in Go 1.18 and later is therefore
32-
to create a `go.work` file containing the modules you wish to work on, and set
33-
your workspace root to the directory containing the `go.work` file.
34-
35-
For example, suppose this repo is checked out into the `$WORK/tools` directory.
36-
We can work on both `golang.org/x/tools` and `golang.org/x/tools/gopls`
37-
simultaneously by creating a `go.work` file using `go work init`, followed by
38-
`go work use MODULE_DIRECTORIES...` to add directories containing `go.mod` files to the
39-
workspace:
74+
workspaces, via [`go.work`](https://go.dev/ref/mod#workspaces) files. `gopls`
75+
will recognize these files if they are present in your workspace.
76+
77+
Use a `go.work` file when:
78+
79+
- You want to work on multiple modules simultaneously in a single logical
80+
build, for example if you want changes to one module to be reflected in
81+
another.
82+
- You want to improve `gopls'` memory usage or performance by reducing the number
83+
of builds it must track.
84+
- You want `gopls` to know which modules you are working on in a multi-module
85+
workspace, without opening any files. For example, if you want to use
86+
`workspace/symbol` queries before any files are open.
87+
- You are using `[email protected]` or earlier, and want to work on multiple
88+
modules.
89+
90+
For example, suppose this repo is checked out into the `$WORK/tools` directory,
91+
and [`x/mod`](https://pkg.go.dev/golang.org/x/mod) is checked out into
92+
`$WORK/mod`, and you are working on a new `x/mod` API for editing `go.mod`
93+
files that you want to simultaneously integrate into `gopls`.
94+
95+
You can work on both `golang.org/x/tools/gopls` and `golang.org/x/mod`
96+
simultaneously by creating a `go.work` file:
4097

4198
```sh
4299
cd $WORK
43100
go work init
44-
go work use ./tools/ ./tools/gopls/
101+
go work use tools/gopls mod
45102
```
46103

47-
...followed by opening the `$WORK` directory in our editor.
48-
49-
#### DEPRECATED: Experimental workspace module (Go 1.17 and earlier)
50-
51-
**This feature is deprecated and will be removed in future versions of gopls.
52-
Please see [issue #52897](https://go.dev/issue/52897) for additional
53-
information.**
54-
55-
With earlier versions of Go, `gopls` can simulate multi-module workspaces by
56-
creating a synthetic module requiring the modules in the workspace root.
57-
See [the design document](https://github.com/golang/proposal/blob/master/design/37720-gopls-workspaces.md)
58-
for more information.
59-
60-
This feature is experimental, and will eventually be removed once `go.work`
61-
files are accepted by all supported Go versions.
62-
63-
You can enable this feature by configuring the
64-
[experimentalWorkspaceModule](settings.md#experimentalworkspacemodule-bool)
65-
setting.
66-
67-
#### Multiple workspace folders
68-
69-
If neither of the above solutions work, and your editor allows configuring the
70-
set of
71-
["workspace folders"](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspaceFolder)
72-
used during your LSP session, you can still work on multiple modules by adding
73-
a workspace folder at each module root (the locations of `go.mod` files). This
74-
means that each module has its own scope, and features will not work across
75-
modules.
76-
77-
In VS Code, you can create a workspace folder by setting up a
78-
[multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces).
79-
View the [documentation for your editor plugin](../README.md#editor) to learn how to
80-
configure a workspace folder in your editor.
81-
82-
### GOPATH mode
104+
...followed by opening the `$WORK` directory in your editor.
83105

84-
When opening a directory within your GOPATH, the workspace scope will be just
85-
that directory.
106+
## When to manually configure `GOOS`, `GOARCH`, or `-tags`
86107

87-
### At your own risk
108+
As described in the first section, `[email protected]` and later will try to
109+
configure a new build scope automatically when you open a file that doesn't
110+
match the system default operating system (`GOOS`) or architecture (`GOARCH`).
88111

89-
Some users or companies may have projects that encompass one `$GOPATH`. If you
90-
open your entire `$GOPATH` or `$GOPATH/src` folder, the workspace scope will be
91-
your entire `GOPATH`. If your GOPATH is large, `gopls` to be very slow to start
92-
because it will try to find all of the Go files in the directory you have
93-
opened. It will then load all of the files it has found.
112+
However, per the caveats listed in that section, this automatic behavior comes
113+
with limitations. Customize your `gopls` environment by setting `GOOS` or
114+
`GOARCH` in your
115+
[`"build.env"`](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#env-mapstringstring)
116+
or `-tags=...` in your"
117+
["build.buildFlags"](https://github.com/golang/tools/blob/master/gopls/doc/settings.md#buildflags-string)
118+
when:
94119

95-
To work around this case, you can create a new `$GOPATH` that contains only the
96-
packages you want to work on.
120+
- You want to modify the default build environment.
121+
- `gopls` is not guessing the `GOOS/GOARCH` combination you want to use for
122+
cross platform development.
123+
- You need to work on a file that is constrained by a user-defined build tags,
124+
such as the build directive `//go:build special`.
97125

98-
---
126+
## GOPATH mode
99127

100-
If you have additional use cases that are not mentioned above, please
101-
[file a new issue](https://github.com/golang/go/issues/new).
128+
When opening a directory within your `GOPATH`, the workspace scope will be just
129+
that directory and all directories contained within it. Note that opening
130+
a large GOPATH directory can make gopls very slow to start.

gopls/doc/zeroconfig.png

34.6 KB
Loading

0 commit comments

Comments
 (0)