Part of #2571965: [meta] Fix PHP coding standards in core.

Approach

We are testing coding standards with PHP CodeSniffer, using the Drupal coding standards from the Coder module. Both of these packages are not installed in Drupal core. We need to do a couple of steps in order to download and configure them so we can run a coding standards check.

Step 1: Add the coding standard to the whitelist

Every coding standard is identified by a "sniff". For example, an imaginary coding standard that would require all llamas to be placed inside a square bracket fence would be called the "Drupal.AnimalControlStructure.BracketedFence sniff". There are dozens of such coding standards, and to make the work easier we have started by only whitelisting the sniffs that pass. For the moment all coding standards that are not yet fixed are simply skipped during the test.

Open the file core/phpcs.xml.dist and add a line for the sniff of this ticket. The sniff name is in the issue title. Make sure your patch will include the addition of this line.

Step 2: Run the test

Now you are ready to run the test! From within the core/ folder, run the following command to launch the test:

$ composer run phpcs -- -p

This takes a couple of minutes. The -p flag shows the progress, so you have a bunch of nice dots to look at while it is running.

Step 3: Fix the failures

When the test is complete it will present you a list of all the files that contain violations of your sniff, and the line numbers where the violations occur. You could fix all of these manually, but thankfully phpcbf can fix many of them. You can call phpcbf like this:

$ composer run phpcbf

This will fix the errors in place or composer will tell you that Script phpcbf --standard=core/phpcs.xml.dist --runtime-set installed_paths $($COMPOSER_BINARY config vendor-dir)/drupal/coder/coder_sniffer -- handling the phpcbf event returned with error code 1 meaning there was no files fixed and you need to fix them manually. You can then make a diff of the changes using git. You can also re-run the test with phpcs and determine if that fixed all of them.

CommentFileSizeAuthor
#2 2937882-2.patch60.91 KBRoSk0
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

RoSk0 created an issue. See original summary.

RoSk0’s picture

Assigned: RoSk0 » Unassigned
Status: Active » Needs review
FileSize
60.91 KB

Fixed.

Status: Needs review » Needs work

The last submitted patch, 2: 2937882-2.patch, failed testing. View results

Ivan Berezhnov’s picture

Issue tags: +CSKyiv18

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Spokje’s picture

Assigned: Unassigned » Spokje

Spokje’s picture

Although the above TestBot errors are easily fixed, I think we should not turn this rule on.

Most important reason:

Both \Drupal\views\ResultRow->_entity and \Drupal\views\ResultRow->_relationship_entities are widely used in Contrib (See here and here).
Changing the name of them would lead to massive breakage.

Other reasons:

This sniff is also covered by sniff Drupal.NamingConventions.ValidVariableName.LowerCamelName.

quietone’s picture

There are two sniff that will do the same task? I am new to this but that seems odd.

Spokje’s picture

AFAIK:

Drupal.Classes.PropertyDeclaration only checks properties and Drupal.NamingConventions.ValidVariableName.LowerCamelName checks all variables for lower CamelCasing.

In the case above both properties start with an underscore, which makes them fail both sniffs.

longwave’s picture

Would it be possible to enable this sniff but skip it for the files we know we can't change for BC reasons (assuming it only triggers on the declaration, and not each time the property is used)? That way we at least can be sure we won't be introducing any new ones to core, even if we can't fix the existing ones right now.

Spokje’s picture

@longwave in #15

Currently the sniff comes back with this:


FILE: D:\htdocs\drupal\core\lib\Drupal\Core\Config\Entity\ConfigEntityBase.php
--------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
--------------------------------------------------------------------------------------------------------------------------------------------------------
 94 | WARNING | Property name "$_core" should not be prefixed with an underscore to indicate visibility
    |         | (Drupal.Classes.PropertyDeclaration.Underscore)
--------------------------------------------------------------------------------------------------------------------------------------------------------


