В этой серии статей мы строим программное обеспечение марсохода в соответствии со следующими спецификациями. Это позволит применить нам на практике следующие подходы:
- Monolithic Repositories — MonoRepo (Монолитные репозитории)
- Command/Query Responsibility Segregation — CQRS (Сегрегация ответственности на чтение и запись)
- Event Sourcing — ES (События как источник)
- Test Driven Development — TDD (Разработка через тестирование)
Оглавление
Cначала нам нужно инициализировать наш проект.
Создание репозитория
Давайте начнем с создания нового git-репозитория:
mkdir rover
cd rover
git init
Поскольку мы собираемся использовать Composer, создадим
composer.json
:{
"name": "mars-rover/mars-rover",
"license": "MIT",
"type": "project",
"description": "Mars Rover",
"require": {
"php": "^7.0"
}
}
Добавим
.gitignore
для игнорирования файлов сторонних библиотек в репозитории:# Third Party libraries
/vendor/
Закончив с созданием репозитория, запустим
composer
:composer install --optimize-autoloader
Этого будет достаточно для первого коммита:
git add composer.json .gitignore
git commit -m '0: Created project'
Создание navigation
-пакета
Посмотрев на декомпозицию задачи, мы увидим, что задачи можно выделить в
write-only
и read-only
:- Посадка ровера на Марс —
write-only
- Вождение ровера —
write-only
- Запрос местоположения —
read-only
Поскольку мы хотим придерживаться принципу CQRS, положим
write-only
логику отдельно от read-only
. Посадка и вождение — это все про навигацию, поэтому начнем с него:git checkout -b 1-navigation
mkdir -p packages/navigation
cd packages/navigation
Создаем
composer.json
для нового пакета:{
"name": "mars-rover/navigation",
"license": "MIT",
"type": "library",
"description": "Mars Rover - Navigation",
"autoload": {
"psr-4": { "MarsRover\\Navigation\\": "src/MarsRover/Navigation" }
},
"require": {
"php": "^7.0"
},
"require-dev": {
"memio/spec-gen": "^0.6"
}
}
В качестве тестовой платформы возьмем phpspec, и для большинства тестов мы будем использовать ее расширение SpecGen. Для этого нужно создать в корне проекта
phpspec.yml.dist
:extensions:
Memio\SpecGen\MemioSpecGenExtension: ~
Примечание: Для получения более подробной информации о phpspec смотрите статью.
Наконец, нам нужно настроить
git
для этого пакета путем создания .gitignore
файла:# Configuration
/phpspec.yml
# Third Party libraries
/vendor/
/composer.lock
На этом мы закончили конфигурирование нашего пакета, и теперь можем запустить
Composer
:composer install --optimize-autoloader
Зафиксируем наши действия во втором коммите:
git add -A
git commit -m '1: Created Navigation package'
Добавление navigation
-пакета в проект
Вернемся к корню проекта:
cd ../../
Одним из преимуществ MonoRepo является возможность выполнять тесты всех пакетов одной командой. Дл этого нам нужно прописать зависимость от
navigation
в composer.json
файле нашего основного проекта:{
"name": "mars-rover/mars-rover",
"license": "MIT",
"type": "project",
"description": "Mars Rover",
"repositories": [
{
"type": "path",
"url": "./packages/*"
}
],
"require": {
"mars-rover/navigation": "*@dev",
"php": "^7.0"
}
}
По-умолчанию
Composer
ищет пакеты только в Packagist. Добавив новую секцию repositories
мы говорим ему проверить наличие пакетов еще и локально в ./packages
, что позволяет нам использовать найденные пакеты в секции require
.Также нам нужно сообщить менеджеру пакетов какую версию мы бы хотели, но в монорепозитории все пакеты имеют одинаковую версию, поэтому мы просто используем
*
(любая). Но чтобы иметь возможность использовать последние изменения, не только с тегами версий, нам необходимо указать предпочитаемую стабильность (@dev
).Ну и раз уж мы используем
phpspec
для наших тестов, поставим дев-зависимость в основном проекте и на него:composer require --dev phpspec/phpspec:^3.0
phpspec
будет искать тесты в корне проекта. Нам нужно создать phpspec.yml.dist
, чтобы сообщить о наличии navigation
-пакета:suites:
navigation:
namespace: 'MarsRover\Navigation'
src_path: packages/navigation/src
spec_path: packages/navigation
Для игнорирования локальной конфигурации также обновим
.gitignore
:# Configuration
/phpspec.yml
# Third Party libraries
/vendor/
Вот оно! Теперь мы можем запустить
Composer
и затем phpspec
:composer update --optimize-autoloader
./vendor/bin/phpspec run
Закоммитим все это:
git add -A
git commit -m '1: Added navigation package to main project'
И смерджимся с мастер-веткой:
git checkout master
git merge --no-ff 1-navigation
Заключение
C
Composer
мы можем создавать много макетов внутри одного репозитория, а применяя подход MonoRepo
— запускать все тесты одной командой.Что дальше
В следующей статье мы займемся внутренней частью задачи “Посадка ровера на Марс”, продемонстрировав пример работы Event Sourcing и TDD.
Предыдущая часть: Марсоход, Введение
Следующая часть: Марсоход, Посадка
Поделиться с друзьями
Fedot
По моему игнорирование composer.lock в конечном коде, самое плохое что можно предложить.
Этот файл фиксирует точные версии всех установленных пакетов, что бы при деплое, и при разработке можно было быть уверенным что новые версии будет соответствовать тем с которыми были выполнялись тесты.
Иначе можно получить ошибки при деплое, так как версия пакета может отличаться от той с которой проводились тесты.
iGusev
В целом да, но в частности — внешних зависимостей, кроме dev, пока ещё нет, а при работе с монорепозиторием зависимость всегда последняя (для внутренних репозиторий).