Skip to content

Commit 3fa30b0

Browse files
authored
Merge pull request #1 from memio/chore/modernize-dev-stack
Prepare v3.0.2
2 parents b01a936 + bbd282d commit 3fa30b0

15 files changed

Lines changed: 375 additions & 37 deletions

File tree

.github/workflows/ci.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
qa:
11+
name: QA (PHP ${{ matrix.php }})
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
matrix:
16+
php: ['8.0']
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Setup PHP
23+
uses: shivammathur/setup-php@v2
24+
with:
25+
php-version: ${{ matrix.php }}
26+
extensions: mbstring
27+
coverage: none
28+
29+
- name: Get Composer cache directory
30+
id: composer-cache
31+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
32+
33+
- name: Cache Composer dependencies
34+
uses: actions/cache@v4
35+
with:
36+
path: ${{ steps.composer-cache.outputs.dir }}
37+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
38+
restore-keys: ${{ runner.os }}-composer-
39+
40+
- name: Install dependencies
41+
run: composer install --prefer-dist --no-progress --optimize-autoloader
42+
43+
- name: Check coding standards
44+
run: vendor/bin/php-cs-fixer fix --dry-run --verbose
45+
46+
- name: Run PHPStan
47+
run: vendor/bin/phpstan analyze --memory-limit=256M
48+
49+
- name: Run Rector
50+
run: vendor/bin/rector process --dry-run
51+
52+
- name: Run phpspec
53+
run: vendor/bin/phpspec --no-interaction run

.gitignore

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
# Third party
2-
/composer.lock
3-
/phpunit.xml
4-
/vendor
5-
/.couscous
6-
/.php_cs.cache
1+
# composer
2+
composer.lock
3+
vendor/
4+
5+
# friendsofphp/php-cs-fixer
6+
.php_cs.cache
7+
.php-cs-fixer.php
8+
.php-cs-fixer.cache
9+
10+
# phpstan
11+
phpstan.neon
12+
13+
# phpunit
14+
phpunit.xml
15+
.phpunit.result.cache

.php-cs-fixer.dist.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/**
4+
* PHP CS Fixer documentation:
5+
* - Homepage: https://cs.symfony.com/
6+
* - List of all available rules: https://cs.symfony.com/doc/rules/index.html
7+
* - List of all available rule sets: https://cs.symfony.com/doc/ruleSets/index.html
8+
* - Find / Compare / See History rules: https://mlocati.github.io/php-cs-fixer-configurator
9+
*
10+
* To inspect a specific rule (e.g. `blank_line_before_statement`), run:
11+
*
12+
* ```console
13+
* > php-cs-fixer describe blank_line_before_statement
14+
* ```
15+
*
16+
* ------------------------------------------------------------------------------
17+
*
18+
* `new \PhpCsFixer\Finder()` is equivalent to:
19+
*
20+
* ```php
21+
* \Symfony\Component\Finder\Finder::create()
22+
* ->files()
23+
* ->name('/\.php$/')
24+
* ->exclude('vendor')
25+
* ->ignoreVCSIgnored(true) // Follow rules establish in .gitignore
26+
* ->ignoreDotFiles(false) // Do not ignore files starting with `.`, like `.php-cs-fixer-dist.php`
27+
* ;
28+
* ```
29+
*/
30+
31+
$finder = (new PhpCsFixer\Finder())
32+
->in(__DIR__)
33+
;
34+
35+
return (new PhpCsFixer\Config())
36+
->setRules([
37+
'@Symfony' => true,
38+
39+
// [Symfony] defaults to `camelCase`, we set it to `snake_case` (phpspec style)
40+
'php_unit_method_casing' => ['case' => 'snake_case'],
41+
42+
// [Symfony] defaults to `true`, we set it to `false` for phpspec
43+
'visibility_required' => false,
44+
])
45+
->setUsingCache(true)
46+
->setFinder($finder)
47+
;

.php_cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

CONTRIBUTING.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,29 @@ changes, improvements or alternatives may be given).
1212

1313
Here's some tips to make you the best contributor ever:
1414

