Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
qa:
name: QA (PHP ${{ matrix.php }})
runs-on: ubuntu-latest

strategy:
matrix:
php: ['8.0']

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring
coverage: none

- name: Get Composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Install dependencies
run: composer install --prefer-dist --no-progress --optimize-autoloader

- name: Check coding standards
run: vendor/bin/php-cs-fixer fix --dry-run --verbose

- name: Run PHPStan
run: vendor/bin/phpstan analyze --memory-limit=256M

- name: Run Rector
run: vendor/bin/rector process --dry-run

- name: Run phpspec
run: vendor/bin/phpspec --no-interaction run
21 changes: 15 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Third party
/composer.lock
/phpunit.xml
/vendor
/.couscous
/.php_cs.cache
# composer
composer.lock
vendor/

# friendsofphp/php-cs-fixer
.php_cs.cache
.php-cs-fixer.php
.php-cs-fixer.cache

# phpstan
phpstan.neon

# phpunit
phpunit.xml
.phpunit.result.cache
47 changes: 47 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/**
* PHP CS Fixer documentation:
* - Homepage: https://cs.symfony.com/
* - List of all available rules: https://cs.symfony.com/doc/rules/index.html
* - List of all available rule sets: https://cs.symfony.com/doc/ruleSets/index.html
* - Find / Compare / See History rules: https://mlocati.github.io/php-cs-fixer-configurator
*
* To inspect a specific rule (e.g. `blank_line_before_statement`), run:
*
* ```console
* > php-cs-fixer describe blank_line_before_statement
* ```
*
* ------------------------------------------------------------------------------
*
* `new \PhpCsFixer\Finder()` is equivalent to:
*
* ```php
* \Symfony\Component\Finder\Finder::create()
* ->files()
* ->name('/\.php$/')
* ->exclude('vendor')
* ->ignoreVCSIgnored(true) // Follow rules establish in .gitignore
* ->ignoreDotFiles(false) // Do not ignore files starting with `.`, like `.php-cs-fixer-dist.php`
* ;
* ```
*/

$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
;

return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,

// [Symfony] defaults to `camelCase`, we set it to `snake_case` (phpspec style)
'php_unit_method_casing' => ['case' => 'snake_case'],

// [Symfony] defaults to `true`, we set it to `false` for phpspec
'visibility_required' => false,
])
->setUsingCache(true)
->setFinder($finder)
;
18 changes: 0 additions & 18 deletions .php_cs

This file was deleted.

36 changes: 28 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,29 @@ changes, improvements or alternatives may be given).

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

