Skip to content

Commit

Permalink
implement new feature #186
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed May 3, 2024
1 parent 97a67ed commit e6501d5
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changes/unreleased/Added-20240503-034646.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Added
body: '[#186](https://github.com/overtrue/phplint/issues/186) : Add SARIF output format'
time: 2024-05-03T03:46:46.579045338Z
3 changes: 2 additions & 1 deletion .phplint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ warning: true
memory-limit: -1
no-cache: false
log-json: false
log-junit: false
log-junit: false
log-sarif: false
12 changes: 12 additions & 0 deletions src/Command/ConfigureCommandTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ protected function configureCommand(Command $command): void
InputOption::VALUE_OPTIONAL,
'Log scan results in JUnit XML format to file (<comment>default: ' . OptionDefinition::DEFAULT_STANDARD_OUTPUT_LABEL . '</comment>)'
)
->addOption(
'log-sarif',
null,
InputOption::VALUE_OPTIONAL,
'Log scan results in SARIF format to file (<comment>default: ' . OptionDefinition::DEFAULT_STANDARD_OUTPUT_LABEL . '</comment>)'
)
->addOption(
'sarif-converter',
null,
InputOption::VALUE_OPTIONAL,
'SARIF class converter (<comment>default: ' . OptionDefinition::DEFAULT_SARIF_CONVERTER_CLASS . '</comment>)'
)
->addOption(
'warning',
'w',
Expand Down
5 changes: 5 additions & 0 deletions src/Configuration/AbstractOptionsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public function __construct(InputInterface $input, array $configuration = [])
OptionDefinition::NO_PROGRESS => false,
OptionDefinition::LOG_JSON => false,
OptionDefinition::LOG_JUNIT => false,
OptionDefinition::LOG_SARIF => false,
OptionDefinition::SARIF_CONVERTER => '\Bartlett\Sarif\Converter\PhpLintConverter',
OptionDefinition::WARNING => false,
OptionDefinition::OPTION_MEMORY_LIMIT => ini_get('memory_limit'),
OptionDefinition::IGNORE_EXIT_CODE => false,
Expand Down Expand Up @@ -82,6 +84,7 @@ public function __construct(InputInterface $input, array $configuration = [])
$names = [
OptionDefinition::LOG_JSON,
OptionDefinition::LOG_JUNIT,
OptionDefinition::LOG_SARIF,
];
foreach ($names as $name) {
if ('' === $options[$name]) {
Expand Down Expand Up @@ -111,6 +114,8 @@ public function __construct(InputInterface $input, array $configuration = [])
OptionDefinition::PROGRESS,
OptionDefinition::LOG_JSON,
OptionDefinition::LOG_JUNIT,
OptionDefinition::LOG_SARIF,
OptionDefinition::SARIF_CONVERTER,
OptionDefinition::WARNING,
OptionDefinition::OPTION_MEMORY_LIMIT,
OptionDefinition::IGNORE_EXIT_CODE,
Expand Down
3 changes: 3 additions & 0 deletions src/Configuration/OptionDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ interface OptionDefinition
public const NO_PROGRESS = 'no-progress';
public const LOG_JSON = 'log-json';
public const LOG_JUNIT = 'log-junit';
public const LOG_SARIF = 'log-sarif';
public const SARIF_CONVERTER = 'sarif-converter';
public const IGNORE_EXIT_CODE = 'ignore-exit-code';

public const DEFAULT_JOBS = 5;
Expand All @@ -44,4 +46,5 @@ interface OptionDefinition
public const DEFAULT_PROGRESS_WIDGET = 'printer';
public const DEFAULT_STANDARD_OUTPUT_LABEL = 'standard output';
public const DEFAULT_STANDARD_OUTPUT = 'php://stdout';
public const DEFAULT_SARIF_CONVERTER_CLASS = 'Bartlett\Sarif\Converter\PhpLintConverter';
}
3 changes: 3 additions & 0 deletions src/Configuration/OptionsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ protected function configureOptions(OptionsResolver $resolver): void
OptionDefinition::NO_PROGRESS => 'bool',
OptionDefinition::LOG_JSON => ['bool', 'string'],
OptionDefinition::LOG_JUNIT => ['bool', 'string'],
OptionDefinition::LOG_SARIF => ['bool', 'string'],
OptionDefinition::SARIF_CONVERTER => ['null', 'string'],
OptionDefinition::WARNING => 'bool',
OptionDefinition::OPTION_MEMORY_LIMIT => ['int', 'string'],
OptionDefinition::IGNORE_EXIT_CODE => 'bool',
Expand Down Expand Up @@ -90,6 +92,7 @@ protected function configureOptions(OptionsResolver $resolver): void
$names = [
OptionDefinition::LOG_JSON,
OptionDefinition::LOG_JUNIT,
OptionDefinition::LOG_SARIF,
];
foreach ($names as $name) {
$resolver->setNormalizer($name, Closure::fromCallable([$this, 'logNormalizer']));
Expand Down
16 changes: 15 additions & 1 deletion src/Extension/OutputFormat.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@

namespace Overtrue\PHPLint\Extension;

use Bartlett\Sarif\Converter\ConverterInterface;
use Overtrue\PHPLint\Command\LintCommand;
use Overtrue\PHPLint\Configuration\ConsoleOptionsResolver;
use Overtrue\PHPLint\Configuration\FileOptionsResolver;
use Overtrue\PHPLint\Configuration\OptionDefinition;
use Overtrue\PHPLint\Event\AfterCheckingEvent;
use Overtrue\PHPLint\Event\AfterCheckingInterface;
use Overtrue\PHPLint\Output\ChainOutput;
use Overtrue\PHPLint\Output\ConsoleOutput;
use Overtrue\PHPLint\Output\JsonOutput;
use Overtrue\PHPLint\Output\JunitOutput;
use Overtrue\PHPLint\Output\SarifOutput;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

use function class_exists;

/**
* @author Laurent Laville
* @since Release 9.0.0
Expand Down Expand Up @@ -70,6 +73,17 @@ public function initFormat(ConsoleCommandEvent $event): void
$this->handlers[] = new JsonOutput(fopen($filename, 'w'));
} elseif (OptionDefinition::LOG_JUNIT == $name) {
$this->handlers[] = new JunitOutput(fopen($filename, 'w'));
} elseif (OptionDefinition::LOG_SARIF == $name) {
$sarifHandler = new SarifOutput(fopen($filename, 'w'));

$sarifConverterClass = $configResolver->getOption(OptionDefinition::SARIF_CONVERTER);
if (class_exists($sarifConverterClass)) {
$converter = new $sarifConverterClass();
if ($converter instanceof ConverterInterface) {
$sarifHandler->setConverter($converter);
}
}
$this->handlers[] = $sarifHandler;
}
}
}
Expand Down
45 changes: 45 additions & 0 deletions src/Output/SarifOutput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/*
* This file is part of the overtrue/phplint package
*
* (c) overtrue
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Overtrue\PHPLint\Output;

use Bartlett\Sarif\Converter\ConverterInterface;
use Bartlett\Sarif\Converter\PhpLintConverter;

use Symfony\Component\Console\Output\StreamOutput;

use function fclose;

/**
* @author Laurent Laville
* @since Release 9.2.0
*/
class SarifOutput extends StreamOutput implements OutputInterface
{
private ConverterInterface $converter;

public function setConverter(ConverterInterface $converter): void
{
$this->converter = $converter;
}

public function format(LinterOutput $results): void
{
$converter = $this->converter ?? new PhpLintConverter();

$jsonString = $converter->format($results); // @phpstan-ignore-line

$this->write($jsonString, true);
fclose($this->getStream());
}
}

0 comments on commit e6501d5

Please sign in to comment.