# Единый репозиторий Аркадия

Важной особенностью разработки в Яндексе является использование единого репозитория с исходными кодами, который называется [Аркадия](https://a.yandex-team.ru/).

## Зачем нужен единый репозиторий { #why }

Исторически разные команды в Яндексе по своему усмотрению выбирали инструменты для хранения, сборки, тестирования и выкладки исходного кода на продакшн. Было развернуто несколько разных репозиториев (Subversion, Git, Mercurial), а в каждой команде мог использоваться собственный CI-сервер и свои процессы разработки. В определенный момент такая разрозненность стала мешать и порождала множество проблем:

1. **Сложность совместного использования кода.** Многие сервисы Яндекса имеют похожую функциональность. Например, Поиск, Маркет и Почта дают возможность поиска. Вместо того, чтобы каждой команде писать свой собственный поисковой движок, можно развивать один и синхронно обновлять его во всех зависимых сервисах. Это позволяет быстро доводить до продакшна улучшения и исправления в общих компонентах.

2. **Отсутствие единых правил хранения кода.** При тех объемах кода, что есть в Яндексе, можно легко потеряться в обилии отдельных репозиториев. Нет простого способа определить где лежит требуемый компонент, как он работает, кто его сейчас пишет и правит, как его начать использовать.

3. **Отсутствие единых правил оформления кода.** Известно, что существуют различные стили написания кода: расстановки скобок, добавления отступов и т.д. Для того, чтобы наиболее эффективно писать код, очень желательно, чтобы все разработчики писали в едином утверждённом стиле.

4. **Отсутствие единых стандартов code review, сборки, тестирования и выкладки.** Это приводит к тому, что взаимодействие между командами идет медленнее, чем могло бы.

5. **Бесконтрольное использование внешних библиотек.** Это не только мешает интеграции компонентов между собой, потому что могут возникать конфликты зависимостей, но и потенциально может приводить к неконтролируемому появлению уязвимостей в продакшне. 

Эти и многие другие причины привели к появлению в 2013 году проекта по переезду всех ключевых подразделений компании в единый репозиторий с общими правилами разработки. Для обозначения этого проекта взаимозаменяемо употребляются термины "Devtools", "Unity" и "разработка в Аркадии". Яндекс - не единственная компания, где применяется подобный подход. Известно, что единый репозиторий активно используется, например, в Facebook и Google.

## Особенности единого репозитория { #properties }

1. **Исходные коды всех проектов хранятся в одном месте.** Для каждого крупного проекта заводится отдельный каталог, где расположены его исходные коды. Есть специальный каталог для хранения исходных кодов общих внутренних библиотек (**library**), внешних библиотек (**contrib**) и экспериментов (**junk**).

2. **Trunk-based development.** Хранение исходного кода можно представить в виде обычного дерева. Весь актуальный код хранится в главной "ветке", которая называется "транк" (англ. trunk - ствол). В определенных случаях от ствола могут отводиться дочерние ветки (branches). Все проекты должны отправлять свои коммиты в транк.

3. **Зеленый транк (green trunk).** Это означает, что любые изменения перед добавлением в транк должны быть проверены набором тестов. Изменения, для которых тесты не проходят, не должны добавляться в транк. В Аркадии добавление изменений организовано через пулл-реквесты (pull-request), аналогично тому, как это сделано в Github. Выполнение тестов для проверки пулл-реквеста называется **прекоммитная проверка**.

4. **Герметичность.** Это означает, что любой из проектов, хранящихся в едином репозитории, можно собрать, используя только исходные коды из этого репозитория. Очевидно, что такого можно достичь, только, если хранить исходные коды внешних библиотек и описание процесса сборки в том же репозитории.

## Уровни использования единого репозитория { #tier }

В идеальном мире все проекты компании уже давно должны были использовать подход единого репозитория. Но мы живем в реальном мире, где команды должны делать крутые продукты и выкатывать релизы, поэтому в едином репозитории предусмотрено два уровня использования, которые называются **tier** (англ. tier - уровень):

* **Tier 0** означает проекты, полностью интегрированные со всеми рекомендуемыми инструментами и технологиями разработки в едином репозитории. Сюда относится большинство проектов на C++, Java, Python и Go.

* **Tier 1** означает проекты, исходные коды которых хранятся в едином репозитории, но при этом используют собственные инструменты тестирования и сборки. В первую очередь сюда относятся проекты мобильной и фронтенд-разработки.

## Файловая структура { #filestructure }

В Аркадии введены ограничения, касающиеся именования файлов и директорий, а также файловой структуры репозитория:
* Символические ссылки запрещены
* Имена файлов и директорий могут содержать только следующие символы:
  * Буквы английского алфавита в верхнем и нижнем регистре `a-zA-Z`
  * Цифры `0-9`
  * Пробел
  * Пунктуационные знаки `_`, `-`, `.`, `,`, `~`, `(`, `)`, `[`, `]`, `{`, `}`, `+`, `=`, `#`, `$`, `@`, `!`
  * Символ `%`, но только единожды в рамках всего пути к файлу или директории от корня репозитория
* Имена файлов и директорий не могут:
  * Начинаться с пробела
  * Заканчиваться на пробел или точку `.`
* Файлы и директории не могут быть названы следующим образом (в любом регистре):
  * `con`, `prn`, `aux`, `nul`
  * `comN` или `lptN` где `N` - цифра от 1 до 9
  * `.arc`, `.git`, `.svn`, `.hg`, `.hglfs`, `.bzr`
* Директория не может содержать файлы или директории, названия которых отличаются только регистром
* Длина имени файла или директории (компонента пути) не должна превышать 143 символа
