povils / phpmnd

PHP Magic Number Detector
MIT License
554 stars 46 forks source link

Add support to more output formats #181

Closed llaville closed 4 months ago

llaville commented 5 months ago

Hello,

As author of the SARIF PHP binding solution https://github.com/llaville/sarif-php-sdk I would like to propose a SARIF support.

For audience that don't know yet what is SARIF (Static Analysis Results Interchange Format), I suggest to read :

But my proposal is not limited to SARIF. With it we could add support to other formats not yet supported.

That will include, for example :

And whatever else we will need !

Now that introduction is opened, here is in details my proposal !

A Povils\PHPMND\Printer\Custom class that implements the standard Povils\PHPMND\Printer\Printer contract and inspired by https://github.com/phpmd/phpmd/blob/2.15.0/src/main/php/PHPMD/TextUI/CommandLineOptions.php#L780

CLI options will be only :

  -o, --output=OUTPUT                  Generate an output to the specified path [default: "php://stdout"]
      --format=FORMAT                  Format of the report [default: "console"]

And remove old --xml-ouptut option

Here are some use cases :

Console (default output)

No change because this is the default. (Option to write/redirect results to a file with --output option)

SARIF format

bin/phpmnd /path/to/source --format SarifPrinter
source code ```php

[!NOTE] no implemention here because I propose to add support to my project as I did since release 1.2.0 for at least 3 other PHP linters : PHPCS, PHPLint, PHPStan

Checkstyle format

bin/phpmnd /path/to/source --format CheckstylePrinter

Now a version of CheckStyle implementation we can have :

source code ```php groupDetectionResultPerFile($detections); $document = new DOMDocument('1.0', 'UTF-8'); $document->formatOutput = true; $rootElement = $document->createElement('checkstyle'); $document->appendChild($rootElement); foreach ($groupedList as $path => $detectionResults) { $fileNode = $document->createElement('file'); $fileNode->setAttribute('name', $path); $rootElement->appendChild($fileNode); foreach ($detectionResults as $detectionResult) { $snippet = $this->getSnippet( $detectionResult->getFile()->getContents(), $detectionResult->getLine(), $detectionResult->getValue() ); $errorNode = $document->createElement('error'); $errorNode->setAttribute('line', (string) $detectionResult->getLine()); $errorNode->setAttribute('column', (string) $snippet['col']); $errorNode->setAttribute('severity', 'error'); $errorNode->setAttribute( 'message', sprintf('Magic Number: %s', $detectionResult->getValue()) ); $fileNode->appendChild($errorNode); } $rootElement->appendChild($fileNode); } $xmlString = $document->saveXML(); if (is_string($xmlString)) { $output->write($xmlString); } } /** * @param array $list * * @return array */ private function groupDetectionResultPerFile(array $list): array { $result = []; foreach ($list as $detectionResult) { $result[$detectionResult->getFile()->getRelativePathname()][] = $detectionResult; } return $result; } /** * Get the snippet and information about it * * @param int|string $text * * @return array */ private function getSnippet(string $content, int $line, $text): array { $content = str_replace(["\r\n", "\r"], "\n", $content); $lines = explode("\n", $content); $lineContent = array_slice($lines, $line - 1, 1); $lineContent = reset($lineContent); $start = strpos($lineContent, $text . ''); return [ 'snippet' => $lineContent, 'line' => $line, 'magic' => $text, 'col' => $start, ]; } } ```

I'll propose a POC PR (not optimized, because we can do better, but essential are available) and link to this feature request just after.

llaville commented 5 months ago

My SARIF PHP SDK has an upcoming version 1.4.0 that will add PHPMD (PHP Mess Detector) to support SARIF.

Even if PHPMD has already a native support, my version gave more informations, and is not maintained by authors of PHPMD.

This is the goal of my proposal here. No need to maintained a SARIF output format, because I'll do if you accept this POC !

llaville commented 5 months ago

I've just published https://github.com/llaville/sarif-php-sdk/releases/tag/1.4.0 that support PHPMD !

Do you want to be the next one on list ?

llaville commented 4 months ago

Any feedback will be greatly appreciated ?