IDE/Linter Integration
The Go packages driver protocol is the standard way to integrate build systems with Go tools. Buck2 implements this protocol using BXL API, enabling golang.org/x/tools/go/packages.Load() based tools to work with Buck2.
How to use it? (golangci-lint example)
Set the GOPACKAGESDRIVER
environment variable to Buck2's gopackagesdriver
binary path and use your Go tool as usual.
There's no precise specification on how CLI tools should process input
arguments, but in general they should treat them as opaque. There are also query
operators file=
and pattern=
(docs).
So for a package "foo/bar"
, one of the examples below should work.
Let's see a golangci-lint
example:
$ export GOPACKAGESDRIVER=$(buck2 build prelude//go/tools/gopackagesdriver:gopackagesdriver --show-full-simple-output)
$ golangci-lint run foo/bar/baz.go
$ golangci-lint run file=foo/bar/baz.go # use file= if previous command doesn't work
$ golangci-lint run root//foo/bar:bar
$ golangci-lint run pattern=root//foo/bar:bar # use pattern= if previous command doesn't work
IDE Integration (gopls/VSCode)
Here's an example of using gopls and VSCode with Buck2. You can use the same approach for other IDEs and tools.
-
Install Go VSCode extension.
-
Create a wrapper script
tools/bin/gopackagesdriver.sh
inside your repo.
#!/usr/bin/env bash
exec buck2 run prelude//go/tools/gopackagesdriver:gopackagesdriver -- "${@}"
- Configure VSCode to use the driver.
{
"go.toolsEnvVars": {
"GOPACKAGESDRIVER": "${workspaceFolder}/tools/bin/gopackagesdriver.sh", # (required) path to the driver
"GOPACKAGESDRIVER_BUCK_OPTIONS": "--target-platforms prelude//platforms:default", # (optional) if your `toolchains//:go` requires it
"GOPACKAGESDRIVER_BUCK_ALL_PACKAGES_TARGET_EXPRS": "root//..." # (optional) index all packages on gopls startup (might be slow and unreliable)
},
"gopls": {
"build.workspaceFiles": [ # (required) to handle changes in BUCK files
"**/BUCK",
"**/PACKAGE",
"**/*.bzl",
"**/.buckconfig"
]
}
}
What tools are supported?
Theoretically, any tool based on
packages.Load()
should work. However, in practice, some tools may have assumptions about
specific build systems.
There are
8.2k occurrences
of packages.Load
on GitHub. You can check if your favorite tool is among them.
If it's not working correctly, you can make a PR to adjust its behavior.
The following tools are known to work well with GOPACKAGESDRIVER
:
gopls,
golangci-lint,
scip-go,
callgraph.
What tools are not supported?
Tools that directly call go list
or go build
are incompatible with this
approach.
Configuration
The driver is configured via environment variables:
GOPACKAGESDRIVER_BUCK_OPTIONS
- options passed tobuck2 bxl
andbuck2 run
commands.GOPACKAGESDRIVER_BUCK_ALL_PACKAGES_TARGET_EXPRS
- a list of target expressions separated by space, useful to replace./...
query thatgopls
does on startup.GOPACKAGESDRIVER_LOG_LEVEL
- log level, one ofdebug
,info
,warn
,error
. Defaults toinfo
.