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

Add PHP lint scripts in npm; Fix lint-staged config #1090

Closed
wants to merge 22 commits into from

Conversation

thelovekesh
Copy link
Member

@thelovekesh thelovekesh commented Mar 26, 2024

Summary

As mentioned by @westonruter in #1012 (comment), for standalone plugins, PHPCS always takes phpcs.xml.dist into account since it is explicitly set to phpcs.xml.dist:

"lint:auto-sizes": "@lint -- ./plugins/auto-sizes --standard=./plugins/auto-sizes/phpcs.xml.dist",

This PR aims to move lint and format scripts from composer.json to package.json scripts to fix the above behavior and running commands from any directory will be easy with npm run.

Also it adds the lint-staged config to run the correct linting commands on staged files based on the correct PHPCS config.

Closes #1089

Relevant technical choices

@thelovekesh thelovekesh added [Type] Enhancement A suggestion for improvement of an existing feature Infrastructure Issues for the overall performance plugin infrastructure no milestone PRs that do not have a defined milestone for release labels Mar 26, 2024
Copy link

github-actions bot commented Mar 26, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: thelovekesh <thelovekesh@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>
Co-authored-by: felixarntz <flixos90@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
plugins.forEach( ( plugin ) => {
const pluginFiles = micromatch(
files,
`**/plugins/${ plugin }/**`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naturally this would need to wait for #1065 to be merged first so that plugin-specific PHPCS rules are checked for test files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently all the tests files adheres to root PHPCS config. Once they are moved to respective plugin directories, they will use plugin specific PHPCS config. In any case this file will remain same so #1065 isn't a blocker for this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's the case. For example, webp-uploads has a plugin-specific translation string:

return new WP_Error( 'image_additional_generated_error', __( 'Additional image was not generated.', 'webp-uploads' ) );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, interesting. At this moment neither of the PHPCS configs are linting the tests/plugins directory as the plugins directory is excluded in the root PHPCS config. So they will be linted once #1065 is merged but no changes will be required in lint staged config. So we can merge it right?

lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
@thelovekesh thelovekesh changed the title Move lint and format scripts from composer to npm Move lint and format scripts to npm; Fix lint-staged config Mar 28, 2024
.github/workflows/php-lint.yml Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Outdated Show resolved Hide resolved
lint-staged.config.js Show resolved Hide resolved
lint-staged.config.js Show resolved Hide resolved
lint-staged.config.js Show resolved Hide resolved
@westonruter
Copy link
Member

Oh, and lint-staged.config.js needs to be added to .gitattributes.

@thelovekesh thelovekesh force-pushed the enhancement/composer-scripts branch 2 times, most recently from 02d3757 to 018aeb6 Compare March 29, 2024 04:48
Copy link
Member

@felixarntz felixarntz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thelovekesh While this PR appears to solve the problem of plugin-specific phpcs.xml files not being respected, I'm not sure about the approach. Why are we moving PHP specific logic to require NPM? That seems a bit backwards to me, especially since it still requires writing a custom script to make it work.

Why not solve it with a PHP solution, which IMO would be more adequate for the problem? If we need to dynamically support plugin-specific phpcs.xml that a developer may have placed, that should be possible in a much less disruptive way by writing a custom PHP script.

By doing that, we'd keep the PHP linting tied to PHP (with NPM merely being a wrapper if anything), and this PR would contain fewer changes.

composer.json Outdated
Comment on lines 28 to 62
"format": "build-cs/vendor/bin/phpcbf --report-summary --report-source",
"lint": "build-cs/vendor/bin/phpcs",
"lint:all": [
"@lint",
"@lint:auto-sizes",
"@lint:dominant-color-images",
"@lint:embed-optimizer",
"@lint:optimization-detective",
"@lint:speculation-rules",
"@lint:webp-uploads"
],
"lint:auto-sizes": "@lint -- ./plugins/auto-sizes --standard=./plugins/auto-sizes/phpcs.xml.dist",
"lint:dominant-color-images": "@lint -- ./plugins/dominant-color-images --standard=./plugins/dominant-color-images/phpcs.xml.dist",
"lint:embed-optimizer": "@lint -- ./plugins/embed-optimizer --standard=./plugins/embed-optimizer/phpcs.xml.dist",
"lint:optimization-detective": "@lint -- ./plugins/optimization-detective --standard=./plugins/optimization-detective/phpcs.xml.dist",
"lint:speculation-rules": "@lint -- ./plugins/speculation-rules --standard=./plugins/speculation-rules/phpcs.xml.dist",
"lint:webp-uploads": "@lint -- ./plugins/webp-uploads --standard=./plugins/webp-uploads/phpcs.xml.dist",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are all of these being removed from here? Similar to @joemcgill's feedback in #1065 (comment), I think PHP based tooling makes sense to be accessible as a Composer script.

Can't this be solved in a PHP way? What's the benefit of moving all of these to NPM?

At a minimum, I think they should remain accessible via composer.json like before, while NPM could effectively be a "wrapper".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixarntz I have added #1065 (comment) in response to #1065 (comment).

At a minimum, I think they should remain accessible via composer.json like before, while NPM could effectively be a "wrapper".

Wouldn't that cause duplication and maintenance burden? Also, I would like to know why we want it on composer specifically while NPM has the same feature, a better build to handle mono-repo use cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thelovekesh There would only be duplication if we have plugin specific scripts in both composer.json and package.json. What I'm proposing though is something like this:

  • We abstract the PHPCS specific call in a custom PHP script that takes the plugin slug as a parameter and takes the potential phpcs.xml from the plugin folder into account.
  • The composer.json can then use that instead of manually calling phpcs with the correct parameters.
  • No changes to package.json would be needed.

PHPCS is PHP specific tooling, and composer.json is the appropriate location to manage such PHP specific tooling.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixarntz Can you please take a look at the new changes? As suggested by @joemcgill, I have added a PHP script to handle linting in plugins and also added an NPM wrapper in composer commands.

@thelovekesh
Copy link
Member Author

Why not solve it with a PHP solution, which IMO would be more adequate for the problem? If we need to dynamically support plugin-specific phpcs.xml that a developer may have placed, that should be possible in a much less disruptive way by writing a custom PHP script.

@felixarntz Why do we need a custom PHP script while NPM has it out of the box? And even if we keep it in composer, the number of commands would be the same. I can also argue about using PHP since all the CLI-based tasks are being handled by NodeJS CLI in this repo.

@felixarntz
Copy link
Member

felixarntz commented Apr 3, 2024

@thelovekesh

Why do we need a custom PHP script while NPM has it out of the box?

My point is that NPM doesn't have it out of the box. If it did, maybe that would be a good reason. But you implemented a custom NPM specific script https://github.com/WordPress/performance/pull/1090/files#diff-29c15f0b5d8d1144bd22153c302cde16c2de092d65b122a618cbdb3023336346 to make it work. At that point, it would be better to solve the problem in PHP and composer.json, as the affected tooling is purely for PHP, and NPM requires a custom script as well.

@westonruter
Copy link
Member

My point is that NPM doesn't have it out of the box. If it did, maybe that would be a good reason. But you implemented a custom NPM specific script https://github.com/WordPress/performance/pull/1090/files#diff-29c15f0b5d8d1144bd22153c302cde16c2de092d65b122a618cbdb3023336346 to make it work.

@felixarntz Actually, no. This is unrelated. This is exclusively to fix the lint-staged issue I mentioned in #1012 (comment). It could be moved into a separate PR.

@felixarntz
Copy link
Member

@westonruter

My point is that NPM doesn't have it out of the box. If it did, maybe that would be a good reason. But you implemented a custom NPM specific script https://github.com/WordPress/performance/pull/1090/files#diff-29c15f0b5d8d1144bd22153c302cde16c2de092d65b122a618cbdb3023336346 to make it work.

@felixarntz Actually, no. This is unrelated. This is exclusively to fix the lint-staged issue I mentioned in #1012 (comment). It could be moved into a separate PR.

Ah I see, thank you for clarifying. Looking at the new package.json scripts, what's preventing us from leaving that in composer.json? Can't we use cd there and run PHPCS that same way?

@thelovekesh
Copy link
Member Author

thelovekesh commented Apr 4, 2024

@felixarntz there are a few scenarios here:

  • The current directory is the root,
  • The current directory is plugins/{some-plugin}
  • Command can handle custom args so we don't need to write our scripts.

By default, the composer works well in the first case. If you run any script from another directory it will ask:

No composer.json in current directory, do you want to use the one at /home/thelovekesh/Desktop/work/wpdev/public/content/plugins/performance? [Y,n]? y
Always want to use the parent dir? Use "composer config --global use-parent-dir true" to change the default.

but we can change this behavior by setting use-parent-dir to true in the global config which I don't think is a good idea.

Coming to the third point, if you pass some custom argument to NPM scripts like npm run foo --bar=baz, NPM CLI will convert it to $npm_config_bar which can be used to determine the value of --bar argument anytime. To achieve this in composer we have to write a custom script. I hope it explains the reason behind choosing NPM over composer.

@felixarntz
Copy link
Member

Thanks for outlining this @thelovekesh.

What I'm curious about is why we need to support running these commands from a specific /plugins/{plugin} directory. Which benefits does developing from a subdirectory like this actually provide? I know @westonruter had mentioned this before somewhere, but I'm unsure why it's useful.

As this is a monorepo, IMO it makes sense to develop from the root folder, just like in any other repo, especially because some tooling is shared, and should be shared to avoid duplication. You probably wouldn't develop or run CI from a specific subdirectory of an individual plugin repository either.

module.exports = {
'**/*.js': ( files ) => `npm run lint-js ${ joinFiles( files ) }`,
'**/*.php': ( files ) => {
const commands = [ 'composer phpstan' ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted by @thelovekesh in #1228 (comment), this intentionally does not include the list of changed files as arguments as PHPStan should be run across the entire codebase.

@thelovekesh thelovekesh force-pushed the enhancement/composer-scripts branch from 0f69d3c to 4cd1af1 Compare May 31, 2024 18:27
Comment on lines +49 to +50
"lint:php:plugins": "cross-env WPP_PLUGIN=$npm_config_plugin php -f bin/phpcs/lint.php",
"lint:php:plugins:fix": "cross-env WPP_FIX=1 WPP_PLUGIN=$npm_config_plugin php -f bin/phpcs/lint.php",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess these need to be updated?

Suggested change
"lint:php:plugins": "cross-env WPP_PLUGIN=$npm_config_plugin php -f bin/phpcs/lint.php",
"lint:php:plugins:fix": "cross-env WPP_FIX=1 WPP_PLUGIN=$npm_config_plugin php -f bin/phpcs/lint.php",
"lint:php:plugins": "cross-env WPP_PLUGIN=$npm_config_plugin php -f tools/phpcs/lint.php",
"lint:php:plugins:fix": "cross-env WPP_FIX=1 WPP_PLUGIN=$npm_config_plugin php -f tools/phpcs/lint.php",

Comment on lines +7 to +17
* $ WPP_PLUGIN=plugin1,plugin2 php bin/phpcs/lint.php
* Would run phpcs on plugin1 and plugin2.
*
* $ WPP_PLUGIN=plugin1,plugin2 WPP_FIX=1 php bin/phpcs/lint.php
* Would run phpcbf on plugin1 and plugin2.
*
* $ php bin/phpcs/lint.php
* Would run phpcs on all plugins.
*
* $ WPP_FIX=1 php bin/phpcs/lint.php
* Would run phpcbf on all plugins.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* $ WPP_PLUGIN=plugin1,plugin2 php bin/phpcs/lint.php
* Would run phpcs on plugin1 and plugin2.
*
* $ WPP_PLUGIN=plugin1,plugin2 WPP_FIX=1 php bin/phpcs/lint.php
* Would run phpcbf on plugin1 and plugin2.
*
* $ php bin/phpcs/lint.php
* Would run phpcs on all plugins.
*
* $ WPP_FIX=1 php bin/phpcs/lint.php
* Would run phpcbf on all plugins.
* $ WPP_PLUGIN=plugin1,plugin2 php tools/phpcs/lint.php
* Would run phpcs on plugin1 and plugin2.
*
* $ WPP_PLUGIN=plugin1,plugin2 WPP_FIX=1 php tools/phpcs/lint.php
* Would run phpcbf on plugin1 and plugin2.
*
* $ php tools/phpcs/lint.php
* Would run phpcs on all plugins.
*
* $ WPP_FIX=1 php tools/phpcs/lint.php
* Would run phpcbf on all plugins.

@@ -22,6 +23,7 @@ on:
- 'phpstan.neon.dist'
- 'composer.json'
- 'composer.lock'
- 'bin/phpcs'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed now that the script ends in .php (tools/phpcs/lint.php)?

Suggested change
- 'bin/phpcs'

@@ -13,6 +13,7 @@ on:
- 'phpstan.neon.dist'
- 'composer.json'
- 'composer.lock'
- 'bin/phpcs'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed now that the script ends in .php (tools/phpcs/lint.php)?

Suggested change
- 'bin/phpcs'

@thelovekesh
Copy link
Member Author

@westonruter I think we need to split this PR into two parts as well, similar to what we did in #1065 (comment)

  1. Fix lint-staged per plugin
  2. Running PHPCS within plugins.

For this PR, the main blocker was the second part. I think we can discuss that a little more and then raise a PR.

@thelovekesh
Copy link
Member Author

Closing in favor of the above comment. cc @westonruter

@thelovekesh thelovekesh deleted the enhancement/composer-scripts branch June 3, 2024 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Infrastructure Issues for the overall performance plugin infrastructure no milestone PRs that do not have a defined milestone for release [Type] Enhancement A suggestion for improvement of an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants