# Getting started

Go уже в Аркадии, а значит пришло время начать работать с Аркадийным Go кодом локально.

Ниже мы рассмотрим как правильно получить код через `arc`, настроить окружение и собрать код стандартным тулингом.

## Arc

Для установки arc и его зависимостей необходимо выполнить [данную инструкцию](https://docs.yandex-team.ru/devtools/intro/quick-start-guide).

## Настройка IDE

### Goland

Чтобы открыть код в Goland, нужно сгенерировать проект используя команду `ya ide goland`. Эта команда включает
правильные настройки проекта, необходимые для работы с аркадией. Если вы попробуете создать Goland проект в обход этой команды,
то Goland не будет работать, или будет работать неправильно.

```
# Нужно запускать из корня аркадии
ya ide goland my/project/root other/project -P ~/GolandProjects/project_name
```

В результате в директории `$HOME/GolandProjects/project_name` будет сгенерирован GoLand проект (папка `.idea`). В GoLand надо будет открывать именно `$HOME/GolandProjects/project_name`, не корень Аркадии!

### VsCode

1. Открываем одну из директорий своего проекта. File -> Open Folder.
2. Добавляем другие директории из аркадии, которые нам необходимы. File -> Add folder to workspace.
3. В настройках workspace дописываем `"gopls.expandWorkspaceToModule": false`, чтобы gopls не пытался индексировать всю аркадию.

### VIm/NeoVim

Минимальная конфигурация описана ниже. Для дополнительных настроек см. [документацию](https://raw.githubusercontent.com/fatih/vim-go/master/doc/vim-go.txt) или `:h vim-go`.

1. Устанавливаем плагин `fatih/vim-go`
2. В корневой `.vimrc` добавляем следующее:

```(vim)
set exrc " разрешаем подгружать дополнительные .vimrc из папок по месту
set secure " запрещаем подгружать .vimrc не от нашего пользователя/группы (Unix)

" включаем форматирование кода и импортов при сохранении
let g:go_fmt_autosave = 1
let g:go_imports_autosave = 1
```

3. В глоабальный `.arcignore` добавляем строчку `.vimrc`, чтобы случайно не закоммитить локальные настройки в Аркадию
4. В корне Аркадии создаем файл `.vimrc`, который будет подгружаться при открытии корня Аркадии в vim:

```(vim)
let g:go_gopls_local = 'a.yandex-team.ru'
let g:go_gopls_settings = { 'directoryFilters': [ '-', '+<ваша_папка>', '-library', '+library/go' ], 'expandWorkspaceToModule': 0 }
```

Теперь при открытии корня Аркадии vim'ом (`$ cd $ARCADIA_ROOT && vim .`) будут применяться глобальные настройки из корневого `.vimrc`, а также специальные настройки для Аркадии из `$ARCADIA_ROOT/.vimrc`, которые не позволят `gopls` пытаться индексировать всю Аркадию.


## Настройка toolchain в терминале

Код в аркадии всегда собирается одной версией go. Версия go обновляется раз в пол года, с небольшой задержкой после официального релиза.

Путь до go toolchain можно получить, запустив команду `ya tool go --print-toolchain-path`. Эта команда скачает версию тулчейна, соответствующую
текущему коммиту в рабочей копии.

Рекомендуется добавить следующую строчку в свой `.bashrc`

```
$ export PATH=$(ya tool go --print-toolchain-path)/bin:$PATH
```

Важно, чтобы команда `ya tool go --print-toolchain-path` исполнялась каждый раз при запуске терминала. Тогда во время обновления toolchain в аркадии
вам будет достаточно перезапустить терминал, чтобы получить новую версию go. Если вы просто сохраните где-то путь из `ya tool go --print-toolchain-path`,
то при следующем обновлении toolchain он станет указывать на неактуальную версию `go`.

## Сборка кода и тестирование

Аркадия поддерживает два способа сборки go кода:

### Сборка через `ya make`

Сборка через `ya make` работает всегда. Этот вид сборки работает универсально между разными языками программирования.
Запуск тестов через `ya make` поддерживает аркадийные рецепты и распределённую сборку.

Более подробно про работу с `ya make` описано в [соответствующем разделе документации](https://docs.yandex-team.ru/ya-make/general/getting_started)

### Сборка через `go build`

Сборка через `go build` работает только для go проектов. Этот вид сборки не поддерживает CGO зависимости,
требует ручной генерации кода, не поддерживает окружение запуска тестов из `ya make` и не проверяется в CI.

Этот вид сборки используют все IDE, поэтому все проекты в аркадии должны собираться в такой конфигурации.

Если проект зависит от cgo, то обычная сборка с `go build` будет падать с непонятными ошибками.

```
prime@prime-dev ~/arc> go build ./library/go/yandex/tvm/tvmauth
# a.yandex-team.ru/library/go/yandex/tvm/tvmauth
In file included from library/go/yandex/tvm/tvmauth/client.go:5:0:
./tvm.h:3:10: fatal error: util/system/types.h: No such file or directory
 #include <util/system/types.h>
          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
```

В этом случае нужно использовать флаг `CGO_ENABLED=0`.

```
prime@prime-dev ~/arc> env CGO_ENABLED=0 go build ./library/go/yandex/tvm/tvmauth
```

Сборка через `go build` используется в IDE для запуска тестов. Если тесты завязаны на аркадийное окружение тестов, например
если они используют рецепты, то запустить их через IDE не получится.

## Генерация кода

Для генерации кода в аркадии используется команда `ya make` с аргументами `--replace-result --add-result .go`.

```
# Запуск команды запустит генерацию кода во всех транзитивных зависимостях path/to/my/project
# и добавит в рабочую копию симлинки на сгенерированные файлы
ya make --replace-result --add-result .go path/to/my/project
```

Генерация кода никак не интегрирована с `go build`. Если вы работаете с кодом из IDE,
то нужно периодически запускать генерацию кода руками. Если этого не делать, в рабочей копии могут остаться
ссылки на устаревшие файлы.
