diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..2b9d2f4 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,31 @@ +name: Test PHP Stan Testsuite + +on: + push: + branches: [ "master", "develop" ] + pull_request: + branches: [ "master", "develop" ] + +permissions: + contents: read + +jobs: + test-phpstan: + + runs-on: ubuntu-latest + + steps: + - uses: shivammathur/setup-php@15c43e89cdef867065b0213be354c2841860869e + with: + php-version: '8.1' + + - uses: actions/checkout@v3 + + - name: Copy .env + run: php -r "file_exists('.env') || copy('.env.example', '.env');" + + - name: Install Dependencies + run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + + - name: Execute static analysis via PHPStan + run: vendor/bin/phpstan analyse --no-progress --quiet --error-format=github > $GITHUB_STEP_SUMMARY diff --git a/composer.json b/composer.json index 74949b8..9607ff4 100755 --- a/composer.json +++ b/composer.json @@ -28,6 +28,8 @@ "laravel/sail": "^1.0.1", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^6.1", + "nunomaduro/larastan": "^2.0", + "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.5.10", "rector/rector": "^0.15.1", "spatie/laravel-ignition": "^1.0" @@ -62,6 +64,8 @@ "test-pint": "@php vendor/bin/pint -v --test", "test": "@php artisan test", "rector": "@php vendor/bin/rector", + "phpstan": "@php vendor/bin/phpstan analyse", + "phpstan-baseline": "@php vendor/bin/phpstan analyse --generate-baseline --allow-empty-baseline", "meta": [ "@php artisan ide-helper:generate", "@php artisan ide-helper:meta", diff --git a/composer.lock b/composer.lock index ee6daaf..907eac5 100755 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "edb0145dd1f046d5516ccb6b8fd4bded", + "content-hash": "1fd6c1503a93edd1c7fba8d49ce22ca8", "packages": [ { "name": "aeon-php/calendar", @@ -7940,6 +7940,103 @@ ], "time": "2022-09-29T12:29:49+00:00" }, + { + "name": "nunomaduro/larastan", + "version": "2.2.9", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/larastan.git", + "reference": "333e7915b984ce6606175749430081a372ead37e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/333e7915b984ce6606175749430081a372ead37e", + "reference": "333e7915b984ce6606175749430081a372ead37e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^9", + "illuminate/container": "^9", + "illuminate/contracts": "^9", + "illuminate/database": "^9", + "illuminate/http": "^9", + "illuminate/pipeline": "^9", + "illuminate/support": "^9", + "mockery/mockery": "^1.4.4", + "php": "^8.0.2", + "phpmyadmin/sql-parser": "^5.5", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13.2", + "orchestra/testbench": "^7.0.0", + "phpunit/phpunit": "^9.5.11" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/nunomaduro/larastan/issues", + "source": "https://github.com/nunomaduro/larastan/tree/2.2.9" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/canvural", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-11-04T14:58:00+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.3", @@ -8051,6 +8148,79 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "^3.0" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "sql" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "time": "2021-12-09T04:31:52+00:00" + }, { "name": "phpstan/phpstan", "version": "1.9.4", diff --git a/config/settings.php b/config/settings.php index 7c910c0..86831e9 100755 --- a/config/settings.php +++ b/config/settings.php @@ -61,8 +61,8 @@ 'global_casts' => [ DateTimeInterface::class => Spatie\LaravelSettings\SettingsCasts\DateTimeInterfaceCast::class, DateTimeZone::class => Spatie\LaravelSettings\SettingsCasts\DateTimeZoneCast::class, - // Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, - Spatie\LaravelData\Data::class => Spatie\LaravelSettings\SettingsCasts\DataCast::class, + // Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, + // Spatie\LaravelData\Data::class => Spatie\LaravelSettings\SettingsCasts\DataCast::class, ], /* diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..3eeed58 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,231 @@ +parameters: + ignoreErrors: + - + message: "#^PHPDoc tag @return with type int is incompatible with native type void\\.$#" + count: 1 + path: app/Console/Commands/CleanupOldPrintJobsCommand.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:ClientApplications\\(\\)\\.$#" + count: 1 + path: app/Http/Controllers/App/ClientApplicationsController.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:ClientApplications\\(\\)\\.$#" + count: 1 + path: app/Http/Controllers/App/PrintJobPromisesController.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:ClientApplications\\(\\)\\.$#" + count: 1 + path: app/Http/Controllers/App/PrintJobsController.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:Printers\\(\\)\\.$#" + count: 2 + path: app/Http/Controllers/App/PrintJobsController.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:PrintServers\\(\\)\\.$#" + count: 1 + path: app/Http/Controllers/App/PrintServersController.php + + - + message: "#^Parameter \\#3 \\$parameters of static method Illuminate\\\\Routing\\\\UrlGenerator\\:\\:temporarySignedRoute\\(\\) expects array, App\\\\Models\\\\PrintJob given\\.$#" + count: 1 + path: app/Http/Controllers/PrintServiceApi/PrintJobsController.php + + - + message: "#^PHPDoc tag @return with type Illuminate\\\\Http\\\\Response is incompatible with native type void\\.$#" + count: 3 + path: app/Http/Controllers/WebPrintApi/PrintDialogsController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintDialogsController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintJobPromisesContentController.php + + - + message: "#^PHPDoc tag @return with type App\\\\Http\\\\Resources\\\\PrintJobPromiseResource\\|Illuminate\\\\Http\\\\Response is not subtype of native type App\\\\Http\\\\Resources\\\\PrintJobPromiseResource\\.$#" + count: 2 + path: app/Http/Controllers/WebPrintApi/PrintJobPromisesController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintJobPromisesController.php + + - + message: "#^PHPDoc tag @return with type Illuminate\\\\Http\\\\Response is incompatible with native type void\\.$#" + count: 4 + path: app/Http/Controllers/WebPrintApi/PrintJobsController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintJobsController.php + + - + message: "#^Call to an undefined method Illuminate\\\\Database\\\\Eloquent\\\\Builder\\:\\:forType\\(\\)\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintersController.php + + - + message: "#^Parameter \\#2 \\$callback of method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\\\:\\:when\\(\\) expects \\(callable\\(Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\BelongsToMany\\, mixed\\)\\: void\\)\\|null, Closure\\(Illuminate\\\\Database\\\\Eloquent\\\\Builder, mixed\\)\\: void given\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintersController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/PrintersController.php + + - + message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" + count: 1 + path: app/Http/Controllers/WebPrintApi/UserPrintDialogController.php + + - + message: "#^Property App\\\\Models\\\\PrintDialog\\:\\:\\$status \\(App\\\\Models\\\\Enums\\\\PrintDialogStatusEnum\\) does not accept string\\.$#" + count: 2 + path: app/Http/Livewire/PrintDialog.php + + - + message: "#^Access to an undefined property App\\\\Http\\\\Resources\\\\PrinterResource\\:\\:\\$ppd_options_layout\\.$#" + count: 1 + path: app/Http/Resources/PrinterResource.php + + - + message: "#^Method App\\\\Models\\\\ClientApplication\\:\\:getRememberTokenName\\(\\) should return string but returns null\\.$#" + count: 1 + path: app/Models/ClientApplication.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperClientApplication\\.$#" + count: 1 + path: app/Models/ClientApplication.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperMembership\\.$#" + count: 1 + path: app/Models/Membership.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperPrintDialog\\.$#" + count: 1 + path: app/Models/PrintDialog.php + + - + message: "#^Parameter \\#3 \\$parameters of static method Illuminate\\\\Routing\\\\UrlGenerator\\:\\:temporarySignedRoute\\(\\) expects array, \\$this\\(App\\\\Models\\\\PrintDialog\\) given\\.$#" + count: 1 + path: app/Models/PrintDialog.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperPrintJob\\.$#" + count: 1 + path: app/Models/PrintJob.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperPrintJobPromise\\.$#" + count: 1 + path: app/Models/PrintJobPromise.php + + - + message: "#^Method App\\\\Models\\\\PrintServer\\:\\:getRememberTokenName\\(\\) should return string but returns null\\.$#" + count: 1 + path: app/Models/PrintServer.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperPrintServer\\.$#" + count: 1 + path: app/Models/PrintServer.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperPrinter\\.$#" + count: 1 + path: app/Models/Printer.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperTeam\\.$#" + count: 1 + path: app/Models/Team.php + + - + message: "#^PHPDoc type array of property App\\\\Models\\\\Team\\:\\:\\$casts is not covariant with PHPDoc type array\\ of overridden property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$casts\\.$#" + count: 1 + path: app/Models/Team.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperTeamInvitation\\.$#" + count: 1 + path: app/Models/TeamInvitation.php + + - + message: "#^PHPDoc tag @mixin contains unknown class App\\\\Models\\\\IdeHelperUser\\.$#" + count: 1 + path: app/Models/User.php + + - + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$personal_team\\.$#" + count: 3 + path: app/Policies/ClientApplicationPolicy.php + + - + message: "#^PHPDoc tag @return with type bool is incompatible with native type void\\.$#" + count: 2 + path: app/Policies/ClientApplicationPolicy.php + + - + message: "#^PHPDoc tag @return with type mixed is not subtype of native type bool\\.$#" + count: 2 + path: app/Policies/GeneralSettingsPolicy.php + + - + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$personal_team\\.$#" + count: 3 + path: app/Policies/PrintJobPromisesPolicy.php + + - + message: "#^PHPDoc tag @return with type bool is incompatible with native type void\\.$#" + count: 2 + path: app/Policies/PrintJobPromisesPolicy.php + + - + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$personal_team\\.$#" + count: 3 + path: app/Policies/PrintJobsPolicy.php + + - + message: "#^PHPDoc tag @return with type bool is incompatible with native type void\\.$#" + count: 2 + path: app/Policies/PrintJobsPolicy.php + + - + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$personal_team\\.$#" + count: 3 + path: app/Policies/PrintServerPolicy.php + + - + message: "#^PHPDoc tag @return with type bool is incompatible with native type void\\.$#" + count: 2 + path: app/Policies/PrintServerPolicy.php + + - + message: "#^Access to an undefined property Illuminate\\\\Database\\\\Eloquent\\\\Model\\:\\:\\$personal_team\\.$#" + count: 3 + path: app/Policies/PrintersPolicy.php + + - + message: "#^PHPDoc tag @return with type bool is incompatible with native type void\\.$#" + count: 2 + path: app/Policies/PrintersPolicy.php + + - + message: "#^PHPDoc tag @return with type mixed is not subtype of native type bool\\.$#" + count: 8 + path: app/Policies/TeamPolicy.php diff --git a/phpstan.dist.neon b/phpstan.dist.neon new file mode 100644 index 0000000..9e543d9 --- /dev/null +++ b/phpstan.dist.neon @@ -0,0 +1,13 @@ +includes: + - ./vendor/nunomaduro/larastan/extension.neon + - phpstan-baseline.neon + +parameters: + level: 6 + + paths: + - app + ignoreErrors: + - '#Method [a-zA-Z0-9\\_]+::[a-zA-Z0-9\\_()]+ should return [a-zA-Z0-9\\_]+ but return statement is missing#' + +# checkMissingIterableValueType: false