Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHPStan support not compatible with gitlabci #92

Open
neclimdul opened this issue Nov 1, 2024 · 8 comments
Open

PHPStan support not compatible with gitlabci #92

neclimdul opened this issue Nov 1, 2024 · 8 comments

Comments

@neclimdul
Copy link

The PHPStan support this provides runs in web/modules/custom/ which means that the baselines aren't compatible with those that would be generated for gitlab-ci. This makes it much less useful for testing a module and fixing CI issues.

@weitzman
Copy link
Collaborator

is there a contrib module you can point to that demonstrates the issue?

@neclimdul
Copy link
Author

Its been true on any module I've tested.

For example, I have a module that uses this baseline that I built to work in gitlab-ci on d.o

parameters:
	ignoreErrors:
		-
			message: "#^Call to an undefined method Drupal\\\\Core\\\\Form\\\\FormInterface\\:\\:getEntity\\(\\)\\.$#"
			count: 3
			path: coveo.module

		-
			message: "#^Method Drupal\\\\coveo\\\\Plugin\\\\search_api\\\\backend\\\\SearchApiCoveoBackend\\:\\:getAutocompleteSuggestions\\(\\) has invalid return type Drupal\\\\search_api_autocomplete\\\\Suggestion\\\\SuggestionInterface\\.$#"
			count: 1
			path: src/Plugin/search_api/backend/SearchApiCoveoBackend.php

		-
			message: "#^Parameter \\$search of method Drupal\\\\coveo\\\\Plugin\\\\search_api\\\\backend\\\\SearchApiCoveoBackend\\:\\:getAutocompleteSuggestions\\(\\) has invalid type Drupal\\\\search_api_autocomplete\\\\SearchInterface\\.$#"
			count: 2
			path: src/Plugin/search_api/backend/SearchApiCoveoBackend.php

If I run phpstan in ddev all these are reported.

> ddev phpstan
Note: Using configuration file /var/www/html/phpstan.neon.
 21/21 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ -------------------------------------------------------------------------- 
  Line   coveo/coveo.module                                                        
 ------ -------------------------------------------------------------------------- 
  20     Call to an undefined method Drupal\Core\Form\FormInterface::getEntity().  
  50     Call to an undefined method Drupal\Core\Form\FormInterface::getEntity().  
  68     Call to an undefined method Drupal\Core\Form\FormInterface::getEntity().  
 ------ -------------------------------------------------------------------------- 

 ------ ----------------------------------------------------------------------------------------------------------------------------------------- 
  Line   coveo/src/Plugin/search_api/backend/SearchApiCoveoBackend.php                                                                            
 ------ ----------------------------------------------------------------------------------------------------------------------------------------- 
  539    Method Drupal\coveo\Plugin\search_api\backend\SearchApiCoveoBackend::getAutocompleteSuggestions() has invalid return type                
         Drupal\search_api_autocomplete\Suggestion\SuggestionInterface.                                                                           
  539    Parameter $search of method Drupal\coveo\Plugin\search_api\backend\SearchApiCoveoBackend::getAutocompleteSuggestions() has invalid type  
         Drupal\search_api_autocomplete\SearchInterface.                                                                                          
  539    Parameter $search of method Drupal\coveo\Plugin\search_api\backend\SearchApiCoveoBackend::getAutocompleteSuggestions() has invalid type  
         Drupal\search_api_autocomplete\SearchInterface.                                                                                          
 ------ ----------------------------------------------------------------------------------------------------------------------------------------- 

Updating through ddev generates this diff

> ddev phpstan --generate-baseline=phpstan-baseline.neon --allow-empty-baseline
Note: Using configuration file /var/www/html/phpstan.neon.
 21/21 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
                                                                                                                        
 [OK] Baseline generated with 6 errors.                                                                                 
                                                                                                                        

> git diff phpstan-baseline.neon
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 247d5b2..813f791 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -3,14 +3,14 @@ parameters:
 		-
 			message: "#^Call to an undefined method Drupal\\\\Core\\\\Form\\\\FormInterface\\:\\:getEntity\\(\\)\\.$#"
 			count: 3