FILE: D:\htdocs\drupal\core\lib\Drupal\Core\DependencyInjection\DependencySerializationTrait.php
------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 2 WARNINGS AFFECTING 2 LINES
------------------------------------------------------------------------------------------------------------------------------------------------------------------
 18 | WARNING | Property name "$_serviceIds" should not be prefixed with an underscore to indicate visibility (Drupal.Classes.PropertyDeclaration.Underscore)
 25 | WARNING | Property name "$_entityStorages" should not be prefixed with an underscore to indicate visibility
    |         | (Drupal.Classes.PropertyDeclaration.Underscore)
------------------------------------------------------------------------------------------------------------------------------------------------------------------


FILE: D:\htdocs\drupal\core\modules\views\src\ResultRow.php
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 2 WARNINGS AFFECTING 2 LINES
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 15 | WARNING | Property name "$_entity" should not be prefixed with an underscore to indicate visibility (Drupal.Classes.PropertyDeclaration.Underscore)
 22 | WARNING | Property name "$_relationship_entities" should not be prefixed with an underscore to indicate visibility
    |         | (Drupal.Classes.PropertyDeclaration.Underscore)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Time: 4 mins, 2.78 secs; Memory: 44MB

So, as far as I can see, it only triggers on the declaration.

Gonna run with the suggestion from @longwave:

Would it be possible to enable this sniff but skip it for the files we know we can't change for BC reasons [snip]? That way we at least can be sure we won't be introducing any new ones to core, even if we can't fix the existing ones right now.

longwave’s picture

If we do go down this route, unsure whether we should skip with the config file or start using phpcs:disable comments in the relevant files. We don't use the comment method for PHPCS yet, but we do have some precedent in that we control cspell with code comments in a few places.

Spokje’s picture

#@longwave:

If we do go down this route, unsure whether we should skip with the config file or start using phpcs:disable comments in the relevant files. We don't use the comment method for PHPCS yet, but we do have some precedent in that we control cspell with code comments in a few places.

Pro phpcs:disable:

- It's clear in the code that it won't be checked.

Con phpcs:disable:
- No precedence, but as @longwave said: It has already be done by cspell (which may or may not have a config file in which to exclude files)
- This would mean another change in sniff Drupal.Commenting.InlineComment.InvalidEndChar to ignore //phpcs:disable. (See similiar issue for cspell: #3207576: Problem with Drupal.Commenting.InlineComment.InvalidEndChar: //cspel)

In #3105950: Fix 'Drupal.Commenting.ClassComment.Missing' coding standard I'm about to introduce excluding files using core/phpcs.xml.dist. (Like this)
Since we already have used core/phpcs.xml.dist to exclude files.

I think this is the time to make a decision which way yo go.

Personally: I'm a fan of the config-file excluding style.

longwave’s picture

I forgot that we do use @codingStandardsIgnoreFile already in a number of places so we do have precedence (and opened #3207968: Replace @codingStandards comments with phpcs: comments to modernise that)

Spokje’s picture

@longwave

Excellent, also we don't have to exclude the full file but some specific lines (https://stackoverflow.com/a/59073074). Let's run with that.

Spokje’s picture

Assigned: Spokje » Unassigned
Status: Needs work » Needs review
Spokje’s picture

Assigned: Unassigned » Spokje
Status: Needs review » Needs work
longwave’s picture

I am not sure we can safely change any of these property names here.

ConfigEntityBase $_core is used for the _core property in exported config entities so I don't think we can easily change that.

$_serviceIds and $_entityStorages are special properties relating to serialization and would need a BC layer for existing serialized objects, we also need to ensure they don't accidentally clash with any existing property name so the underscore helps prevent that.

Spokje’s picture

Looking at @longwave's comment in #25 I think it's better to ignore all three of them.

That way this sniff can go in, and no more of these underscored properties go in.

We could open a follow-up for a BC layer for existing serialized objects for $_serviceIds and $_entityStorages, but that might be too much effort for little result?

longwave’s picture

Personal opinion is it's not worth changing the serialization properties, they are a really special case and so I think they are OK to stay with their rule-breaking names.

Spokje’s picture

I'm with #TeamLongwave on this one.

Spokje’s picture

Assigned: Spokje » Unassigned
Status: Needs work » Needs review
longwave’s picture

Status: Needs review » Reviewed & tested by the community

I think this is the best we can do here, and it will prevent us adding similar properties in the future without making a good case for doing so first.

quietone’s picture

This looks good. My only concern is how to prevent someone in the future wanting to remove the ignore lines. Kind of feels like some of the ignores need to have an @see to a doc page with some explanation and history. Not sure though. Is it worth adding an 'exceptions page' to Coding standards?

Spokje’s picture

I like the idea of an explanation/@see for these cases. Having them right beside the ignore bit makes sure people actually see them.

However (untested at the moment) I fear that adding such a line will trigger some of the other sniffs and a Coder/sniff change is needed.

If I have time later today I will give that a test-test-run (See what I did there...), if anybody beats me to it: Fair play :)

