urfu-daddy/CONTRIBUTE.md

115 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Инструкция по внесению изменений в проект.
## Введение.
Этот файл содержит подробное описание принципов, которые необходимо соблюдать при участии в разработке данного проекта.
Все изменения исходного кода требуется совершать в тематических ветках, некоторые из них уже могут быть в проекте, например, `feature/handlers` для работы с командами и callback'ами бота, `feature/docker` для настройки развертки проекта через Docker. Если вы собираетесь сделать несколько независимых задач, то это следует делать в разных тематических ветках. Если ваша основная задача связана с другими аспектами проекта, например, требует изменений в докере, то вам следует делать эти изменения в тематической ветке вашей основной задачи, не следует дробить на ветки **зависимости** вашей основной ветки. Ветка - это именно указание основной тематики ваших изменений. Их названия не означают, что в них можно изменять только соответствующие модули проекта.
После завершения работы над изменениями следует создать PR на их внедрение в ветку `develop` . Так как в ветке `develop` всегда находится завершенный и рабочий код, это еще раз подчеркивает важность правильной работы с тематическими ветками. Изменения в них должны быть самостоятельны и не зависить от изменений в других ветка. Затем проходит проверка PR и если всё хорошо, то изменения будут приняты в `develop` .
Не забывайте синхронизировать вашу тематическую ветку с текущей веткой `develop` .
Помимо сливания в ветку `develop` изменений из тематических веток, в ней также допускаются коммиты хот-фиксы/фиксы, направленные на устранение любых неисправностей, уязвимостей, критических ошибок.
Когда задачи, намеченные на новый релиз проекта выполнены, версия проекта в ветке `develop` ещё раз тестируется и затем происходит слияние ветки `develop` и `main` с git-тегом, указывающим на новую версию проекта.
## Про Python пакеты проекта.
* Каждый файл `__init__.py` должен содержать в своей первой строке список `__all__ = [...]` с перечислением всех элементов, которые могут быть импортированы из этого пакета. То есть если пакет в своем `__init__.py` содержит 2 различные переменные и импорт 1 класса, которые должны быть из него импортированы, то их названия следует указать в `__all__`. Пакет - директория, содерщая в себе другие директории, Python-модули и имеющая файл `__init__.py`.
* После `__all__`, но перед началом импортов всегда должно находится 2 пустых строки. Если дальше идет обычная переменная, то 1 строка, если класс, функция или что-то ещё, то тоже 2 строки.
* В пакете не следует импортировать абсолютно все переменные из его подпакетов, только то, что действительно может потребоваться за пределами этого основного пакета. Так, пакет `middlewares` в своем `__init__.py` будет содержать только импорт функции для присоединения мидлвари к диспетчеру бота, с последующим указанием названия этой функции в `__all__`, вся остальная логика, зависимости и реализации мидлвари могут быть скрыты в других файлах пакета, или находится внутри его подпакетов, если в них нет необходимости для использования за рамками этого пакета.
* Если вашему пакету требуются вспомогательные функции, то их можно указать в модуле `utils.py` и импортировать оттуда.
* Внутри директории `src/` содержатся папки для всех основных компонентов проекта, его основных пакетов. Внутри них могут быть как вспомогательные пакеты, так и простые папки, так и простые модули.
* Относительные пути следует использовать только в случае, если мы имеем хотим импортировать в пакет его содержимое. В остальном случае требуется использовать полный путь, который начинается с объявления основного пакета. Например `from bot.handlers import connect_routers`.
## Про инструменты.
* Для запуска проекта требуется использовать пакетный менеджер `uv`. Для начала загрузите все зависимости проекта командой `uv sync --dev --locked`.
* Для запуска проекта используйте `uv run src/main.py`, вы также можете запускать скрипты проекта с помощью команды `uv run --script scripts/<название-скрипта>.py`.
* Из-за указания флага `--dev` при использовании `uv sync`, были загружены зависимости необходимые для разработки. К ним относится `ruff` - Python линтер, который проверяет основные ошибки при написании кода с помощью команды `ruff check`. А также `pyrefly` - type-checker, который проверяет, учитывают ли ваши сценарии для работы с кодом то, что переменная может иметь разные типы данных, в зависимости от ситуации. Так `CallbackQuery` не всегда имеет атрибут `message`. Проверка осуществляется с помощью `pyrefly check`.
## Про написание кода.
* Все основные правила написания кода заложены в настройки `ruff`, `pyrefly`.
* Длина строки не больше 70 символов.
* Названия переменных, классов, функций должны быть понятными, короткими. Всё по PEP8.
* Код должен быть понятным и лаконичным, заглушки для `ruff` указываются только в случае острой/временной необходимости, или если его замечания не соответствуют действительности. Перед ними всегда должен стоять объясняющий комментарий с тегом `# DEBUG: ...`
* Костыли, hard-code, заглушки должны содержать комментарий с тегом `# FIXME: ...`
* Всегда указывайте для всех функций, какой тип они возвращают и какие типы параметров принимают.
* Логируйте важные события, делайте лог ошибок, старайтесь не допускать дыр в поведении программы. Логирование совершается с помощью библиотеки `loguru`. Импорт логера следует делать так: `from loguru import logger as loguru_logger`. Никаких `print()`, только логирование.
## Про структуру проекта.
```
urfu-daddy/
├── .gitignore # Список файлов для игнорирования гитом.
├── flake.nix # Файл для настроек окружения NixOS.
├── flake.lock # Закрепление версий зависимостей.
├── docker/ # Контейнеризация и создание Docker образа.
├── .dockerignore # Игнорирование файлов проекта для Docker.
├── logs/ # Папка для хранения логов.
├── scripts/ # Полезные скрипты для проекта.
│ ├── pybabel.py # Работа с локализацией.
│ ├── build.sh # Сборка образа бота.
│ └── deploy.sh # Настройка и запуск Urfu Daddy через Docker Compose.
├── src/ # Основные ресурсы проекта.
│ ├── main.py # Запуск всех компонентов.
│ ├── bot/ # Бот для Telegram.
│ │ ├── __init__.py # Функция для запуска бота.
│ │ ├── handlers/ # Обработка всех ивентов.
│ │ │ ├── callbacks/ # Обработка запросов.
│ │ │ └── commands/ # Обработка комманд.
│ │ ├── middlewares/ # Мидлвари для диспетчера/роутеров.
│ │ ├── services/ # Взаимодействие с другими сервисами бота.
│ │ └── utils/ # Вспомогательные компоненты для для бота.
│ ├── config/ # Получение env-настроек, настройка логирования.
│ ├── database/ # Инициализация и настройка БД.
│ └── locales/ # Папка с локализацией проекта.
├── LICENSE # Лицензия проекта.
├── README.md # Описание проекта.
├── CONTRIBUTE.md # Этот файл.
├── pyproject.toml # Настройки инструментов для разработки.
├── .python-version # Закрепление версии Python для проекта.
└── uv.lock # Закрепление версий зависимостей проекта.
```
* В директориях `commands` и `callbacks` для создания новых хендлеров, требуется только создание нового файла (или изменение текущего) с привязкой декоратора RouterRegistry.register к функции хендлера. Подробный пример смотрите в docstring декоратора. Подключение к роутеру и последующая привязка к диспетчеру Aiogram происходит автоматически. Если вы хотите объединить несколько Python-модулей в одну папку, то просто создайте её и переместите модули туда. Файл `__init__.py` создавать не требуется, он будет проигнорирован при импортировании настроек RouterRegistry для привязки к роутеру!
## Про настройки для проекта (env-настройки, config).
* В корне проекта должен находится файл `.env`.
* В нем должны быть объявлены обязательные переменные (`bot_token`), а также опциональные переменные, если такие требуются.
* Список всех обязательный переменных и опциональных переменных с их значениями можно найти в `src/config/utils`, класс `Settings`.
## Про коммиты, PR, документацию.
* Если вы предлагаете PR, то пишите краткое, но полное описание изменений (если вы обсудили их с командой) или развернутое описание (в ином случае).
* Коммиты пишутся на английском языке и соответствуют [соглашению о коммитах](https://www.conventionalcommits.org/ru/v1.0.0/).
* Докстинги на английском языке и соответствуют общепринятому соглашению (расширения для VSCode - python docstrings).
## Небольшие уточнения.
* Игнорируйте замечания `pyrefly` на то, что для `config: Settings` не объявлена обязательная переменная, он не понимает, что они получаются из `.env` файла.
## И самое главное.
* Делайте хорошо.
* Плохо не делайте.