-			path: coveo.module
+			path: web/modules/custom/coveo/coveo.module
 
 		-
 			message: "#^Method Drupal\\\\coveo\\\\Plugin\\\\search_api\\\\backend\\\\SearchApiCoveoBackend\\:\\:getAutocompleteSuggestions\\(\\) has invalid return type Drupal\\\\search_api_autocomplete\\\\Suggestion\\\\SuggestionInterface\\.$#"
 			count: 1
-			path: src/Plugin/search_api/backend/SearchApiCoveoBackend.php
+			path: web/modules/custom/coveo/src/Plugin/search_api/backend/SearchApiCoveoBackend.php
 
 		-
 			message: "#^Parameter \\$search of method Drupal\\\\coveo\\\\Plugin\\\\search_api\\\\backend\\\\SearchApiCoveoBackend\\:\\:getAutocompleteSuggestions\\(\\) has invalid type Drupal\\\\search_api_autocomplete\\\\SearchInterface\\.$#"
 			count: 2
-			path: src/Plugin/search_api/backend/SearchApiCoveoBackend.php
+			path: web/modules/custom/coveo/src/Plugin/search_api/backend/SearchApiCoveoBackend.php

But if you push that to drupal.org the pipeline fails because the files don't exist in the web/modules/custom directory

https://git.drupalcode.org/project/coveo/-/jobs/3226498

You can see this commit fixing the phpstan failures by using the correct paths.
https://git.drupalcode.org/project/coveo/-/commit/5e8d58e755dc1d2663618294a775747236845755

@weitzman
Copy link
Collaborator

weitzman commented Dec 4, 2024

PR welcome

@neclimdul
Copy link
Author

I'm happy to make a MR but I'm not sure how to fix this.

The two options I see are:

  1. Use the base path. Convert the command to run phpstan analyse $DDEV_DOCROOT "$@" and expect users to add this to their phpstan config.

      parameters:
        excludePaths:
          - %currentWorkingDirectory%/web/
          - %currentWorkingDirectory%/vendor/
    

    Benefits:

    1. The baseline will make more sense containing something like src/Foo.php
    2. Minimizes assumptions about the test environment to Drupal being installed in web.

    Drawbacks:

    1. Probably requires a lot of maintainer interaction to change phpstan.neon.
  2. Some how convert ddev to run the command against the module like phpstan analyse $DDEV_DOCROOT/modules/custom/modulename "$@".
    Benefits:

    1. Little to no maintainer interaction.

    Drawbacks:

    1. ddev has to figure out the module name in the custom folder.
    2. The baseline is a bit confusing because it points to files not technically in the repository like web/modules/custom/modulename/src/Foo.php
    3. It is relying on a lot of assumptions and a convention to run tests with the current modules symlinked into a specific directory in web/modules/custom. Probably easy to manually validate today but seems a more complicated convention to maintain long term.

@mxr576
Copy link

mxr576 commented Dec 8, 2024

Option 2 extension, how about looping through every directory in web/modules/custom, opening the directories and running phpstan in them? That would eliminate the hardcoded module name problem and also the path issue in phpstan-baseline.neon.

@neclimdul
Copy link
Author

That seems like it would be leaning into the Drupalism while simultaneously making it impossible for the ddev command to generate the baseline since its being run multiple times instead of a single process.

1 seems like the better use of the tool if I'm honest because it keeps the implementation simple and lets PHPstan handle the complexity the way it normally would for any other project.

@mrmishmash
Copy link

I've found that adding this to phpstan.neon:

  excludePaths:
  	- %currentWorkingDirectory%/web/
  	- %currentWorkingDirectory%/vendor/

And then modifying the phpstan command to analyze files in the basedir:

BASE_DIR=$(dirname "$DDEV_DOCROOT")
phpstan analyse $BASE_DIR "$@"

Works in my case. Thanks to @neclimdul for these suggestions.

Not sure how this issue hasn't been brought up more times, I found it quite surprising that phpstan with a baseline did not work. Either you have it fixed for local work and it fails on Drupal CI or you have it fixed for Drupal CI and it fails locally, making it impossible to invoke pre-commit hooks.

Though this all goes away if you don't have a baseline and have your codebase fixed up so maybe that's the reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants