Initial PHPStan integration

This commit is contained in:
Pascal Birchler 2025-04-24 15:38:11 +02:00
parent 5039699772
commit 3eedb3ebd8
No known key found for this signature in database
GPG key ID: 0DECE73DD74E8B2F
11 changed files with 45 additions and 24 deletions

22
.gitignore vendored
View file

@ -1,18 +1,6 @@
.DS_Store
wp-cli.local.yml
build/
node_modules/
vendor/
src/vendor/
src/composer.json
third-party/
*.zip
*.tar.gz
*.swp
*.txt
*.log
composer.lock
phpunit.xml
phpcs.xml
.phpcs.xml
.vscode/ .vscode/
vendor/
composer.lock
phpcs.xml
phpunit.xml
.phpunit.result.cache

View file

@ -1 +0,0 @@
{"version":1,"defects":[],"times":{"AiCommand\\Tests\\MCP\\Client\\ClientTest::test_runs":0.001}}

View file

@ -12,11 +12,22 @@
"wp-cli/wp-cli": "^2.11" "wp-cli/wp-cli": "^2.11"
}, },
"require-dev": { "require-dev": {
"felixarntz/ai-services": "dev-main",
"humbug/php-scoper": "^0.18.17", "humbug/php-scoper": "^0.18.17",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-strict-rules": "^2.0",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"wp-cli/extension-command": "^2.1", "wp-cli/extension-command": "^2.1",
"wp-cli/wp-cli-tests": "^v4.3.9" "wp-cli/wp-cli-tests": "^v4.3.9"
}, },
"repositories": [
{
"type": "vcs",
"url": "https://github.com/felixarntz/ai-services",
"no-api": true
}
],
"config": { "config": {
"lock": false, "lock": false,
"process-timeout": 7200, "process-timeout": 7200,
@ -24,7 +35,8 @@
"allow-plugins": { "allow-plugins": {
"composer/installers": true, "composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true, "dealerdirect/phpcodesniffer-composer-installer": true,
"php-http/discovery": true "php-http/discovery": true,
"phpstan/extension-installer": true
} }
}, },
"extra": { "extra": {
@ -62,9 +74,11 @@
"phpcbf": "run-phpcbf-cleanup", "phpcbf": "run-phpcbf-cleanup",
"phpunit": "run-php-unit-tests", "phpunit": "run-php-unit-tests",
"prepare-tests": "install-package-tests", "prepare-tests": "install-package-tests",
"phpstan": "phpstan analyse --memory-limit=2048M",
"test": [ "test": [
"@lint", "@lint",
"@phpcs", "@phpcs",
"@phpstan",
"@phpunit", "@phpunit",
"@behat" "@behat"
] ]

16
phpstan.neon.dist Normal file
View file

@ -0,0 +1,16 @@
parameters:
level: 1
paths:
- ai-command.php
- src/
scanDirectories:
- vendor/felixarntz/ai-services/includes
- vendor/wp-cli/wp-cli/php
bootstrapFiles:
- tests/phpstan/bootstrap.php
reportMaybesInMethodSignatures: false
strictRules:
disallowedEmpty: false
strictArrayFilter: false
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

View file

@ -14,7 +14,7 @@
verbose="true"> verbose="true">
<testsuites> <testsuites>
<testsuite name="ai-command tests"> <testsuite name="ai-command tests">
<directory suffix="Test.php">tests</directory> <directory suffix="Test.php">tests/phpunit/tests</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>



View file

@ -67,6 +67,8 @@ class AiClient {


private function call_ai_service( $contents ) { private function call_ai_service( $contents ) {
// See https://github.com/felixarntz/ai-services/issues/25. // See https://github.com/felixarntz/ai-services/issues/25.
// Temporarily ignore error because eventually this should not be needed anymore.
// @phpstan-ignore function.notFound
add_filter( add_filter(
'map_meta_cap', 'map_meta_cap',
static function () { static function () {

View file

@ -134,14 +134,15 @@ readonly class CliCommands {
]; ];


foreach ( $synopsis_spec as $arg ) { foreach ( $synopsis_spec as $arg ) {
$prop_name = str_replace( '-', '_', $arg['name'] );

if ( 'positional' === $arg['type'] || 'assoc' === $arg['type'] ) { if ( 'positional' === $arg['type'] || 'assoc' === $arg['type'] ) {
$prop_name = str_replace( '-', '_', $arg['name'] );
$properties[ $prop_name ] = [ $properties[ $prop_name ] = [
'type' => 'string', 'type' => 'string',
'description' => $arg['description'] ?? "Parameter {$arg['name']}", 'description' => $arg['description'] ?? "Parameter {$arg['name']}",
]; ];

} }

// TODO: Handle flag type parameters (boolean) // TODO: Handle flag type parameters (boolean)


if ( ! isset( $arg['optional'] ) || ! $arg['optional'] ) { if ( ! isset( $arg['optional'] ) || ! $arg['optional'] ) {

View file

@ -142,7 +142,7 @@ class McpServerCommand extends WP_CLI_Command {
* @param array $args Indexed array of positional arguments. * @param array $args Indexed array of positional arguments.
*/ */
public function remove( $args, $assoc_args ): void { public function remove( $args, $assoc_args ): void {
$all = Utils\get_flag_value( $assoc_args, 'all', false ); $all = (bool) Utils\get_flag_value( $assoc_args, 'all', false );


if ( ! $all && empty( $args ) ) { if ( ! $all && empty( $args ) ) {
WP_CLI::error( 'Please specify one or more servers, or use --all.' ); WP_CLI::error( 'Please specify one or more servers, or use --all.' );

View file

@ -23,7 +23,7 @@ class McpConfig extends WP_CLI_Command {


$json_content = file_get_contents( $config_file ); $json_content = file_get_contents( $config_file );
$config = json_decode( $json_content, true ); $config = json_decode( $json_content, true );
return $config ? (array) $config : []; return null !== $config ? (array) $config : [];
} }


/** /**

View file

@ -0,0 +1 @@
<?php