# Работа с контрибами

## Менеджмент контрибов
Работа с контрибами осуществляется через [Go Modules](https://github.com/golang/go/wiki/Modules). Это относится только к контрибам, менеджмента зависимостей между проектами внутри самой Аркадии не подразумевается.

Использовать `go get` напрямую не получится, т.к. он не знает нюансов Аркадии. Вместо него есть специальный [тул](https://a.yandex-team.ru/arc/trunk/arcadia/library/go/yo/), который по сути оборачивает `go get` и делает дополнительные необходимые действия. Документация по его использованию можно почитать [тут](https://a.yandex-team.ru/arc/trunk/arcadia/library/go/yo/README.md).

Так как для менеджмента контрибов используются модули, а модули используют semver и поддерживают одновременно несколько мажорных версий одной зависимости, то технически любой контриб поддерживающий модульное версионирование может присутствовать в Аркадии в виде нескольких мажорных версий одновременно. Однако мы стремимся к тому, чтобы для решения какой-либо задачи было не более одного контриба одной мажорной версии.

## Типы контрибов
Контрибы могут быть прямыми и транзитивными зависимостями для Аркадийного кода.

### Прямые зависимости
Для прямых зависимостей используется [whitelist](https://a.yandex-team.ru/arc/trunk/arcadia/build/rules/go/vendor.policy), который явно описывает все разрешенные контрибы. Если нужного вам контриба нет в whitelist, то нужно будет [создать](https://st.yandex-team.ru/createTicket?queue=CONTRIB&_form=12959) тикет в специальной [очереди](https://st.yandex-team.ru/filters/filter:38070) в стартреке, а после утверждения контриба сделать PR в Аркадию с его добавлением в whitelist, go.mod и vendor (не забываем использовать нашу [утилиту](https://a.yandex-team.ru/arc/trunk/arcadia/library/go/yo/)). Тикет нужен даже если контриб физически уже лежит в vendor.

Мы настоятельно рекомендуем решать вопрос с вайтлистингом контрибов до того, как вы написали 100500 строк зависящего от них кода.

### Транзитивные зависимости
Для транзитивных зависимостей их набор или их версии никак не ограничиваются. Транзитивные зависимости не попадают в whitelist, но их количество и качество будет влиять на решение о добавлении основного контриба (вайтлистинга) - при прочих равных будет выбран тот контриб, который приносит с собой адекватные зависимости с актуальными версиями, а не набор чего-то рандомного.

## Работа с кодом внутри vendor
По умолчанию, код контрибов добавляется вместе с тестами.
- Это позволяет находить несовместимости между библиотеками на ранней стадии.
- Защищает нас от возможности "завендорить" поломаную версию библиотеки.
- Добавляет уверености при обновлении корневых зависимостей.
- Проверяет, что текущий тулчеин Go, а так же сборка и тесты через ya make работают как ожидается.

Поломки тестов или сборки, которые обнаруживаются в момент добавления/обновления контриба нужно чинить.

Есть несколько основных причин поломок:
1. Тест использует негерметичное окружение / ходит в сеть.
2. Тест полагается на наличие файлов из репозитория.
3. Тест приводит к "псевдо циклу зависимостей".
4. Тест использует библиотеку, которая не добавлена в vendor.
5. Тест не работает под платформой windows/darwin.
6. Имена тестов отличаются от запуска к запуску (например, потому что генерируются на лету).

Для решения проблем, можно:
1. Поменять настройки окружения отредактировав ya.make файл.
2. Отключить тест используя макрос [GO_SKIP_TESTS](https://a.yandex-team.ru/search?search=GO_SKIP_TESTS,%5Evendor.*,w,arcadia,,200)
3. [Отключить](https://a.yandex-team.ru/arc/trunk/arcadia/library/go/yo#caveats) тест/пакет на уровне системы сборки, закоментировав нужные части ya.make.
4. В случае если имена тестов отличаются от запуска к запуску, следует отключить парсер тестов при помощи `TAG(ya:go_total_report)` в `ya.make`. CI будет считать весь test suite одним тестом не вдаваясь в подробности каждого теста и его сабтестов.
4. Обновить / понизить версию другой библиотеки.

**Важно:** Менять файлы контриба руками нельзя. Редактировать руками можно только файлы ya.make.

### Советы по отладке
* Перед созданием PR стоит прогнать все тесты на distbuild, с помощью команды `ya make -t --dist vendor/github.com/my-contib`. Это позволит обнаружить проблемы окружения сразу и сэкономить время итерации.
* Если ваш коммит затронул слишком много файлов (больше 500000 строк), то стоит обратиться за помощью. Такой большой коммит может не влезть в PR и потребует разбиения на несколько мелких коммитов.
* Проверить корректность всех импортов можно не собирая код, с помощью команды `ya make -j0 -t vendor/github.com/my-contrib`.
