- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
3.8 KiB
Code Quality Scanner
This module provides repository-aware rules that validate architectural conventions. It currently ships with the following rules:
StringableImplementation: classes that define__toString()must implementStringableFinalClass: value-object classes must be declaredfinalReadonlyClass: value-object classes must be declaredreadonlyReadonlyGetter: readonly properties (or classes) should be exposed directly; avoidget*()wrappersNoInheritance: inheritance is forbidden (except for a small allow list, e.g. Exceptions)
Command Line Usage
Run the scanner from the project root:
php console.php quality:scan # scans src/ by default
php console.php quality:scan app/path # scan a custom directory
php console.php quality:scan --skip-errors # skip classes/files that cannot be parsed
The command groups violations by rule and shows file locations:
❌ Found 2 violation(s). Scanned 185 files, 174 classes in 6.91s
StringableImplementation (2)
• App\Domain\User\ValueObjects\UserId
↳ src/Domain/User/ValueObjects/UserId.php:42
Classes defining __toString() must implement Stringable explicitly.
The exit code is 0 when all checks pass, or 1 when violations are found. You can wire this command into CI to block regressions.
Skipping Faulty Classes
Some parts of the repository (legacy examples, experimental prototypes, etc.) may not load because they contain invalid PHP constructs or depend on unavailable interfaces. Use the --skip-errors flag to collect a warning and continue scanning the remaining classes:
php console.php quality:scan --skip-errors
When the flag is omitted, any parsing/reflection error stops the scan and the command exits with a non-zero status.
Adding New Rules
Rules implement App\Framework\Quality\CodeQuality\CodeQualityRule:
use App\Framework\Quality\CodeQuality\CodeQualityRule;
use App\Framework\Quality\CodeQuality\Results\RuleViolation;
use App\Framework\Quality\CodeQuality\ValueObjects\ClassInspection;
final class MyCustomRule implements CodeQualityRule
{
public function name(): string
{
return 'MyCustomRule';
}
public function check(ClassInspection $inspection): array
{
if ($this->isValid($inspection)) {
return [];
}
$line = $inspection->getMethodLine('someMethod');
return [
RuleViolation::create(
$inspection->className(),
$inspection->filePath(),
$this->name(),
'Explain what must change.',
$line
),
];
}
}
Register the rule inside CodeQualityScanCommand:
$this->scanner = new CodeQualityScanner(
$fileScanner,
$reflectionService,
[
new RequireStringableImplementationRule(),
new MyCustomRule(),
],
$logger
);
Because rules leverage full reflection data and the actual file path, you have the flexibility to enforce namespacing, attribute usage, dependency boundaries, and more.
Storage Permissions
The scanner runs inside the console bootstrap. When Redis is unavailable, the framework falls back to the filesystem cache. The cache directory now resolves to <project-root>/storage/cache, but you still need to make sure it exists and is writable:
mkdir -p storage/cache
chmod -R ug+rw storage
If you run the command from another working directory (e.g. inside Docker), set the base path explicitly so the cache resolver finds the right storage folder:
APP_BASE_PATH=/home/michael/dev/michaelschiemer php console.php quality:scan
The CLI entry point already exports APP_BASE_PATH; keep the environment variable handy for custom runners, background workers, or integration tests.