diff --git a/composer.json b/composer.json index 8c06c45..e400a8b 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ "php": ">=7.2.24", "wp-cli/package-command": "^2", "wp-cli/scaffold-command": "^2", - "wp-cli/wp-cli": "^2.12" + "wp-cli/wp-cli": "^2.13" }, "require-dev": { "wp-cli/wp-cli-tests": "^5" diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..e0134ef --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,13 @@ +parameters: + level: 9 + paths: + - src + - scaffold-package-command.php + scanDirectories: + - vendor/wp-cli/wp-cli/php + scanFiles: + - vendor/php-stubs/wordpress-stubs/wordpress-stubs.php + treatPhpDocTypesAsCertain: false + ignoreErrors: + - identifier: missingType.parameter + - identifier: missingType.return diff --git a/src/ScaffoldPackageCommand.php b/src/ScaffoldPackageCommand.php index e126d24..d4e2580 100644 --- a/src/ScaffoldPackageCommand.php +++ b/src/ScaffoldPackageCommand.php @@ -5,6 +5,9 @@ namespace WP_CLI; use WP_CLI; use WP_CLI\Utils; +/** + * @phpstan-type ComposerConfig array{name: string, description: string, extra: array{readme: array{shields: array}, commands: array}, require: array, 'require-dev': array} + */ class ScaffoldPackageCommand { /** @@ -43,13 +46,13 @@ class ScaffoldPackageCommand { * [--require_wp_cli=] * : Required WP-CLI version for the package. * --- - * default: ^2.11 + * default: ^2.12 * --- * * [--require_wp_cli_tests=] * : Required WP-CLI testing framework version for the package. * --- - * default: ^4.3.9 + * default: ^5.0.0 * --- * [--skip-tests] @@ -242,7 +245,10 @@ EOT; self::check_if_valid_package_dir( $package_dir ); - $composer_obj = json_decode( file_get_contents( $package_dir . '/composer.json' ), true ); + /** + * @var null|ComposerConfig $composer_obj + */ + $composer_obj = json_decode( (string) file_get_contents( $package_dir . '/composer.json' ), true ); if ( ! $composer_obj ) { WP_CLI::error( 'Invalid composer.json in package directory.' ); } @@ -334,8 +340,8 @@ EOT; */ $longdesc = isset( $parent_command['longdesc'] ) ? $parent_command['longdesc'] : ''; - $longdesc = preg_replace( '/## GLOBAL PARAMETERS(.+)/s', '', $longdesc ); - $longdesc = preg_replace( '/##\s(.+)/', '**$1**', $longdesc ); + $longdesc = (string) preg_replace( '/## GLOBAL PARAMETERS(.+)/s', '', $longdesc ); + $longdesc = (string) preg_replace( '/##\s(.+)/', '**$1**', $longdesc ); // definition lists $longdesc = preg_replace_callback( '/([^\n]+)\n: (.+?)(\n\n|$)/s', [ __CLASS__, 'rewrap_param_desc' ], $longdesc ); @@ -405,7 +411,9 @@ EOT; $v = $composer_obj['extra']['readme'][ $section ][ $k ]; if ( filter_var( $v, FILTER_VALIDATE_URL ) === $v ) { $response = Utils\http_request( 'GET', $v ); - $v = $response->body; + + // @phpstan-ignore class.notFound + $v = $response->body; } elseif ( preg_match( $ext_regex, $v ) ) { $v = $package_dir . '/' . $v; } @@ -479,7 +487,10 @@ EOT; $force = Utils\get_flag_value( $assoc_args, 'force' ); $template_path = dirname( __DIR__ ) . '/templates'; - $composer_obj = json_decode( file_get_contents( $package_dir . '/composer.json' ), true ); + /** + * @var ComposerConfig $composer_obj + */ + $composer_obj = json_decode( (string) file_get_contents( $package_dir . '/composer.json' ), true ); $settings_vars = [ 'has_description' => false, 'description' => '', @@ -709,27 +720,10 @@ EOT; $files_written = []; foreach ( $copy_source as $source => $to_copy ) { foreach ( $to_copy as $file => $dir ) { - if ( 'php/WP_CLI/ProcessRun.php' === $file && ! file_exists( $source . "/{$file}" ) ) { - continue; - } // file_get_contents() works with Phar-archived files - $contents = file_get_contents( $source . "/{$file}" ); + $contents = (string) file_get_contents( $source . "/{$file}" ); $file_path = $dir . basename( $file ); - if ( '.travis.yml' === $file ) { - foreach ( $travis_tags as $travis_tag ) { - if ( isset( $travis_tag_overwrites[ $travis_tag ] ) ) { - // Note the contents fully overwrite, so should include the tag, eg `env:` etc (or nothing if want to remove totally). - $contents = preg_replace( '/^' . $travis_tag . ':.*?(?:^$|\z)/ms', $travis_tag_overwrites[ $travis_tag ], $contents ); - } elseif ( isset( $travis_tag_appends[ $travis_tag ] ) ) { - $contents = preg_replace( '/^' . $travis_tag . ':.*?(?:^$|\z)/ms', '\0' . $travis_tag_appends[ $travis_tag ], $contents ); - } - } - if ( $travis_append ) { - $contents .= $travis_append; - } - } - $force = Utils\get_flag_value( $assoc_args, 'force' ); $should_write_file = $this->prompt_if_files_will_be_overwritten( $file_path, $force ); if ( ! $should_write_file ) { diff --git a/templates/composer.mustache b/templates/composer.mustache index 5929906..be307a7 100644 --- a/templates/composer.mustache +++ b/templates/composer.mustache @@ -15,7 +15,8 @@ "process-timeout": 7200, "sort-packages": true, "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true } }, "extra": { @@ -42,12 +43,14 @@ "behat-rerun": "rerun-behat-tests", "lint": "run-linter-tests", "phpcs": "run-phpcs-tests", + "phpstan": "run-phpstan-tests", "phpcbf": "run-phpcbf-cleanup", "phpunit": "run-php-unit-tests", "prepare-tests": "install-package-tests", "test": [ "@lint", "@phpcs", + "@phpstan", "@phpunit", "@behat" ]