xandrw / architecture-enforcer
Console command that checks your project's structure against an architecture config
Installs: 27
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 0
Open Issues: 0
pkg:composer/xandrw/architecture-enforcer
Requires
- php: >= 8.1
- symfony/console: ^6.4
- symfony/finder: ^6.4
- symfony/stopwatch: ^6.4
- symfony/yaml: ^6.4
Requires (Dev)
- phpunit/phpunit: ^9.5
README
A command-line tool that recursively scans a given app source directory, analyzes the .php files
for namespace and use statements, and checks them against a defined architecture config.
If a file uses a dependency that is outside the allowed scope for its layer, the command
will display all errors along with their file names and offending line numbers.
Installation
Install the tool as a development dependency using Composer:
composer require --dev xandrw/architecture-enforcer
Or you can install it globally
composer global require xandrw/architecture-enforcer
Configuration
The configuration file defines your application's layers and their allowed dependencies.
Example: Clean Architecture
// project-root/config/architecture.php <?php return [ // 'projectRootNamespace' is required, used when scanning for namespace:directory 'projectRootNamespace' => 'App', // 'architecture' is required, it contains the layers in your application 'architecture' => [ 'App\\Presentation' => [ 'App\\Application', 'App\\Domain', ], 'App\\Infrastructure' => [ 'App\\Application', 'App\\Domain', ], 'App\\Application' => ['App\\Domain'], // A layer key that has itself contained in the child array // will be marked as strict. Any dependency not referenced // in the children array, not part of the current layer or // not a PHP Core member will result in an error // 'App\\Domain' => ['App\\Domain'], 'App\\Domain' => [], ], // 'ignore' is not required, as these paths can be passed with the ignore parameter 'ignore' => ['bin', 'config', 'public', 'tests', 'var', 'vendor'], ];
Or if you prefer yaml:
# project-root/config/architecture.yml/yaml projectRootNamespace: App architecture: App\Presentation: - App\Infrastructure - App\Application - App\Domain App\Infrastructure: - App\Application - App\Domain App\Application: - App\Domain App\Domain: [ ] ignore: - bin - config - public - tests - var - vendor
Or json:
{
"projectRootNamespace": "App",
"architecture": {
"App\\Presentation": [
"App\\Infrastructure",
"App\\Application",
"App\\Domain"
],
"App\\Infrastructure": [
"App\\Application",
"App\\Domain"
],
"App\\Application": [
"App\\Domain"
],
"App\\Domain": []
},
"ignore": [
"bin",
"config",
"public",
"tests",
"var",
"vendor"
]
}
Usage
After you've configured your architecture, let's say your project root is at
/project-root and has a src directory where your application files are located.
./vendor/bin/enforcer validate /project-root/src /project-root/config/architecture.php/yml/yaml
With ignored paths
./vendor/bin/enforcer validate -i Domain/Interfaces,Infrastructure /project-root/src /project-root/config/architecture.php/yml/yaml/json
Command Signature
./vendor/bin/enforcer validate [--ignore/-i] [--no-circular/-c] [--pure/p] [--] <path-to-source> <path-to-config>
Or you can run:
./vendor/bin/enforcer validate -h
Additional Information
- Tests: for more details, refer to the
testsincluded with the project.
Roadmap
-
validatecommand that validates your application files against the config - Execution time and memory used
- Refactor processes to OOP
-
--no-circularoptional parameter forvalidatethat restricts circular dependencies between layers -
--purePure mode, where the defined architecture layers must exist, meaning the directory structure should be there - Separate rendering and validating
-
debugcommand that shows all files, their namespace, the layer they belong to and the used layers/namespaces -
diagramcommand that generates uml diagram of layers and dependencies