Mars Rover, Initialization 22/06/2016
In this series we're going to build the software of a Mars Rover, according to the following specifications. It will allow us to practice the followings:
- Monolithic Repositories (MonoRepo)
- Command / Query Responsibility Segregation (CQRS)
- Event Sourcing (ES)
- Test Driven Development (TDD)
But first, we need to initialize our project.
Creating the repository
Let's start by creating a new git repository:
mkdir rover
cd rover
git init
Since we're going to use Composer, we can create
a composer.json
file:
{
"name": "mars-rover/mars-rover",
"license": "MIT",
"type": "project",
"description": "Mars Rover",
"require": {
"php": "^7.0"
}
}
We're then going to ignore some third party library related stuff by
creating .gitignore
:
# Third Party libraries
/vendor/
With this we've finished creating our repository. We can run composer:
composer install --optimize-autoloader
That should be enough for a first commit:
git add composer.json .gitignore
git commit -m '0: Created project'
Creating the navigation
package
By having a look at the use cases, we can see that there's going to be "write-only" dedicated ones and "read-only" dedicated ones:
- Landing a Rover on Mars: is write only
- Driving a Rover: is write only
- Requesting the Rover's location: is read only
Since we'd like to follow the CQRS principle, we'll put the "write-only"
logic in a different package than the "read-only" logic. Landing and Driving
is all about navigation, so we'll create a navigation
package:
git checkout -b 1-navigation
mkdir -p packages/navigation
cd packages/navigation
Composer needs us to set up the package by creating a composer.json
file:
{
"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"
}
}
We've decided to use phpspec as a test framework, and
to get the most of it we'd like to use its SpecGen
extension. To do so we need to create the phpspec.yml.dist
file:
extensions:
Memio\SpecGen\MemioSpecGenExtension: ~
Note: For more information about phpspec see this article.
Finally, we can configure this package's git by creating a .gitignore
file:
# Configuration
/phpspec.yml
# Third Party libraries
/vendor/
/composer.lock
With this we've finished creating our package. We can run Composer:
composer install --optimize-autoloader
That should be enough for a second commit:
git add -A
git commit -m '1: Created Navigation package'
Adding navigation
to the project
Let's go back to the project's root:
cd ../../
One benefit of MonoRepos is to be able to run all packages tests in one
command. To do so, we need to require navigation
in our project's
composer.json
file:
{
"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"
}
}
By default, Composer looks for packages only in Packagist.
By adding the new repositories
section we can tell it to also check locally
in ./packages
, allowing us to add them in the require
section.
Composer needs us to tell it what version of the package we'd like, but in
MonoRepos all packages share the same version, so we simply use *
(any).
But to be able to use the latest changes, and not only the tagged one, we
have to specify the development stability (@dev
).
Since we've decided to use phpspec for our test, we're also going to need to require it in the project's development dependencies:
composer require --dev phpspec/phpspec:^3.0
By default phpspec is going to look for test in the project's root. We need to
create a phpspec.yml.dist
file to tell it to use navigation
's ones:
suites:
navigation:
namespace: 'MarsRover\Navigation'
src_path: packages/navigation/src
spec_path: packages/navigation
We'll also update .gitignore
to ignore local configuration:
# Configuration
/phpspec.yml
# Third Party libraries
/vendor/
And that's it! We are now able to run Composer and then phpspec:
composer update --optimize-autoloader
./vendor/bin/phpspec run
That should be enough for a last commit:
git add -A
git commit -m '1: Added navigation package to main project'
Let's merge it to master:
git checkout master
git merge --no-ff 1-navigation
Conclusion
With Composer we can create many packages inside a single repository. With this MonoRepo, we can then execute all the tests in one command.
What's next
In the next article we'll tackle down the "Landing a Rover on Mars" use case, allowing us to showcase an example of Event Sourcing and TDD.