From e34364b75aa756386f41b1d7590f6e2c099a69a0 Mon Sep 17 00:00:00 2001 From: OscarMerida Date: Thu, 19 Dec 2024 09:22:53 -0500 Subject: [PATCH 1/6] USAGOV-2116-phsptan-config: Installs phpstan with Drupal rules. --- composer.json | 13 ++- composer.lock | 214 +++++++++++++++++++++++++++++++++++++++++++++++++- phpstan.neon | 39 +++++++++ 3 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index e16e6a0886..b453cf35ce 100644 --- a/composer.json +++ b/composer.json @@ -167,7 +167,10 @@ }, "require-dev": { "drupal/coder": "^8.3", - "php-parallel-lint/php-parallel-lint": "^1.4" + "mglaman/phpstan-drupal": "*", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpstan/phpstan": "*", + "phpstan/phpstan-deprecation-rules": "*" }, "scripts": { "changed-files": [ @@ -187,6 +190,14 @@ ], "php-lint": [ "vendor/bin/parallel-lint -e php,module,inc,install,test,profile,theme ./web/modules/custom ./web/themes/custom" + ], + + "phpstan": [ + "vendor/bin/phpstan --memory-limit=1G" + ], + + "phpstan-changes": [ + "vendor/bin/phpstan --memory-limit=1G `bin/changed-files`" ] } } diff --git a/composer.lock b/composer.lock index 8cf213b5e2..85d10da64c 100644 --- 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": "750e25aca453a5fccca5ae752bbcd6e3", + "content-hash": "94edd133926783b501da55b423aab2a8", "packages": [ { "name": "asm89/stack-cors", @@ -11777,6 +11777,107 @@ }, "time": "2024-11-28T23:14:29+00:00" }, + { + "name": "mglaman/phpstan-drupal", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/mglaman/phpstan-drupal.git", + "reference": "6fab2917c6ed26c1f515771c5ab2065448169016" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mglaman/phpstan-drupal/zipball/6fab2917c6ed26c1f515771c5ab2065448169016", + "reference": "6fab2917c6ed26c1f515771c5ab2065448169016", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "symfony/finder": "^6.2 || ^7.0", + "symfony/yaml": "^6.2 || ^7.0", + "webflo/drupal-finder": "^1.3.1" + }, + "require-dev": { + "behat/mink": "^1.10", + "composer/installers": "^1.9", + "drupal/core-recommended": "^10", + "drush/drush": "^11 || ^12 || ^13", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9 || ^10 || ^11", + "slevomat/coding-standard": "^8.6", + "squizlabs/php_codesniffer": "^3.7", + "symfony/phpunit-bridge": "^6.2 || ^7.0" + }, + "suggest": { + "jangregor/phpstan-prophecy": "Provides a prophecy/prophecy extension for phpstan/phpstan.", + "phpstan/phpstan-deprecation-rules": "For catching deprecations, especially in Drupal core.", + "phpstan/phpstan-phpunit": "PHPUnit extensions and rules for PHPStan." + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + }, + "installer-paths": { + "tests/fixtures/drupal/core": [ + "type:drupal-core" + ], + "tests/fixtures/drupal/libraries/{$name}": [ + "type:drupal-library" + ], + "tests/fixtures/drupal/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "tests/fixtures/drupal/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "tests/fixtures/drupal/profiles/contrib/{$name}": [ + "type:drupal-profile" + ] + } + }, + "autoload": { + "psr-4": { + "mglaman\\PHPStanDrupal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Glaman", + "email": "nmd.matt@gmail.com" + } + ], + "description": "Drupal extension and rules for PHPStan", + "support": { + "issues": "https://github.com/mglaman/phpstan-drupal/issues", + "source": "https://github.com/mglaman/phpstan-drupal/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/mglaman", + "type": "github" + }, + { + "url": "https://opencollective.com/phpstan-drupal", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/mglaman/phpstan-drupal", + "type": "tidelift" + } + ], + "time": "2024-12-11T16:01:57+00:00" + }, { "name": "php-parallel-lint/php-parallel-lint", "version": "v1.4.0", @@ -11885,6 +11986,111 @@ }, "time": "2024-10-13T11:25:22+00:00" }, + { + "name": "phpstan/phpstan", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "50d276fc3bf1430ec315f2f109bbde2769821524" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/50d276fc3bf1430ec315f2f109bbde2769821524", + "reference": "50d276fc3bf1430ec315f2f109bbde2769821524", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2024-12-17T17:14:01+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "1cc1259cb91ee4cfbb5c39bca9f635f067c910b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/1cc1259cb91ee4cfbb5c39bca9f635f067c910b4", + "reference": "1cc1259cb91ee4cfbb5c39bca9f635f067c910b4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.1" + }, + "time": "2024-11-28T21:56:36+00:00" + }, { "name": "sirbrillig/phpcs-variable-analysis", "version": "v2.11.21", @@ -12102,7 +12308,7 @@ }, "prefer-stable": true, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.2.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000000..c86b6e98b1 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,39 @@ +includes: + - vendor/mglaman/phpstan-drupal/extension.neon + - vendor/phpstan/phpstan-deprecation-rules/rules.neon +parameters: + level: 3 + paths: + - web/modules/custom + - web/themes/custom + excludePaths: + - web/modules/custom/usagov_benefit_finder + - web/themes/custom/usagov/node_modules/flatted/php + # The next two files define the same functions into global scope, + # And confuse stan + - web/modules/custom/usagov_directories/utility/states_import_prep.php + - web/modules/custom/usagov_directories/utility/agency_import_prep.php + reportUnmatchedIgnoredErrors: false + ignoreErrors: + # same as Drupal core + # new static() is a best practice in Drupal, so we cannot fix that. + - "#^Unsafe usage of new static#" + + - '#^Access to an undefined property Drupal\\views\\ResultRow::#' + - '#^Access to an undefined property Drupal\\views\\Plugin\\views\\field\\FieldPluginBase::#' + # FieldItemListInterface needs additional help in core + # https://github.com/mglaman/phpstan-drupal/issues/782 + - '#Access to an undefined property Drupal\\Core\\Field\\FieldItemInterface::#' + - '#Access to an undefined property Drupal\\Core\\Field\\FieldItemListInterface::#' + - '#Access to an undefined property Drupal\\Core\\Field\\FieldItemListInterface\\:\:\$alias.#' + - '#Access to an undefined property Drupal\\Core\\TypedData\\TypedDataInterface::#' + + drupal: + entityMapping: + # From https://www.drupal.org/project/paragraphs/issues/3256371 + embedded_paragraphs: + class: Drupal\paragraphs\Entity\Paragraph + paragraph: + class: Drupal\paragraphs\Entity\Paragraph + paragraphs_type: + class: Drupal\paragraphs\Entity\ParagraphsType From 9d2b75321aebf764b99d4a8bc6e1fbb634742f0b Mon Sep 17 00:00:00 2001 From: OscarMerida Date: Thu, 19 Dec 2024 09:24:59 -0500 Subject: [PATCH 2/6] USAGOV-2116-phsptan-config: Document phpstan usage. --- README.md | 19 ++++++++++++++----- composer.json | 5 ----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1edf9ff9e4..6f04b1e6e4 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ We use [Cypress](cypress.io). Note that we use only the Cypress App, _not_ Cypre 1. Supply Drupal *credentials* for the automated tests: Edit the file `env.local.cypress`. Supply a valid Drupal user name and password for `cypressCmsUser` and `cypressCmsPass`. -2. Run `docker compose up` to (re-)create the cypress container with the new environment variables. +2. Run `docker compose build cypress` to (re-)create the cypress container with the new environment variables. 3. Run `bin/cypress-ssh` to open a shell in the cypress container @@ -337,26 +337,35 @@ The following composer scripts are aliases for running these tools. * Check for PHP lint errors `./bin/composer php-lint` +## Checking Code with PHPStan + +[PHPStan](https://phpstan.org/) is available to statically analyze custom theme and module code for correctness. + +It should be installed automatically on a local environment via `composer install`. + +The following composer scripts are aliases for running PHPStan + +* Check for errors at the level configured in `phpstan.neon` + `./bin/composer phpcs-errors`: + ## Project Restart/Reset + Sometimes, Docker problems arise after an upgrade and a more complete restart is needed. After closing down and destroying the existing containers, networks, and volumes the procedure is the same as the full project setup. ### Docker Cleanup - ``` docker compose down docker system prune ``` - Refer to `Full Project Setup` section above to continue the setup. - [back to top](#usagov-2021) - ## Update Database + Safe development database dumps are kept in Google Drive. You can download and import a SQL database from https://drive.google.com/drive/folders/1zVDr7dxzIa3tPsdxCb0FOXNvIFz96dNx?usp=sharing. diff --git a/composer.json b/composer.json index b453cf35ce..b67955243c 100644 --- a/composer.json +++ b/composer.json @@ -191,13 +191,8 @@ "php-lint": [ "vendor/bin/parallel-lint -e php,module,inc,install,test,profile,theme ./web/modules/custom ./web/themes/custom" ], - "phpstan": [ "vendor/bin/phpstan --memory-limit=1G" - ], - - "phpstan-changes": [ - "vendor/bin/phpstan --memory-limit=1G `bin/changed-files`" ] } } From c52f5ea4f7b27fbbc438dd036eeba741e6ffbd2d Mon Sep 17 00:00:00 2001 From: OscarMerida Date: Thu, 19 Dec 2024 13:26:44 -0500 Subject: [PATCH 3/6] USAGOV-2116-phsptan-config: Update config to pull in the rules from phpstan-drupal package. --- phpstan.neon | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index c86b6e98b1..79293c35ed 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,9 @@ includes: - vendor/mglaman/phpstan-drupal/extension.neon + - vendor/mglaman/phpstan-drupal/rules.neon - vendor/phpstan/phpstan-deprecation-rules/rules.neon parameters: - level: 3 + level: 4 paths: - web/modules/custom - web/themes/custom From e50dd0e27d1783d0eea48d523a557588812fbc7e Mon Sep 17 00:00:00 2001 From: OscarMerida Date: Thu, 26 Dec 2024 15:39:55 -0500 Subject: [PATCH 4/6] USAGOV-2116-phsptan-config: Updating instructions for installing phpstan --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f04b1e6e4..a7fce4f4eb 100644 --- a/README.md +++ b/README.md @@ -341,7 +341,8 @@ The following composer scripts are aliases for running these tools. [PHPStan](https://phpstan.org/) is available to statically analyze custom theme and module code for correctness. -It should be installed automatically on a local environment via `composer install`. +It's defined as a dev dependency in `composer.json` and will be installed automatically when you run the build scripts or `bin/composer` install. + The following composer scripts are aliases for running PHPStan From 30cd1e8398d2872e73c1238d5d65742385556237 Mon Sep 17 00:00:00 2001 From: OscarMerida Date: Fri, 27 Dec 2024 15:45:34 -0500 Subject: [PATCH 5/6] USAGOV-2116-phsptan-config: Fixing Merge conflicts --- composer.lock | 208 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 207 insertions(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index a670be3808..d0986ec9a9 100644 --- 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": "f0d83968cc33c23bac1bc0397f95f19e", + "content-hash": "d5ed7d7e2f3b7236d6206c3f0a6a81c4", "packages": [ { "name": "asm89/stack-cors", @@ -11772,6 +11772,107 @@ }, "time": "2024-11-28T23:14:29+00:00" }, + { + "name": "mglaman/phpstan-drupal", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/mglaman/phpstan-drupal.git", + "reference": "6fab2917c6ed26c1f515771c5ab2065448169016" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mglaman/phpstan-drupal/zipball/6fab2917c6ed26c1f515771c5ab2065448169016", + "reference": "6fab2917c6ed26c1f515771c5ab2065448169016", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "symfony/finder": "^6.2 || ^7.0", + "symfony/yaml": "^6.2 || ^7.0", + "webflo/drupal-finder": "^1.3.1" + }, + "require-dev": { + "behat/mink": "^1.10", + "composer/installers": "^1.9", + "drupal/core-recommended": "^10", + "drush/drush": "^11 || ^12 || ^13", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9 || ^10 || ^11", + "slevomat/coding-standard": "^8.6", + "squizlabs/php_codesniffer": "^3.7", + "symfony/phpunit-bridge": "^6.2 || ^7.0" + }, + "suggest": { + "jangregor/phpstan-prophecy": "Provides a prophecy/prophecy extension for phpstan/phpstan.", + "phpstan/phpstan-deprecation-rules": "For catching deprecations, especially in Drupal core.", + "phpstan/phpstan-phpunit": "PHPUnit extensions and rules for PHPStan." + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + }, + "installer-paths": { + "tests/fixtures/drupal/core": [ + "type:drupal-core" + ], + "tests/fixtures/drupal/libraries/{$name}": [ + "type:drupal-library" + ], + "tests/fixtures/drupal/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "tests/fixtures/drupal/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "tests/fixtures/drupal/profiles/contrib/{$name}": [ + "type:drupal-profile" + ] + } + }, + "autoload": { + "psr-4": { + "mglaman\\PHPStanDrupal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Glaman", + "email": "nmd.matt@gmail.com" + } + ], + "description": "Drupal extension and rules for PHPStan", + "support": { + "issues": "https://github.com/mglaman/phpstan-drupal/issues", + "source": "https://github.com/mglaman/phpstan-drupal/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/mglaman", + "type": "github" + }, + { + "url": "https://opencollective.com/phpstan-drupal", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/mglaman/phpstan-drupal", + "type": "tidelift" + } + ], + "time": "2024-12-11T16:01:57+00:00" + }, { "name": "php-parallel-lint/php-parallel-lint", "version": "v1.4.0", @@ -11880,6 +11981,111 @@ }, "time": "2024-10-13T11:25:22+00:00" }, + { + "name": "phpstan/phpstan", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "50d276fc3bf1430ec315f2f109bbde2769821524" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/50d276fc3bf1430ec315f2f109bbde2769821524", + "reference": "50d276fc3bf1430ec315f2f109bbde2769821524", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2024-12-17T17:14:01+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "1cc1259cb91ee4cfbb5c39bca9f635f067c910b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/1cc1259cb91ee4cfbb5c39bca9f635f067c910b4", + "reference": "1cc1259cb91ee4cfbb5c39bca9f635f067c910b4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.1" + }, + "time": "2024-11-28T21:56:36+00:00" + }, { "name": "sirbrillig/phpcs-variable-analysis", "version": "v2.11.21", From 37acca21efc5cd2b11a7760baa59a135eed515b8 Mon Sep 17 00:00:00 2001 From: Oscar Merida Date: Fri, 27 Dec 2024 15:46:44 -0500 Subject: [PATCH 6/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9743dae4d..c20e8dfee5 100644 --- a/README.md +++ b/README.md @@ -332,7 +332,7 @@ ex: USAGOV-123-short-ticket-name If a ticket name is too long, you may shorten or even exclude the title, only the USAGOV-### prefix is required. -As part of the `bin/init` process, we copy a Git hook script (```.git.commit-msg``` to ```.git/hooks/commit-msg```) +As part of the `bin/init` process, we copy a Git hook script (`.git.commit-msg` to `.git/hooks/commit-msg`) to automatically include the current branch name in all commit messages. This ensures that commit messages consistently reflect the task being worked on, streamlining automation.