Gopls: Настройка рабочей среды
В протоколе языкового сервера «рабочая среда» (workspace) состоит из папки вместе с конфигурацией на папку. Некоторые клиенты LSP, такие как VS Code, позволяют явно настраивать рабочие среды, в то время как другие делают это автоматически, просматривая специальные файлы, определяющие корень рабочей среды (например, каталог .git или файл go.mod).
Чтобы функционировать, gopls требует определённой области действия, в которой функции языка, такие как ссылки, переименование и реализации, должны работать. Иными словами, gopls должен выводить из рабочей среды LSP, какие вызовы go build вы бы использовали для сборки вашей рабочей среды, включая рабочую директорию, среду и флаги сборки.
Ранее настройка рабочей среды такая, чтобы gopls мог правильно вывести информацию о сборке, могла быть сложной. Требовалось открыть правильную директорию или использовать файл go.work, чтобы сообщить gopls о модулях, над которыми вы работаете, а также заранее настроить правильную операционную систему и архитектуру. Если это не работало должным образом, gopls часто падал с загадочными ошибками — знаменитая ошибка «No packages found» (пакеты не найдены).
Начиная с версии gopls v0.15.0, настройка рабочей среды стала намного проще, и gopls обычно будет работать, когда вы откроете файл Go где угодно в своей рабочей среде. Если это не работает для вас или вы хотите лучше понять, как gopls моделирует вашу рабочую среду, пожалуйста, продолжайте читать.
Сборки рабочей среды
Начиная с gopls v0.15.0, gopls будет угадывать сборки, над которыми вы работаете, основываясь на наборе открытых файлов. Когда вы открываете файл в папке рабочей среды, gopls проверяет, содержится ли файл в модуле, рабочей среде go.work или в каталоге GOPATH, и соответствующим образом настраивает сборку. Кроме того, если вы открываете файл, ограниченный другой операционной системой или архитектурой, например, открываете foo_windows.go при работе в Linux, gopls создаст область с GOOS и GOARCH, установленными в значение, соответствующее файлу.
Например, предположим, что у нас есть репозиторий с тремя модулями: moda, modb и modc, и файл go.work, использующий модули moda и modb. Если мы открываем файлы moda/a.go, modb/b.go, moda/a_windows.go и modc/c.go, gopls автоматически создаст три сборки:

Это позволяет gopls просто работать, когда вы открываете файл Go, но это сопряжено с несколькими оговорками:
- Это заставляет gopls выполнять больше работы, поскольку теперь он отслеживает три сборки вместо одной. Однако недавняя переработка масштабируемости позволяет избежать большей части этой работы благодаря эффективному кэшированию.
- Для операций, вызванных из конкретного файла, таких как «Ссылки» или «Реализации», gopls выполняет операцию в стандартной сборке для этого файла. Например, поиск ссылок на символ
Sизfoo_linux.goвернёт ссылки из сборки для Linux, а поиск ссылок на тот же символSизfoo_windows.goвернёт ссылки из сборки для Windows. Gopls ищет в стандартной сборке для файла, но не ищет во всех возможных сборках (хотя это было бы удобно), потому что это может быть слишком затратно. Проблемы #65757 и #65755 предлагают улучшения этого поведения. - При выборе комбинации
GOOS/GOARCH, соответствующей файлу, ограниченному сборкой, gopls выберет первую подходящую комбинацию из этого списка. В некоторых случаях это может быть неожиданным. - При работе в файле, ограниченном
GOOS/GOARCH, не соответствующем вашей стандартной сборочной цепочке,CGO_ENABLED=0устанавливается неявно, поскольку C-компилятор для этой цели, вероятно, недоступен. Это означает, что gopls не будет работать в файлах, содержащихimport "C". Проблема #65758 может привести к улучшению этого поведения. - В настоящее время gopls не способен угадать флаги сборки, включающие произвольные пользовательские ограничения сборки, такие как файл с директивой сборки
//go:build mytag. Проблема #65089 предлагает эвристический подход, с помощью которого gopls мог бы автоматически обрабатывать такие случаи.
Пожалуйста, оставьте отзыв об этом поведении, поднимая голос или комментируя упомянутые выше вопросы, или открывая новый вопрос для других улучшений, которые вы хотели бы видеть.
Когда использовать файл go.work для разработки
Начиная с Go 1.18, команда go имеет встроенную поддержку многомодульных рабочих пространств, указанных файлами go.work.
Gopls будет распознавать эти файлы, если они присутствуют в вашем рабочем пространстве.
Используйте файл go.work, когда:
- вы хотите работать над несколькими модулями одновременно в одном логическом сборке, например, если вы хотите, чтобы изменения в одном модуле отражались в другом.
- вы хотите улучшить использование памяти или производительность gopls, уменьшив количество сборок, которые ему нужно отслеживать.
- вы хотите, чтобы gopls знал, над какими модулями вы работаете в многомодульном
рабочем пространстве, не открывая никаких файлов. Например, может быть удобно
использовать запросы
workspace/symbolдо открытия любых файлов. - вы используете gopls v0.14.2 или более раннюю версию и хотите работать над несколькими модулями.
Например, предположим, что этот репозиторий проверен в каталог $WORK/tools,
а x/mod проверен в
$WORK/mod, и вы работаете над новым API x/mod для редактирования файлов go.mod,
который вы хотите одновременно интегрировать в gopls.
Вы можете работать над golang.org/x/tools/gopls и golang.org/x/mod
одновременно, создав файл go.work:
<code class="language-sh">cd $WORK go work init go work use tools/gopls mod </code>
затем открывая каталог $WORK в вашем редакторе.
Когда вручную настраивать GOOS, GOARCH или -tags
Как описано в первом разделе, gopls v0.15.0 и выше будет пытаться
автоматически настроить новую область сборки, когда вы откроете файл, который
не соответствует системе по умолчанию (операционной системе GOOS) или архитектуре (GOARCH).
Однако, согласно ограничениям, указанным в этом разделе, это автоматическое поведение имеет
ограничения. Настройте среду gopls, установив GOOS или
GOARCH в вашем
"build.env"
или -tags=... в вашем
“build.buildFlags”
когда:
- Вы хотите изменить среду сборки по умолчанию.
- Gopls не угадывает комбинацию
GOOS/GOARCH, которую вы хотите использовать для кросс-платформенной разработки. - Вам нужно работать с файлом, ограниченным пользовательскими тегами сборки,
например, директивой сборки
//go:build mytag.
Режим GOPATH
При открытии каталога внутри каталога GOPATH область рабочей среды будет ограничена только этим каталогом и всеми содержащимися в нем каталогами. Следует отметить, что открытие большого каталога GOPATH может привести к очень медленному запуску gopls.
Исходные файлы этой документации можно найти в каталоге golang.org/x/tools/gopls/doc.