Проект «Статистика дрифта». Часть 1. Настройка

8964aedb382a23f58d9313a7f3530c8d.jpg

Введение

Хэй, всем привет. Мы начинаем небольшой блог по разработке пет-проекта. О чем будет проект? Хороший вопрос…
На данный момент о статистике дрифта. Да, именно о статистике дрифта. Проект, на самом деле, большой, но мы будем делать его по «запчастям», чтобы медленно и уверенно расширять его. Этот подход поможет нам совершенствовать навыки разработки и архитектуры, а также не позволит «утонуть» в потоках мыслей и объемах работ.

Ну хватит с введением, давайте приступать. Первая часть статистики — встречи пилотов. Что? Не-не, не те всякие современные «европейские встречи», а сколько раз и где пилоты соревновались друг с другом. Для чего нам нужна такая статистика? Все очень просто! Когда идет этап, комментаторы часто говорят, что эти пилоты уже ни раз встречались, а их счет встреч 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 я немного дополню приблизительной логикой:

  1. Делается запрос к нашему проекту (будет сделано в самый последний момент).

  2. Что-то, что отвечает за обращения, вызывает из App слоя команду.

  3. Команда вызывает репозитории для работы с данными что-то обрабатывает и т.д., а в ответ возвращает DTO результата.

    1. Репозиторий стучится в БД, чтобы получить данные.

    2. Маппит «сырые» данные в сущности 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
файле вызовы, чем строчить тест или идти на какой-нибудь онлайн ресурс.

© Habrahabr.ru