From 988af9bd27d34b8c94da7773d24808dc750c52cf Mon Sep 17 00:00:00 2001 From: geekiot Date: Sat, 25 Oct 2025 18:07:07 +0500 Subject: [PATCH] Add CONTRIBUTE.md --- CONTRIBUTE.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CONTRIBUTE.md diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 0000000..5b33d36 --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,128 @@ +# Инструкция по внесению изменений в проект. + +## Введение. + +Этот файл содержит подробное описание принципов, которые необходимо соблюдать при участии в разработке данного проекта. + +Все изменения исходного кода требуется совершать в тематических ветках, некоторые из них уже могут быть в проекте, например, `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 # Работа с локализацией. +├── src/ # Основные ресурсы проекта. +│ ├── main.py # Запуск всех компонентов. +│ ├── bot/ # Бот для Telegram. +│ │ ├── __init__.py # Функция для запуска бота. +│ │ ├── handlers/ # Обработка всех ивентов. +│ │ │ ├── callbacks/ # Обработка запросов. +│ │ │ ├── commands/ # Обработка комманд. +│ │ │ ├── utils/ # Вспомогательные компоненты для хендлеров. +│ │ ├── middlewares/ # Мидлвари для диспетчера. +│ │ └── services/ # Взаимодействие с другими сервисами бота. +│ ├── config/ # Получение env-настроек, настройка логирования. +│ ├── database/ # Инициализация и настройка БД. +│ ├── locales/ # Папка с локализацией проекта. +│ └── redis_client/ # Настройка redis-клиента. +├── 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` файла. + +--- + +## И самое главное. +* Делайте хорошо. +* Плохо не делайте.