15+
* [Getting started](#getting-started)
1516
* [Standard code](#standard-code)
1617
* [Specifications](#specifications)
18+
* [Full QA check](#full-qa-check)
1719
* [Keeping your fork up-to-date](#keeping-your-fork-up-to-date)
1820

21+
## Getting started
22+
23+
First, set up your local environment:
24+
25+
```console
26+
make lib-init
27+
```
28+
29+
> **Note**: Run `make` or `make help` to see all available commands.
30+
1931
## Standard code
2032

2133
Use [PHP CS fixer](http://cs.sensiolabs.org/) to make your code compliant with
2234
Memio's coding standards:
2335

2436
```console
25-
$ ./vendor/bin/php-cs-fixer fix .
37+
make cs-fix
2638
```
2739

2840
## Specifications
@@ -32,35 +44,43 @@ Memio drives its development using [phpspec](http://www.phpspec.net/).
3244
First bootstrap the code for the Specification:
3345

3446
```console
35-
$ phpspec describe 'Memio\Validator\MyNewUseCase'
47+
make phpspec arg="describe 'Memio\Validator\MyNewClass'"
3648
```
3749

3850
Next, write the actual code of the Specification:
3951

4052
```console
41-
$ $EDITOR spec/Memio/Validator/MyNewUseCase.php
53+
$EDITOR spec/Memio/Validator/MyNewClassSpec.php
4254
```
4355

44-
Then bootstrap the code for the corresponding Use Case:
56+
Then bootstrap the code for the corresponding class:
4557

4658
```console
47-
$ phpspec run
59+
make phpspec
4860
```
4961

50-
Follow that by writing the actual code of the Use Case:
62+
Follow that by writing the actual code of the class:
5163

5264
```console
53-
$ $EDITOR src/Memio/Validator/MyNewUseCase.php
65+
$EDITOR src/Memio/Validator/MyNewClass.php
5466
```
5567

5668
Finally run the specification:
5769

5870
```console
59-
$ phpspec run
71+
make phpspec
6072
```
6173

6274
Results should be green!
6375

76+
## Full QA check
77+
78+
Before submitting your pull request, run the full QA pipeline:
79+
80+
```console
81+
make lib-qa
82+
```
83+
6484
## Keeping your fork up-to-date
6585

6686
To keep your fork up-to-date, you should track the upstream (original) one

Dockerfile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# syntax=docker/dockerfile:1
2+
3+
###
4+
# PHP Dev Container
5+
# Utility Tools: PHP, bash, Composer
6+
###
7+
FROM php:8.0-cli AS php_dev_container
8+
9+
# Composer environment variables:
10+
# * default user is superuser (root), so allow them
11+
# * put cache directory in a readable/writable location
12+
# _Note_: When running `composer` in container, use `--no-cache` option
13+
ENV COMPOSER_ALLOW_SUPERUSER=1 \
14+
COMPOSER_CACHE_DIR=/tmp/.composer/cache
15+
16+
# Update apt sources to use archived Debian repositories
17+
RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list \
18+
&& sed -i '/debian-security/d' /etc/apt/sources.list \
19+
&& sed -i '/stretch-updates/d' /etc/apt/sources.list
20+
21+
# Install dependencies:
22+
# * git: for composer to download packages from source
23+
# * libzip-dev: for composer packages that use ZIP archives
24+
# * unzip: for composer to extract packages
25+
# _Note (Hadolint)_: No version locking for dev container
26+
# hadolint ignore=DL3008
27+
RUN apt-get update && apt-get install -y --no-install-recommends \
28+
git \
29+
libzip-dev \
30+
unzip \
31+
&& rm -rf /var/lib/apt/lists/*
32+
33+
# Copy Composer binary from composer image
34+
# _Note (Hadolint)_: False positive as `COPY` works with images too
35+
# See: https://github.com/hadolint/hadolint/issues/197#issuecomment-1016595425
36+
# hadolint ignore=DL3022
37+
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
38+
39+
WORKDIR /app

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2015-2024 Loïc Faugeron
1+
Copyright (c) 2015-2026 Loïc Faugeron
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

Makefile

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Parameters (optional)
2+
# * `arg`: arbitrary arguments to pass to rules (default: none)
3+
arg ?=
4+
5+
# Docker containers
6+
LIB_SERVICE = memio-validator
7+
8+
# Executables
9+
COMPOSER = docker exec $(LIB_SERVICE) composer
10+
PHP_CS_FIXER = docker exec $(LIB_SERVICE) php vendor/bin/php-cs-fixer
11+
PHPSPEC = docker exec $(LIB_SERVICE) php vendor/bin/phpspec
12+
PHPSTAN = docker exec $(LIB_SERVICE) php vendor/bin/phpstan --memory-limit=256M
13+
RECTOR = docker exec $(LIB_SERVICE) php vendor/bin/rector
14+
SWISS_KNIFE = docker exec $(LIB_SERVICE) php vendor/bin/swiss-knife
15+
16+
# Misc
17+
.DEFAULT_GOAL = help
18+
.PHONY: *
19+
20+
## —— 🔭 The Super Secret Makefile ——————————————————————————————————————————————
21+
## Based on https://github.com/dunglas/symfony-docker
22+
## (arg) denotes the possibility to pass "arg=" parameter to the target
23+
## this allows to add command and options, example: make composer arg='dump --optimize'
24+
help: ## Outputs this help screen
25+
@grep -E '(^[a-zA-Z0-9\./_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) \
26+
| awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' \
27+
| sed -e 's/\[32m##/[33m/'
28+
29+
## —— Docker 🐳 ————————————————————————————————————————————————————————————————
30+
docker: ## Runs Docker (arg, eg `arg='ps'`)
31+
@docker $(arg)
32+
33+
docker-init: ## Builds the Docker image and starts the container in detached mode
34+
@docker build --platform linux/amd64 --pull -t $(LIB_SERVICE) .
35+
@docker run -d --platform linux/amd64 --name $(LIB_SERVICE) -v .:/app $(LIB_SERVICE) tail -f /dev/null
36+
37+
docker-down: ## Stops and removes the container
38+
@docker rm -f $(LIB_SERVICE) 2>/dev/null || true
39+
40+
docker-bash: ## Opens a (bash) shell in the container
41+
@docker exec -it $(LIB_SERVICE) bash
42+
43+
## —— PHP 🐘 ———————————————————————————————————————————————————————————————————
44+
composer: ## Runs Composer (arg, eg `arg='outdated'`)
45+
@$(COMPOSER) $(arg)
46+
47+
composer-install: ## Install dependencies (arg, eg `arg='--no-dev'`)
48+
@$(COMPOSER) install --optimize-autoloader $(arg)
49+
50+
composer-update: ## Updates dependencies (arg, eg `arg='--no-dev'`)
51+
@$(COMPOSER) update --optimize-autoloader $(arg)
52+
53+
composer-dump: ## Dumps autoloader (arg, eg `arg='--classmap-authoritative'`)
54+
@$(COMPOSER) dump-autoload --optimize --strict-psr --strict-ambiguous $(arg)
55+
56+
cs-check: ## Checks CS with PHP-CS-Fixer (arg, eg `arg='../monolith/web'`)
57+
@$(PHP_CS_FIXER) fix --dry-run --verbose $(arg)
58+
59+
cs-fix: ## Fixes CS with Swiss Knife and PHP-CS-Fixer
60+
@$(SWISS_KNIFE) namespace-to-psr-4 spec/Memio/Validator --namespace-root 'spec\\Memio\\Validator\\'
61+
@$(SWISS_KNIFE) namespace-to-psr-4 src/Memio/Validator --namespace-root 'Memio\\Validator\\'
62+
@$(PHP_CS_FIXER) fix --verbose $(arg)
63+
64+
phpstan: ## Static Analysis with PHPStan (arg, eg `arg='--level=6'`)
65+
@$(PHPSTAN) analyze $(arg)
66+
67+
swiss-knife: ## Automated refactorings with Swiss Knife (arg, eg `arg='namespace-to-psr-4 src --namespace-root \'App\\\''`)
68+
@$(SWISS_KNIFE) $(arg)
69+
70+
phpspec: ## Runs the specifications with phpspec (arg, eg `arg='--format=dot'`)
71+
@$(PHPSPEC) --no-interaction run $(arg)
72+
73+
rector-fix: ## Automated refactorings with Rector (arg, eg `arg='--clear-cache'`)
74+
@$(RECTOR) $(arg)
75+
76+
rector-check: ## Refactoring checks with Rector
77+
@$(RECTOR) process --dry-run
78+
79+
## —— Lib 📚 ———————————————————————————————————————————————————————————————————
80+
lib-init: ## First install / resetting (Docker build, up, etc)
81+
@echo ''
82+
@echo ' // Installing git hooks...'
83+
@git config core.hooksPath bin/hooks
84+
@echo ''
85+
@echo ' // Stopping lib docker services...'
86+
@$(MAKE) docker-down
87+
@echo ''
88+
@echo ' // Starting lib docker services...'
89+
@$(MAKE) docker-init
90+
@echo ''
91+
@echo ' [OK] Lib initialized'
92+
93+
lib-qa: ## Runs full QA pipeline (composer-dump, cs-check, phpstan, rector-check, phpspec)
94+
@echo ''
95+
@echo ' // Running composer dump...'
96+
@$(MAKE) composer-dump
97+
@echo ''
98+
@echo ' // Running PHP CS Fixer...'
99+
@$(MAKE) cs-check
100+
@echo ''
101+
@echo ' // Running PHPStan...'
102+
@$(MAKE) phpstan
103+
@echo ''
104+
@echo ' // Running Rector...'
105+
@$(MAKE) rector-check
106+
@echo ''
107+
@echo ' // Running phpspec...'
108+
@$(MAKE) phpspec
109+
@echo ''
110+
@echo ' [OK] QA done'

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,12 @@ Memio uses [phpspec](http://phpspec.net/), which means the tests also provide th
9595
Not convinced? Then clone this repository and run the following commands:
9696

9797
```console
98-
$ composer install -o
99-
$ ./vendor/bin/phpspec run -n -f pretty
98+
make lib-init # Set up Docker environment
99+
make phpspec arg='--format pretty' # Run the specifications
100100
```
101101

102+
> **Note**: Run `make` or `make help` to see all available commands.
103+
102104
You can see the current and past versions using one of the following:
103105

104106
* the `git tag` command

0 commit comments

Comments
 (0)