# Правила разработки

## Основные принципы

### Система контроля версий

Код проекта X размещен на GitHub:

- Ядро Xray [Xray-core](https://github.com/XTLS/Xray-core)
- Скрипты установки [Xray-install](https://github.com/XTLS/Xray-install)
- Шаблоны конфигурации [Xray-examples](https://github.com/XTLS/Xray-examples)
- Документация по Xray [Xray-docs-next](https://github.com/XTLS/Xray-docs-next)

Вы можете использовать [Git](https://git-scm.com/) для получения кода.

### Ветки (Branch)

- Основной веткой проекта является main.
- Основной веткой для выпуска релизов также является main.
- Необходимо убедиться, что main в любой момент времени может быть скомпилирован и работает корректно.
- Если вам нужно разработать новую функцию, создайте новую ветку для разработки. После завершения разработки и тщательного тестирования объедините ее с основной веткой.
- Удалите ветки, которые были объединены с основной веткой и больше не нужны.

### Релизы (Release)

<Badge text="В РАЗРАБОТКЕ" type="warning"/>

- Создайте два канала выпуска: для предварительных версий и для стабильных версий.
  - Предварительные версии могут быть ежедневными сборками, в основном используются для тестирования в определенных ситуациях, ознакомления с новыми функциями и получения обратной связи для дальнейшего улучшения.
  - Стабильные версии выпускаются по расписанию (например, ежемесячно) и содержат стабильные изменения.

### Использование других проектов

- Golang
  - В коде рекомендуется использовать стандартную библиотеку Golang и библиотеки из [golang.org/x/](https://pkg.go.dev/search?limit=25&m=package&q=golang.org%2Fx).
  - Если вам нужно использовать другие проекты, сначала создайте issue для обсуждения.
- Другие
  - Можно использовать любые инструменты, которые не нарушают лицензии обеих сторон и полезны для проекта.

## Процесс разработки

### Перед написанием кода

Если вы обнаружили какую-либо проблему или у вас есть идеи по улучшению проекта, создайте [issue](https://github.com/XTLS/Xray-core/issues) для обсуждения, чтобы избежать дублирования усилий и траты времени на написание кода.

### Изменение кода

- Golang
  - См. [Effective Go](https://golang.org/doc/effective_go.html).
  - Перед каждой отправкой (push) выполните команду: `go generate core/format.go`.
  - Если вам нужно изменить protobuf, например, добавить новый параметр конфигурации, выполните команду: `go generate core/proto.go`.
  - Перед отправкой pull request рекомендуется запустить тесты: `go test ./...`.
  - Перед отправкой pull request рекомендуется, чтобы новый код имел покрытие кода (code coverage) не менее 70%.
- Другие
  - Обратите внимание на читаемость кода.

### Запрос на включение изменений (Pull Request)

- Перед отправкой PR сначала выполните команду `git pull https://github.com/XTLS/Xray-core.git`, чтобы убедиться, что слияние пройдет гладко.
- Один PR должен решать только одну задачу. Если вы исправляете несколько ошибок, отправьте по одному PR для каждой ошибки.
- Из-за особенностей Golang (пути к пакетам) процесс PR для проектов Go отличается от других проектов. Рекомендуемый процесс следующий:
  1. Сначала сделайте форк (fork) проекта, создайте свой собственный репозиторий `github.com/<your_name>/Xray-core.git`.
  2. Клонируйте свой репозиторий Xray локально: `git clone https://github.com/<your_name>/Xray-core.git`.
  3. Создайте новую ветку на основе ветки `main`, например, `git branch issue24 main`.
  4. Внесите изменения в новую ветку и зафиксируйте их (commit).
  5. Перед отправкой (push) измененной ветки в свой репозиторий переключитесь на ветку `main` и выполните команду `git pull https://github.com/XTLS/Xray-core.git`, чтобы получить последнюю версию кода.
  6. Если на предыдущем шаге были получены новые изменения, переключитесь на созданную вами ветку и выполните команду `git rebase main` для слияния веток. Если возникнут конфликты файлов, их необходимо разрешить.
  7. После завершения предыдущего шага вы можете отправить свою ветку в свой репозиторий: `git push -u origin your-branch`.
  8. Наконец, отправьте PR из своей ветки в ветку `main` репозитория `XTLS/Xray-core`.
  9. В заголовке и описании PR четко опишите проблему, которую решает этот PR / новую функцию / цель изменений кода.
  10. Дождитесь ответа разработчиков.

### Изменения кода

#### Проблемы с функциональностью

Отправьте хотя бы один тестовый пример (Test Case), чтобы проверить изменения в существующей функциональности.

#### Проблемы с производительностью

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

#### Новые функции

- Если новая функция не влияет на существующую функциональность, предоставьте переключатель (например, флаг) для ее включения/отключения и оставьте ее отключенной по умолчанию.
- Перед разработкой новой крупной функции (например, добавления нового протокола) создайте issue для обсуждения.

#### Другое

Зависит от конкретной ситуации.

## Стандарты кодирования Xray

Следующие правила применяются к коду Golang в Xray.

### Структура кода

```
Xray-core
├── app        // Модули приложений
│   ├── router // Маршрутизация
├── common     // Общий код
├── proxy      // Протоколы связи
│   ├── blackhole
│   ├── dokodemo-door
│   ├── freedom
│   ├── socks
│   ├── vmess
├── transport  // Транспортные модули
```

### Стандарты кодирования

В основном соответствуют рекомендациям Golang, за некоторыми исключениями. Приведены здесь для удобства ознакомления с Golang.

#### Именование

- Для имен файлов и каталогов по возможности используйте одно английское слово, например, hello.go.
  - Если это невозможно, используйте дефисы для разделения слов в имени каталога и подчеркивания для разделения слов в имени файла, например, hello-world/hello_again.go.
  - Тестовый код должен иметь суффикс \_test.go.
- Для типов используйте нотацию PascalCase, например, ConnectionHandler.
  - Сокращения не обязательно писать в нижнем регистре, то есть HTML не нужно писать как Html.
- Для публичных переменных-членов также используйте нотацию PascalCase.
- Для приватных переменных-членов используйте [нотацию camelCase](https://ru.wikipedia.org/wiki/CamelCase), например, `privateAttribute`.
- Для удобства рефакторинга рекомендуется использовать нотацию PascalCase для всех методов.
  - Полностью приватные типы помещайте в каталог `internal`.

#### Организация кода

- Один файл должен содержать один основной тип и связанные с ним приватные функции.
- Тестовые файлы, такие как Mock и другие утилиты, помещайте в подкаталог testing.

#### Int32Range

**Для конечного пользователя**

Значение, представляющее собой необязательный диапазон. Возможные варианты записи:

- Отдельное число или диапазон, заключенные в кавычки:
  - `""` (считается как 0). Обратите внимание, что полное отсутствие настройки поля и установка пустого значения могут иметь разное значение.
  - `"114"`
  - `"114-514"`
- Отдельное целое число (int). В этом случае возможно указать только одно число:
  - `114`

**Для разработчика**

Если вам нужно использовать диапазон в файле конфигурации, используйте тип `Int32Range`. Для получения значений используйте `.From` и `.To` вместо использования строкового типа (`string`) и последующего ручного разбора.

Метод `.EnsureOrder()` можно использовать для обмена значений From и To, если From больше, чем To (при необходимости).