Spokje’s picture

Status: Reviewed & tested by the community » Needs review

Added explanatory comment to each phpcs:ignore

Let's see what TestBot thinks.

If it's green: Let's see what you think => Back to NR.

Spokje’s picture

Also something to consider:

If we like these comments about _why_ phpcs:ignore was needed in the first place, should we create a follow-up to make these comments on the phpcs:ignore that are already in the code.

Also, if we decide to do so, we need to make sure all the sniffs currently in backlog get them.

quietone’s picture

Status: Needs review » Needs work

I applied the MR and looked the changes in PhpSTorm for ConfigEntityBase and ResultRow and found the extra comments informative but it made the code ugly to read. I think we go back to the version that was RTBC in #32. Thanks for making the changes Spokje, I really needed to see it. So, shall we make a single issue follow up for deprecating these class properties. That leaves the code easier on the eye and the details of the properties are not lost.

Spokje’s picture

Thanks @quietone.

I would like more opinions about the comments on phpcs:ignore, I think they're useful and they don't strike me as ugly, but that's in the eye of the beholder I guess.

So, shall we make a single issue follow up for deprecating these class properties. That leaves the code easier on the eye and the details of the properties are not lost.

That's a lot of work to get a BC layer for those in place (See @longwave in #25).

(Again) personally: I don't see that follow-up being worked on in the foreseeable future, since I don't think it will get a lot of priority.

quietone’s picture

Completely agree with getting more eyes on this!

Regarding the followup, I have voiced my opinion, more than once, and accept the wisdom of the group. No problem there from me. Thanks for listening.

Spokje’s picture

@quietone: More than happy to listen to you, most of the time it makes sense :)

Since my wisdom has long left, I'm also more than happy to listen to The Wiser Ones on this one.

longwave’s picture

I prefer the version in #32 as well.

I don't think we explicitly need to say why we are ignoring coding standards in the code here. If someone wants to know the reasoning, they can look at git history for the line in question which will link them back to this issue and they can read the discussion here. I find myself doing this for all sorts of core issues where I want to know why a specific line was added.

We add comments to help other developers; I think coding standards comments are a niche case where most developers won't care why the property is named what it is, they are much more interested in the docblock above which tells them what the property is actually used for.

longwave’s picture

Also as for followups: there is no harm in opening them but as I said in #29 the first three are super-special cases that I think can continue to break the rules. ResultRow is inherited from Views and the naming isn't for any particular reason so we have more chance of fixing this one, but I'm still not sure it's worth the effort.

Spokje’s picture

Status: Needs work » Needs review

Thanks @longwave and @quiteone for the input.

Seeing that I'm outnumbered, I can only do what any self-respecting person would do: Surrender! ;)

New MR should contain only phpcs":ignores and the actual adding of the sniff.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC as per #32, I assume @quietone agrees.

quietone’s picture

Yes, I agree!

Spokje’s picture

  • catch committed e7fadb0 on 9.2.x
    Issue #2937882 by Spokje, RoSk0, longwave, quietone: Fix 'Drupal.Classes...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.2.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.