Loading...
Loading...
Code quality tooling with PHPStan, Pint, and strict types. Use when working with code quality, static analysis, formatting, or when user mentions PHPStan, Pint, quality, static analysis, type safety, code style, linting.
npx skill4agent add leeovery/claude-laravel laravel-quality# composer.json scripts
{
"test": "pest",
"analyse": "phpstan analyse",
"format": "pint",
"quality": [
"@analyse",
"@test"
]
}declare(strict_types=1)tests/Pest.phppest()->extend(Tests\TestCase::class)->in('Feature', 'Unit');tests/Architecture/ActionsTest.php<?php
declare(strict_types=1);
arch('actions are invokable')
->expect('App\Actions')
->toHaveMethod('__invoke');
arch('actions live in Actions namespace')
->expect('App\Actions')
->toBeClasses()
->toOnlyBeUsedIn('App\Actions', 'App\Http', 'App\Jobs', 'App\Listeners');
arch('actions do not use models directly')
->expect('App\Actions')
->not->toUse('Illuminate\Database\Eloquent\Model');tests/Architecture/DataTest.php<?php
declare(strict_types=1);
arch('data objects extend base Data class')
->expect('App\Data')
->toExtend('App\Data\Data')
->ignoring('App\Data\Data');
arch('data objects use constructor property promotion')
->expect('App\Data')
->toHaveConstructor();tests/Architecture/StrictTypesTest.php<?php
declare(strict_types=1);
arch('app files declare strict types')
->expect('App')
->toUseStrictTypes();
arch('test files declare strict types')
->expect('Tests')
->toUseStrictTypes();tests/Architecture/ControllersTest.php<?php
declare(strict_types=1);
arch('controllers do not use DB facade')
->expect('App\Http')
->not->toUse('Illuminate\Support\Facades\DB');
arch('controllers do not use models directly')
->expect('App\Http\Web\Controllers')
->not->toUse('App\Models');tests/Architecture/NamingTest.php<?php
declare(strict_types=1);
arch('actions end with Action suffix')
->expect('App\Actions')
->toHaveSuffix('Action');
arch('data objects end with Data suffix')
->expect('App\Data')
->toHaveSuffix('Data')
->ignoring('App\Data\Data', 'App\Data\Concerns');
arch('exceptions end with Exception suffix')
->expect('App\Exceptions')
->toHaveSuffix('Exception')
->ignoring('App\Exceptions\Concerns');tests/Architecture/ModelsTest.php<?php
declare(strict_types=1);
arch('models use custom query builders')
->expect('App\Models')
->toHaveMethod('newEloquentBuilder');
arch('models do not use local scopes')
->expect('App\Models')
->not->toHaveMethod('scope*');composer require phpstan/phpstan --dev
composer require phpstan/phpstan-strict-rules --dev
composer require larastan/larastan --devphpstan.neonincludes:
- vendor/larastan/larastan/extension.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
parameters:
level: 8
paths:
- app
- tests
excludePaths:
- app/Providers/TelescopeServiceProvider.php
checkMissingIterableValueType: true
checkGenericClassInNonGenericObjectType: true
reportUnmatchedIgnoredErrors: false./vendor/bin/phpstan analysecomposer require laravel/pint --devpint.json{
"preset": "laravel",
"rules": {
"simplified_null_return": true,
"no_unused_imports": true,
"ordered_imports": {
"sort_algorithm": "alpha"
}
}
}./vendor/bin/pint
./vendor/bin/pint --test # Check onlyphpunit.xml<coverage>
<report>
<html outputDirectory="coverage"/>
<text outputFile="php://stdout"/>
</report>
</coverage>./vendor/bin/pest --coverage
./vendor/bin/pest --coverage --min=80 # Enforce minimum.github/workflows/tests.ymlname: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite
coverage: xdebug
- name: Install Dependencies
run: composer install --prefer-dist --no-interaction
- name: Code Style
run: ./vendor/bin/pint --test
- name: Static Analysis
run: ./vendor/bin/phpstan analyse
- name: Run Tests
run: ./vendor/bin/pest --coverage --min=80composer require brainmaestro/composer-git-hooks --devcomposer.json{
"extra": {
"hooks": {
"pre-commit": [
"./vendor/bin/pint",
"./vendor/bin/phpstan analyse",
"./vendor/bin/pest"
]
}
},
"scripts": {
"post-install-cmd": "vendor/bin/cghooks add --ignore-lock",
"post-update-cmd": "vendor/bin/cghooks update"
}
}