15 - Introduce Deptrac for lightweight architecture enforcement
All checks were successful
CI / ci (push) Successful in 9m11s

This commit is contained in:
myrmidex 2026-06-10 16:51:13 +00:00
parent f3c06363db
commit e6ab5ccbb6
6 changed files with 398 additions and 2 deletions

View file

@ -63,6 +63,9 @@ jobs:
- name: Static analysis - name: Static analysis
run: vendor/bin/phpstan analyse --memory-limit=1G -c phpstan.dist.neon run: vendor/bin/phpstan analyse --memory-limit=1G -c phpstan.dist.neon
- name: Architecture (Deptrac)
run: vendor/bin/deptrac analyse --no-interaction
- name: Create and migrate test database - name: Create and migrate test database
env: env:
DATABASE_URL: postgresql://app:!ChangeMe!@postgres:5432/app?serverVersion=16&charset=utf8 DATABASE_URL: postgresql://app:!ChangeMe!@postgres:5432/app?serverVersion=16&charset=utf8

2
.gitignore vendored
View file

@ -25,3 +25,5 @@
phpstan.* phpstan.*
!phpstan.dist.neon !phpstan.dist.neon
###< phpstan/phpstan ### ###< phpstan/phpstan ###
.deptrac.cache

View file

@ -92,7 +92,8 @@
"stan": "phpstan analyse --memory-limit=1G", "stan": "phpstan analyse --memory-limit=1G",
"stan-baseline": "phpstan analyse --memory-limit=1G --generate-baseline", "stan-baseline": "phpstan analyse --memory-limit=1G --generate-baseline",
"test": "phpunit", "test": "phpunit",
"cs": "php-cs-fixer fix" "cs": "php-cs-fixer fix",
"deptrac": "deptrac analyse --no-interaction"
}, },
"conflict": { "conflict": {
"symfony/symfony": "*" "symfony/symfony": "*"
@ -105,6 +106,7 @@
}, },
"require-dev": { "require-dev": {
"dama/doctrine-test-bundle": "^8.6", "dama/doctrine-test-bundle": "^8.6",
"deptrac/deptrac": "^4.6",
"phpstan/extension-installer": "^1.4", "phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.2", "phpstan/phpstan": "^2.2",
"phpstan/phpstan-doctrine": "^2.0", "phpstan/phpstan-doctrine": "^2.0",

329
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "b14a697ba14ca17f0a5361d3e5fff5fc", "content-hash": "7f5ff8c2e2a69f08b4522770b961fc80",
"packages": [ "packages": [
{ {
"name": "composer/semver", "name": "composer/semver",
@ -7759,6 +7759,151 @@
} }
], ],
"packages-dev": [ "packages-dev": [
{
"name": "composer/pcre",
"version": "3.3.2",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
"reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<1.11.10"
},
"require-dev": {
"phpstan/phpstan": "^1.12 || ^2",
"phpstan/phpstan-strict-rules": "^1 || ^2",
"phpunit/phpunit": "^8 || ^9"
},
"type": "library",
"extra": {
"phpstan": {
"includes": [
"extension.neon"
]
},
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Pcre\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
"keywords": [
"PCRE",
"preg",
"regex",
"regular expression"
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
"source": "https://github.com/composer/pcre/tree/3.3.2"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2024-11-12T16:29:46+00:00"
},
{
"name": "composer/xdebug-handler",
"version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
"shasum": ""
},
"require": {
"composer/pcre": "^1 || ^2 || ^3",
"php": "^7.2.5 || ^8.0",
"psr/log": "^1 || ^2 || ^3"
},
"require-dev": {
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-strict-rules": "^1.1",
"phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Composer\\XdebugHandler\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "John Stevenson",
"email": "john-stevenson@blueyonder.co.uk"
}
],
"description": "Restarts a process without Xdebug.",
"keywords": [
"Xdebug",
"performance"
],
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/xdebug-handler/issues",
"source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2024-05-06T16:37:16+00:00"
},
{ {
"name": "dama/doctrine-test-bundle", "name": "dama/doctrine-test-bundle",
"version": "v8.6.0", "version": "v8.6.0",
@ -7828,6 +7973,91 @@
}, },
"time": "2026-01-21T07:39:44+00:00" "time": "2026-01-21T07:39:44+00:00"
}, },
{
"name": "deptrac/deptrac",
"version": "4.6.1",
"source": {
"type": "git",
"url": "https://github.com/deptrac/deptrac.git",
"reference": "6ff20dec210f119a4ddebdf8e28603689f34eb67"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/deptrac/deptrac/zipball/6ff20dec210f119a4ddebdf8e28603689f34eb67",
"reference": "6ff20dec210f119a4ddebdf8e28603689f34eb67",
"shasum": ""
},
"require": {
"composer/xdebug-handler": "^3.0",
"jetbrains/phpstorm-stubs": "2024.3 || 2025.3 || 2026.1",
"nikic/php-parser": "^5",
"php": "^8.2",
"phpdocumentor/graphviz": "^2.1",
"phpdocumentor/type-resolver": "^1.9.0 || ^2.0.0",
"phpstan/phpdoc-parser": "^1.5.0 || ^2.1.0",
"phpstan/phpstan": "^2.0",
"psr/container": "^2.0",
"psr/event-dispatcher": "^1.0",
"symfony/config": "^6.4 || ^7.4 || ^8.0",
"symfony/console": "^6.4 || ^7.4 || ^8.0",
"symfony/dependency-injection": "^6.4 || ^7.4 || ^8.0",
"symfony/event-dispatcher": "^6.4 || ^7.4 || ^8.0",
"symfony/event-dispatcher-contracts": "^3.4",
"symfony/filesystem": "^6.4 || ^7.4 || ^8.0",
"symfony/finder": "^6.4 || ^7.4 || ^8.0",
"symfony/yaml": "^6.4 || ^7.4 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8",
"ergebnis/composer-normalize": "^2.45",
"ext-libxml": "*",
"symfony/stopwatch": "^6.4 || ^7.4 || ^8.0"
},
"suggest": {
"ext-dom": "For using the JUnit output formatter"
},
"bin": [
"deptrac"
],
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": false,
"forward-command": true,
"target-directory": "tools"
}
},
"autoload": {
"psr-4": {
"Deptrac\\Deptrac\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Tim Glabisch"
},
{
"name": "Simon Mönch"
},
{
"name": "Denis Brumann"
}
],
"description": "Deptrac is a static code analysis tool that helps to enforce rules for dependencies between software layers.",
"keywords": [
"dev",
"static analysis"
],
"support": {
"issues": "https://github.com/deptrac/deptrac/issues",
"source": "https://github.com/deptrac/deptrac/tree/4.6.1"
},
"time": "2026-05-13T08:23:06+00:00"
},
{ {
"name": "fakerphp/faker", "name": "fakerphp/faker",
"version": "v1.24.1", "version": "v1.24.1",
@ -7891,6 +8121,50 @@
}, },
"time": "2024-11-21T13:46:39+00:00" "time": "2024-11-21T13:46:39+00:00"
}, },
{
"name": "jetbrains/phpstorm-stubs",
"version": "v2026.1",
"source": {
"type": "git",
"url": "https://github.com/JetBrains/phpstorm-stubs",
"reference": "2cdd054c4109dfb76667c9198bf9427606354243"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/2cdd054c4109dfb76667c9198bf9427606354243",
"reference": "2cdd054c4109dfb76667c9198bf9427606354243",
"shasum": ""
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^v3.86",
"nikic/php-parser": "^v5.6",
"phpdocumentor/reflection-docblock": "^5.6",
"phpunit/phpunit": "^12.3"
},
"type": "library",
"autoload": {
"files": [
"PhpStormStubsMap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"description": "PHP runtime & extensions header files for PhpStorm",
"homepage": "https://www.jetbrains.com/phpstorm",
"keywords": [
"autocomplete",
"code",
"inference",
"inspection",
"jetbrains",
"phpstorm",
"stubs",
"type"
],
"time": "2026-02-19T20:12:01+00:00"
},
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
"version": "1.13.4", "version": "1.13.4",
@ -8127,6 +8401,59 @@
}, },
"time": "2022-02-21T01:04:05+00:00" "time": "2022-02-21T01:04:05+00:00"
}, },
{
"name": "phpdocumentor/graphviz",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/GraphViz.git",
"reference": "115999dc7f31f2392645aa825a94a6b165e1cedf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/GraphViz/zipball/115999dc7f31f2392645aa825a94a6b165e1cedf",
"reference": "115999dc7f31f2392645aa825a94a6b165e1cedf",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"ext-simplexml": "*",
"mockery/mockery": "^1.2",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8.2 || ^9.2",
"psalm/phar": "^4.15"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
"phpDocumentor\\GraphViz\\": "src/phpDocumentor/GraphViz",
"phpDocumentor\\GraphViz\\PHPStan\\": "./src/phpDocumentor/PHPStan"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"description": "Wrapper for Graphviz",
"support": {
"issues": "https://github.com/phpDocumentor/GraphViz/issues",
"source": "https://github.com/phpDocumentor/GraphViz/tree/2.1.0"
},
"time": "2021-12-13T19:03:21+00:00"
},
{ {
"name": "phpstan/extension-installer", "name": "phpstan/extension-installer",
"version": "1.4.3", "version": "1.4.3",

59
deptrac.yaml Normal file
View file

@ -0,0 +1,59 @@
# Permissive baseline (#15): codifies the dependency directions observed in the
# current codebase as a starting ruleset. Tighten incrementally as the
# architecture evolves — see ticket #15 for the rationale.
deptrac:
paths:
- ./src
layers:
- name: Controller
collectors:
- type: directory
value: src/Controller/.*
- name: Presenter
collectors:
- type: directory
value: src/Presenter/.*
- name: Repository
collectors:
- type: directory
value: src/Repository/.*
- name: Entity
collectors:
- type: directory
value: src/Entity/.*
- name: Service
collectors:
- type: directory
value: src/Services/.*
- name: Fixtures
collectors:
- type: directory
value: src/Factory/.*
- type: directory
value: src/Story/.*
ruleset:
Controller:
- Entity
- Presenter
- Repository
- Service
Presenter:
- Entity
Repository:
- Entity
Entity:
- Entity
- Repository
# Services currently have no internal App\ dependencies — kept empty
# intentionally to flag the first dependency a Service ever takes on.
Service: ~
Fixtures:
- Entity
- Repository

View file

@ -11,6 +11,9 @@
"config/packages/dama_doctrine_test_bundle.yaml" "config/packages/dama_doctrine_test_bundle.yaml"
] ]
}, },
"deptrac/deptrac": {
"version": "4.6.1"
},
"doctrine/deprecations": { "doctrine/deprecations": {
"version": "1.1", "version": "1.1",
"recipe": { "recipe": {