Skip to content

Allow to configure PHPMD with php or yaml file #1058

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

Open
wants to merge 1 commit into
base: 3.x
Choose a base branch
from

Conversation

kylekatarnls
Copy link
Member

Type: feature
Breaking change: yes

@kylekatarnls kylekatarnls added this to the 3.0.0 milestone Jan 7, 2024
@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch from 67d9440 to 2bedff3 Compare January 7, 2024 14:47
@kylekatarnls
Copy link
Member Author

kylekatarnls commented Jan 7, 2024

Note: the src/conf/phpmd.schema.json file is what allow auto-completion in IDEs:
image

To be automatically applied to phpmd.yml files by IDE, we'll need to submit it in
https://github.com/SchemaStore/schemastore/tree/master/src/schemas/json

Then to be associated to relevant file names in the catalog:
https://github.com/SchemaStore/schemastore/blob/master/src/api/json/catalog.json

@kylekatarnls
Copy link
Member Author

src/test/resources/files/rulesets/phpmd.yml is an example of how it would look to configure rule with a YAML file.

It would work the same by providing JSON file or PHP file returning the same array structure.

Comment on lines +146 to +174
$options = new CommandLineOptions([__FILE__, 'app', 'sarif']);

$args = [__FILE__, 'text', 'design'];
new CommandLineOptions($args);
self::assertSame('cleancode,codesize,controversial,design,naming,unusedcode', $options->getRuleSets());
self::assertSame('sarif', $options->getReportFormat());
self::assertSame('app', $options->getInputPath());

$options = new CommandLineOptions([__FILE__, 'app']);

self::assertSame('cleancode,codesize,controversial,design,naming,unusedcode', $options->getRuleSets());
self::assertSame('text', $options->getReportFormat());
self::assertSame('app', $options->getInputPath());

$options = new CommandLineOptions([__FILE__]);

self::assertSame('cleancode,codesize,controversial,design,naming,unusedcode', $options->getRuleSets());
self::assertSame('text', $options->getReportFormat());
self::assertSame('src', $options->getInputPath());
Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines +377 to +373
0 => [file_exists('src') ? 'src' : '.', 'text', $this->getDefaultConfig()],
1 => ['text', $this->getDefaultConfig()],
2 => [$this->getDefaultConfig()],
default => [],
Copy link
Member Author

Choose a reason for hiding this comment

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

  • input path would fallback to "src" if it's exist, "." else
  • report format would fallback to "text"
  • ruleset would fallback to first config file found by getDefaultConfig, or "all" if no file provided.


$validator = new ArgumentsValidator($hasImplicitArguments, $originalArguments, $arguments);

$this->ruleSets = (string)array_pop($arguments);
$ruleSets = (string)array_pop($arguments);
$this->ruleSets = $ruleSets === 'all' ? InternalRuleSet::getNamesConcatenated() : $ruleSets;
Copy link
Member Author

Choose a reason for hiding this comment

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

"all" would be a shorthand for all internal rulesets from PHPMD:

cleancode,codesize,controversial,design,naming,unusedcode

@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch 2 times, most recently from dabeb46 to 51c1a92 Compare January 7, 2024 17:06
@kylekatarnls kylekatarnls force-pushed the feature/3.x-experiment branch from 799e1db to 5173ebb Compare January 17, 2024 13:27
@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch 2 times, most recently from 0439441 to 7775855 Compare January 17, 2024 15:35
Base automatically changed from feature/3.x-experiment to 3.x April 29, 2024 15:24
@AJenbo
Copy link
Member

AJenbo commented May 11, 2024

Not using XML is a big improvement in my book. I prefer the PHP option personally.

@kylekatarnls I think now is a good point to rebase this so it's ready for merging.

@kylekatarnls kylekatarnls changed the title [Tentative] Allow to configure PHPMD with php or yaml file Allow to configure PHPMD with php or yaml file May 16, 2024
@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch 3 times, most recently from c7d924c to 2be8831 Compare May 16, 2024 17:45
Copy link

codecov bot commented May 16, 2024

Codecov Report

Attention: Patch coverage is 93.08176% with 11 lines in your changes missing coverage. Please review.

Project coverage is 91.75%. Comparing base (3aef909) to head (c9dd2f4).
Report is 37 commits behind head on 3.x.

Files with missing lines Patch % Lines
src/main/php/PHPMD/RuleSetFactory.php 92.00% 10 Missing ⚠️
src/main/php/PHPMD/TextUI/CommandLineOptions.php 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##                3.x    #1058   +/-   ##
=========================================
  Coverage     91.75%   91.75%           
- Complexity     1275     1297   +22     
=========================================
  Files           107      109    +2     
  Lines          3370     3443   +73     
