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/features/scaffold-package-readme.feature b/features/scaffold-package-readme.feature index 6c12925..32b6722 100644 --- a/features/scaffold-package-readme.feature +++ b/features/scaffold-package-readme.feature @@ -40,7 +40,7 @@ Feature: Scaffold a README.md file for an existing package And the {PACKAGE_PATH}/local/wp-cli/default-readme/README.md file should exist And the {PACKAGE_PATH}/local/wp-cli/default-readme/README.md file should contain: """ - Installing this package requires WP-CLI v2.11 or greater. Update to the latest stable release with `wp cli update`. + Installing this package requires WP-CLI v2.12 or greater. Update to the latest stable release with `wp cli update`. """ And the {PACKAGE_PATH}/local/wp-cli/default-readme/README.md file should contain: """ @@ -76,7 +76,7 @@ Feature: Scaffold a README.md file for an existing package And the {PACKAGE_PATH}/local/wp-cli/custom-branch/README.md file should exist And the {PACKAGE_PATH}/local/wp-cli/custom-branch/README.md file should contain: """ - Installing this package requires WP-CLI v2.11 or greater. Update to the latest stable release with `wp cli update`. + Installing this package requires WP-CLI v2.12 or greater. Update to the latest stable release with `wp cli update`. """ And the {PACKAGE_PATH}/local/wp-cli/custom-branch/README.md file should contain: """ @@ -152,10 +152,10 @@ Feature: Scaffold a README.md file for an existing package "files": [ "command.php" ] }, "require": { - "wp-cli/wp-cli": "^2.11" + "wp-cli/wp-cli": "^2.12" }, "require-dev": { - "wp-cli/wp-cli-tests": "^4.3.9" + "wp-cli/wp-cli-tests": "^5.0.0" }, "extra": { "readme": { @@ -333,7 +333,7 @@ Feature: Scaffold a README.md file for an existing package }, "require-dev": { "wp-cli/wp-cli": "*", - "wp-cli/wp-cli-tests": "^4.3.9" + "wp-cli/wp-cli-tests": "^5.0.0" }, "extra": { "bundled": true diff --git a/features/scaffold-package.feature b/features/scaffold-package.feature index 9c37eae..d321887 100644 --- a/features/scaffold-package.feature +++ b/features/scaffold-package.feature @@ -34,7 +34,7 @@ Feature: Scaffold WP-CLI commands And the {PACKAGE_PATH}/local/wp-cli/foo/composer.json file should contain: """ "require": { - "wp-cli/wp-cli": "^2.11" + "wp-cli/wp-cli": "^2.12" }, """ And the {PACKAGE_PATH}/local/wp-cli/foo/hello-world-command.php file should exist 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 @@ 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 @@ public function package_readme( $args, $assoc_args ) { 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 @@ public function package_readme( $args, $assoc_args ) { */ $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 @@ public function package_readme( $args, $assoc_args ) { $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 @@ public function package_github( $args, $assoc_args ) { $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 @@ public function package_tests( $args, $assoc_args ) { $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" ]