* [Getting started](#getting-started)
* [Standard code](#standard-code)
* [Specifications](#specifications)
* [Full QA check](#full-qa-check)
* [Keeping your fork up-to-date](#keeping-your-fork-up-to-date)

## Getting started

First, set up your local environment:

```console
make lib-init
```

> **Note**: Run `make` or `make help` to see all available commands.

## Standard code

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

```console
$ ./vendor/bin/php-cs-fixer fix .
make cs-fix
```

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

```console
$ phpspec describe 'Memio\Validator\MyNewUseCase'
make phpspec arg="describe 'Memio\Validator\MyNewClass'"
```

Next, write the actual code of the Specification:

```console
$ $EDITOR spec/Memio/Validator/MyNewUseCase.php
$EDITOR spec/Memio/Validator/MyNewClassSpec.php
```

Then bootstrap the code for the corresponding Use Case:
Then bootstrap the code for the corresponding class:

```console
$ phpspec run
make phpspec
```

Follow that by writing the actual code of the Use Case:
Follow that by writing the actual code of the class:

```console
$ $EDITOR src/Memio/Validator/MyNewUseCase.php
$EDITOR src/Memio/Validator/MyNewClass.php
```

Finally run the specification:

```console
$ phpspec run
make phpspec
```

Results should be green!

## Full QA check

Before submitting your pull request, run the full QA pipeline:

```console
make lib-qa
```

## Keeping your fork up-to-date

To keep your fork up-to-date, you should track the upstream (original) one
Expand Down
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# syntax=docker/dockerfile:1

###
# PHP Dev Container
# Utility Tools: PHP, bash, Composer
###
FROM php:8.0-cli AS php_dev_container

# Composer environment variables:
# * default user is superuser (root), so allow them
# * put cache directory in a readable/writable location
# _Note_: When running `composer` in container, use `--no-cache` option
ENV COMPOSER_ALLOW_SUPERUSER=1 \
COMPOSER_CACHE_DIR=/tmp/.composer/cache

# Update apt sources to use archived Debian repositories
RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list \
&& sed -i '/debian-security/d' /etc/apt/sources.list \
&& sed -i '/stretch-updates/d' /etc/apt/sources.list

# Install dependencies:
# * git: for composer to download packages from source
# * libzip-dev: for composer packages that use ZIP archives
# * unzip: for composer to extract packages
# _Note (Hadolint)_: No version locking for dev container
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
libzip-dev \
unzip \
&& rm -rf /var/lib/apt/lists/*

# Copy Composer binary from composer image
# _Note (Hadolint)_: False positive as `COPY` works with images too
# See: https://github.com/hadolint/hadolint/issues/197#issuecomment-1016595425
# hadolint ignore=DL3022
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2015-2024 Loïc Faugeron
Copyright (c) 2015-2026 Loïc Faugeron

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
110 changes: 110 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Parameters (optional)
# * `arg`: arbitrary arguments to pass to rules (default: none)
arg ?=

# Docker containers
LIB_SERVICE = memio-validator

# Executables
COMPOSER = docker exec $(LIB_SERVICE) composer
PHP_CS_FIXER = docker exec $(LIB_SERVICE) php vendor/bin/php-cs-fixer
PHPSPEC = docker exec $(LIB_SERVICE) php vendor/bin/phpspec
PHPSTAN = docker exec $(LIB_SERVICE) php vendor/bin/phpstan --memory-limit=256M
RECTOR = docker exec $(LIB_SERVICE) php vendor/bin/rector
SWISS_KNIFE = docker exec $(LIB_SERVICE) php vendor/bin/swiss-knife

# Misc
.DEFAULT_GOAL = help
.PHONY: *

## —— 🔭 The Super Secret Makefile ——————————————————————————————————————————————
## Based on https://github.com/dunglas/symfony-docker
## (arg) denotes the possibility to pass "arg=" parameter to the target
## this allows to add command and options, example: make composer arg='dump --optimize'
help: ## Outputs this help screen
@grep -E '(^[a-zA-Z0-9\./_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) \
| awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' \
| sed -e 's/\[32m##/[33m/'

## —— Docker 🐳 ————————————————————————————————————————————————————————————————
docker: ## Runs Docker (arg, eg `arg='ps'`)
@docker $(arg)

docker-init: ## Builds the Docker image and starts the container in detached mode
@docker build --platform linux/amd64 --pull -t $(LIB_SERVICE) .
@docker run -d --platform linux/amd64 --name $(LIB_SERVICE) -v .:/app $(LIB_SERVICE) tail -f /dev/null

docker-down: ## Stops and removes the container
@docker rm -f $(LIB_SERVICE) 2>/dev/null || true

docker-bash: ## Opens a (bash) shell in the container
@docker exec -it $(LIB_SERVICE) bash

## —— PHP 🐘 ———————————————————————————————————————————————————————————————————
composer: ## Runs Composer (arg, eg `arg='outdated'`)
@$(COMPOSER) $(arg)

composer-install: ## Install dependencies (arg, eg `arg='--no-dev'`)
@$(COMPOSER) install --optimize-autoloader $(arg)

composer-update: ## Updates dependencies (arg, eg `arg='--no-dev'`)
@$(COMPOSER) update --optimize-autoloader $(arg)

composer-dump: ## Dumps autoloader (arg, eg `arg='--classmap-authoritative'`)
@$(COMPOSER) dump-autoload --optimize --strict-psr --strict-ambiguous $(arg)

cs-check: ## Checks CS with PHP-CS-Fixer (arg, eg `arg='../monolith/web'`)
@$(PHP_CS_FIXER) fix --dry-run --verbose $(arg)

cs-fix: ## Fixes CS with Swiss Knife and PHP-CS-Fixer
@$(SWISS_KNIFE) namespace-to-psr-4 spec/Memio/Validator --namespace-root 'spec\\Memio\\Validator\\'
@$(SWISS_KNIFE) namespace-to-psr-4 src/Memio/Validator --namespace-root 'Memio\\Validator\\'
@$(PHP_CS_FIXER) fix --verbose $(arg)

phpstan: ## Static Analysis with PHPStan (arg, eg `arg='--level=6'`)
@$(PHPSTAN) analyze $(arg)

swiss-knife: ## Automated refactorings with Swiss Knife (arg, eg `arg='namespace-to-psr-4 src --namespace-root \'App\\\''`)
@$(SWISS_KNIFE) $(arg)

phpspec: ## Runs the specifications with phpspec (arg, eg `arg='--format=dot'`)
@$(PHPSPEC) --no-interaction run $(arg)

rector-fix: ## Automated refactorings with Rector (arg, eg `arg='--clear-cache'`)
@$(RECTOR) $(arg)

rector-check: ## Refactoring checks with Rector
@$(RECTOR) process --dry-run

## —— Lib 📚 ———————————————————————————————————————————————————————————————————
lib-init: ## First install / resetting (Docker build, up, etc)
@echo ''
@echo ' // Installing git hooks...'
@git config core.hooksPath bin/hooks
@echo ''
@echo ' // Stopping lib docker services...'
@$(MAKE) docker-down
@echo ''
@echo ' // Starting lib docker services...'
@$(MAKE) docker-init
@echo ''
@echo ' [OK] Lib initialized'

lib-qa: ## Runs full QA pipeline (composer-dump, cs-check, phpstan, rector-check, phpspec)
@echo ''
@echo ' // Running composer dump...'
@$(MAKE) composer-dump
@echo ''
@echo ' // Running PHP CS Fixer...'
@$(MAKE) cs-check
@echo ''
@echo ' // Running PHPStan...'
@$(MAKE) phpstan
@echo ''
@echo ' // Running Rector...'
@$(MAKE) rector-check
@echo ''
@echo ' // Running phpspec...'
@$(MAKE) phpspec
@echo ''
@echo ' [OK] QA done'
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ Memio uses [phpspec](http://phpspec.net/), which means the tests also provide th
Not convinced? Then clone this repository and run the following commands:

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

> **Note**: Run `make` or `make help` to see all available commands.

You can see the current and past versions using one of the following:

* the `git tag` command
Expand Down
Loading