=========================================
+ Hits           3092     3159   +67     
- Misses          278      284    +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch 4 times, most recently from df1b444 to 2585b4e Compare May 17, 2024 00:04
@kylekatarnls kylekatarnls marked this pull request as ready for review May 17, 2024 00:17
@kylekatarnls kylekatarnls requested a review from AJenbo May 17, 2024 00:17
@kylekatarnls kylekatarnls requested review from ravage84 and tvbeek May 17, 2024 00:17
AJenbo
AJenbo previously approved these changes May 17, 2024
@@ -32,31 +36,18 @@ class RuleSetFactory
/**
Copy link
Member

@AJenbo AJenbo May 17, 2024

Choose a reason for hiding this comment

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

This calls is getting a bit heavy on pulling out mixed variables and casting them to various types. This is likely going to trigger a lot of unsafe operations on higher PHPStan levels.

@AJenbo
Copy link
Member

AJenbo commented May 17, 2024

Lots of things going on in one PR, most of it is nice, but a bit hard to review and comment on individual things with it all there.

@kylekatarnls
Copy link
Member Author

kylekatarnls commented May 17, 2024

In theory bcmul can go even above 64 bits, but I wonder if it has a real interest in practice for npath (and also why it would be the only one using big number). BTW it also possible to go above by using float (which is automatic in PHP), it just loose a bit of precision but I'm not sure it's an actual problem, if you have billion npath, you probably care about order of magnitude, not an exact value.

@AJenbo
Copy link
Member

AJenbo commented May 17, 2024

i wold normally just use it if decimal fractional rounding is important, I have a hard time imagining the need for values that high.

@kylekatarnls
Copy link
Member Author

Lots of things going on in one PR, most of it is nice, but a bit hard to review and comment on individual things with it all there.

I'm also unsatisfied about how it growth after re-basing. I will split.

@@ -109,8 +112,6 @@ public function createRuleSets(string $ruleSetFileNames): array
* Creates a single rule-set instance for the given filename or identifier.
*
* @param string $ruleSetOrFileName The rule-set filename or identifier.
* @throws RuleSetNotFoundException
* @throws RuntimeException
*/
Copy link
Member Author

Choose a reason for hiding this comment

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

Likely just lost in rebasing

Suggested change
*/
* @throws RuleSetNotFoundException
* @throws RuntimeException
*/

$fileName = $file;
} elseif (is_readable($ruleSetFolderPath . DIRECTORY_SEPARATOR . $file)) {
$fileName = $ruleSetFolderPath . DIRECTORY_SEPARATOR . $file;
$ruleNodeFile = (string )$ruleNode['file'];
Copy link
Member Author

Choose a reason for hiding this comment

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

Suggested change
$ruleNodeFile = (string )$ruleNode['file'];
$ruleNodeFile = (string) $ruleNode['file'];

@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch 5 times, most recently from c88ef0c to e8a5290 Compare September 8, 2024 22:26
@kylekatarnls
Copy link
Member Author

Rebased, I also extracted PHPStan in a dedicated job. Few things are broken here after the rebase, I'll have to check.

@AJenbo
Copy link
Member

AJenbo commented Sep 8, 2024

Some of the reported issues are addressed by #1202

@kylekatarnls kylekatarnls force-pushed the feature/multi-format-support branch from 6f9319c to c9dd2f4 Compare September 11, 2024 08:31
@@ -56,7 +56,9 @@ public function __construct(
* The magic call method is used to pipe requests from rules direct
* to the underlying PDepend AST node.
*
* @param array<mixed> $args
* @param list<mixed> $args
* @throws BadMethodCallException When the underlying PDepend node
Copy link
Member

Choose a reason for hiding this comment

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

Since it's not possible for the analyzer to figure out what function can throw this exception you can use an overwrite to indicate what line can throw it:

        /** @throws BadMethodCallException */
        return $this->node->{$name}(...$args);

Copy link
Member

@tvbeek tvbeek left a comment

Choose a reason for hiding this comment

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

Nice job 👍

We need to have an update for the documentation but I suggest it can be a good idea to create a new PR for that.

{
foreach ($ruleSetNode->exclude as $exclude) {
if ($rule->getName() === (string) $exclude['name']) {
$excludes = (is_object($ruleSetNode) ? ($ruleSetNode->exclude ?? null) : null)
Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking if it isn't an improvement to create a new method to get the excludes? I see that I need to read it multiple times to see if it is correct.

But that can be a personal style.

@@ -39,7 +39,8 @@
"php": "^8.1",
"ext-xml": "*",
"composer/xdebug-handler": "^3.0",
"pdepend/pdepend": "3.x-dev#c21f168eccda0175040c9425b9b7c330176d60c4"
"pdepend/pdepend": "3.x-dev#c21f168eccda0175040c9425b9b7c330176d60c4",
"symfony/yaml": "^5.4.31 || ^6.0 || ^7.0"
Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking, this is only needed if you use a yaml file. Is it an option to add this to the suggest and check the existence of this package(or the class) in the function that use it?

On that way we lower the number of dependencies that isn't needed for all users.

Copy link
Member Author

Choose a reason for hiding this comment

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

It depends if we plan to recommend it as the default in our documentation.

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

Successfully merging this pull request may close these issues.

4 participants