Проект «Статистика дрифта». Часть 1. Настройка
Введение
Хэй, всем привет. Мы начинаем небольшой блог по разработке пет-проекта. О чем будет проект? Хороший вопрос…
На данный момент о статистике дрифта. Да, именно о статистике дрифта. Проект, на самом деле, большой, но мы будем делать его по «запчастям», чтобы медленно и уверенно расширять его. Этот подход поможет нам совершенствовать навыки разработки и архитектуры, а также не позволит «утонуть» в потоках мыслей и объемах работ.
Ну хватит с введением, давайте приступать. Первая часть статистики — встречи пилотов. Что? Не-не, не те всякие современные «европейские встречи», а сколько раз и где пилоты соревновались друг с другом. Для чего нам нужна такая статистика? Все очень просто! Когда идет этап, комментаторы часто говорят, что эти пилоты уже ни раз встречались, а их счет встреч N: M. И я вот подумал, а что если просто взять данные, составить их структуру, сделать открытый доступ к данным через красивый визуальный интерфейс? Прикольно же, когда ты можешь в режиме реального времени зайти на сайт, выбрать двух пилотов и посмотреть подробную или краткую статистику их встреч. Ну вот и давайте попробуем это сделать максимально интересно, технологично (тут как выйдет) и практично.
С чего мы начнем? Файловой структуры проекта. Учтите, что в процессе разработки что-то может меняться, а что-то кардинально изменяться. Это норма, так как я не пишу готовую статью, где все уже «вылизано до блеска». Это лайф-тайм блог по проекту.
Файловая структура
Наша файловая структура сейчас не будет привязана ни к какому фреймворку, поскольку мы делаем изолированный проект на «честном слове». Что? Да, я решил пойти по принципу — написать внутренность проекта, а потом натянуть на это что-то готовое из фреймворков. В чем плюс? Пока точно не знаю, но мне нравится писать изолированные вещи, которые работают без привязки к чему-то, а потом страдать с переносом этого на что-то готовое. На самом деле, как показывает практика, такой подход отлично подходит, чтобы «изучить» ядро проекта, а потом «изучить» работу фреймворка на готовом ядре. А еще прикол этого подхода в том, не будет использоваться огромная часть готового решения, так как поймем, что она нам просто не нужна, а глаз мозолит.
Давайте я сразу накидаю всю структуру, а потом ее детально опишу?
- config
- src
- App
- Domain
- Infrastructure
- Shared
- tests
- var
- cache
- reports
- tests
- vendor
В config
будут лежать какие-то конфиги приложения.
В src
будет лежать основной код приложения. Эта папка содержит в себе 3 слоя:
App — команды, события, мапперы, DTO и прочие вещи. По сути — тут лежат файлы «первой точки обращения»;
Domain — доменные сущности, интерфейсы и прочие запчасти сущностей (не путать с моделями базы данных);
Infrastructure — репозитории, работа с базой данных и прочие вещи.
А что за Shared
папка? Да все просто — общие элементы: базовые команды, обертки и прочая «общая» ерундистика.
В tests
— тесты, которые будут разбиты также, как и папки в src
. Ну или почти также.
В var
— отчеты, кэш и прочая служебная история.
В vendor
будут лежать необходимые пакеты для разработки.
Надеюсь, что структуру вы поняли, но про src
я немного дополню приблизительной логикой:
Делается запрос к нашему проекту (будет сделано в самый последний момент).
Что-то, что отвечает за обращения, вызывает из
App
слоя команду.Команда вызывает репозитории для работы с данными что-то обрабатывает и т.д., а в ответ возвращает DTO результата.
Репозиторий стучится в БД, чтобы получить данные.
Маппит «сырые» данные в сущности
Domain
и возвращает их в команду
Как бы все. Это просто и понятно. Хотя, вам может показаться это избыточным, но такая архитектура помогает четко разграничить области ответственности по слоям. Вы точно будете знать, что, где и для чего находится. Ну и что делает, соответственно.
Теперь, давайте поговорим про настройки и необходимые пакеты для старта нашего интересного проекта.
Настройки PHPStorm и composer пакеты
Начнем с простого и очевидного — пакеты composer. На данный момент, я подразумеваю, что мне понадобится вот это:
{
"require-dev": {
"phpunit/phpunit": "^11.0",
"qossmic/deptrac-shim": "^1.0"
},
"require": {
"php-di/php-di": "^7.0"
}
}
Ну как бы тут есть понятно, phpunit
для тестов, php-di
для контейнера зависимостей. А что за deptrac-shim
?
Ой, относительно крутая штука, которая немного контролирует вас в слоях. Помните, я писал про слои: App
, Domain
, Infrastructure
? Так вот, между ними есть «особое» взаимодействие. Точнее, кто что может «дергать». Например, App
слой может использовать все напрямую. Но чаще всего, ему надо работать с Infrastructure
слоем, который может в Domain
слой. Почему App
всемогущий? Потому что ему надо и вызвать штуку по работе с БД, но и передать ей данные в нужном формате (в нашем случае будут ValueObject доменного слоя).
Немного сложно, но это нормально для начала. В процессе все поймете. Если коротко — сильно разделяем слои и их использование между собой. Давайте настроим это дело!
Deptrac
Выполняем команду vendor/bin/deptrac init
, чтобы создать конфигурационный файл deptrac.yaml
. В него вписываем такую конфигурацию:
Код deptrac.yaml
Полный код можно посмотреть в оригинальной статье: Пихта DEV — Проект «Статистика дрифта». Часть 1. Настройка.
Что тут за магия такая происходит? Все очень просто. В начале мы указали, где смотреть (paths
) и что исключить (exclude_files
). Далее указали наши слои и настроили их. Например, вот так мы создали слой App
, который имеет тип проверки directory
и находится в src/App/
:
name: App
collectors:
- type: directory
value: src/App/.*
Потом в секции ruleset
мы просто указали какой слой какие слои может использовать. Как бы все. И по выполнению команды vendor/bin/deptrac analyse
мы будем получать отчет, который покажет нам корректность использования слоев.
Но сам deptrac будет писать cache файл прям в корень проекта. А мне такое не нравится! Понятно, что можно исключить его из git, но я же сделал для этого отдельную папку var/cache
. Проблема в том, что я не нашел как поменять конфигом путь до cache файла. Но, если запустить команду vendor/bin/deptrac analyse --cache-file=var/cache/.deptrac.cache
, то все хорошо. Это не очень удобно, так как мы можем забыть про дополнительные ключи CLI команды. Давайте создадим еще одну новую директорию bin
, в которой будем хранить исполняемые файлы?
И наш первый файл — deptrac.sh
, в котором вот такое простое содержание:
../vendor/bin/deptrac analyse --config-file=../deptrac.yaml --cache-file=../var/cache/.deptrac.cache
Это позволит нам запускать скрипт с корректными для нас настройками, а также расширять его в будущем. Возможно, когда-нибудь можно будет подключить его к сборке проекта (билд), поставить в pre-commit событие git и вообще круто сделать чистую сборку или push.
А теперь, предлагаю настроить phpunit, чтобы также круто запускать тесты, как проверки deptrac.
PHP Unit
Создаем файл в корневой директории phpunit.xml
с очень простым содержимым:
Код phpunit.xml
Полный код можно посмотреть в оригинальной статье: Пихта DEV — Проект «Статистика дрифта». Часть 1. Настройка.
Тут особо нечего рассказывать, кроме того, что в этих секциях: bootstrap="vendor/autoload.php"
, colors="true"
и cacheDirectory="var/cache"
— мы указали загрузчик, включили цвета (для красоты вывода) и указали директорию кэша. В testsuites
указали местоположение наших тестов, а в source
указали местоположение нашего основного кода. А еще я люблю покрытие. Дааа, я тот самый шибанутый, который любит максимальное покрытие кода… Не судите строго, каждый псих по своему. Поэтому, я добавил секцию coverage
по умолчанию и указал 2 формата: html и xml — экспорта в папку var/reports/tests
. Зачем? Html буду смотреть в браузере, там красиво и удобно, а xml может понадобиться нам в будущем для сборки.
Теперь, создайте папку tests
в корне проекта и допишите в composer.json
такую штуку:
{
"autoload": {
"psr-4": {
"tests\\": "tests/"
}
}
}
Это позволит использовать внутри папки tests
namespace tests\*
. А еще это надо прописать в IDE, чтобы не ругался. Идем в File -> Settings -> Directories
, справа есть папка tests
. Нажимаем на карандаш и пишем tests\
. Сохраняемся и выходим. Теперь, нажимаем по нашей папке tests
правой кнопкой и выбираем Mark Directory as -> Test Source Root
. Теперь она светится зеленым цветом и нам хорошо. А да, раз уж про директории зашла речь, то по известному алгоритму пометьте src
как Source Root
, а папки var
и vendor
как Excluded
. Вот теперь супер все настроено.
Ну и напоследок создайте .gitignore
файл, в котором напишите:
vendor
.idea
var
test.php
Что мы тут сделали? Мы объяснили нашему git репозиторию, что нам не надо заносить под контроль версий папки vendor
, var
и .idea
, а также файл test.php
. Так, стоп! А что за файл test.php
? А это, ребята, стандарт одного из видов крутого атомарного тестирования! Шучу, просто иногда надо что-то быстро запустить проверить и проще писать в test.php
файле вызовы, чем строчить тест или идти на какой-нибудь онлайн ресурс.