Skip to content

Commit

Permalink
Add github reporter (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentLanglet authored Nov 28, 2023
1 parent cdfdccf commit dd28e60
Show file tree
Hide file tree
Showing 18 changed files with 212 additions and 101 deletions.
28 changes: 14 additions & 14 deletions src/Report/Report.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class Report
/**
* @var array<string, list<SniffViolation>>
*/
private array $messagesByFiles = [];
private array $violationsByFile = [];

/**
* @var array<string, true>
Expand All @@ -39,14 +39,14 @@ final class Report
public function __construct(iterable $files)
{
foreach ($files as $file) {
$this->messagesByFiles[$file->getPathname()] = [];
$this->violationsByFile[$file->getPathname()] = [];
}
}

public function addMessage(SniffViolation $sniffViolation): self
public function addViolation(SniffViolation $sniffViolation): self
{
$filename = $sniffViolation->getFilename();
if (!isset($this->messagesByFiles[$filename])) {
if (!isset($this->violationsByFile[$filename])) {
throw new InvalidArgumentException(
sprintf('The file "%s" is not handled by this report.', $filename)
);
Expand All @@ -66,29 +66,29 @@ public function addMessage(SniffViolation $sniffViolation): self
break;
}

$this->messagesByFiles[$filename][] = $sniffViolation;
$this->violationsByFile[$filename][] = $sniffViolation;

return $this;
}

/**
* @return list<SniffViolation>
*/
public function getMessages(string $filename, ?string $level = null): array
public function getFileViolations(string $filename, ?string $level = null): array
{
if (!isset($this->messagesByFiles[$filename])) {
if (!isset($this->violationsByFile[$filename])) {
throw new InvalidArgumentException(
sprintf('The file "%s" is not handled by this report.', $filename)
);
}

if (null === $level) {
return $this->messagesByFiles[$filename];
return $this->violationsByFile[$filename];
}

return array_values(
array_filter(
$this->messagesByFiles[$filename],
$this->violationsByFile[$filename],
static fn (SniffViolation $message): bool => $message->getLevel() >= SniffViolation::getLevelAsInt($level)
)
);
Expand All @@ -97,9 +97,9 @@ public function getMessages(string $filename, ?string $level = null): array
/**
* @return list<SniffViolation>
*/
public function getAllMessages(?string $level = null): array
public function getViolations(?string $level = null): array
{
$messages = array_merge(...array_values($this->messagesByFiles));
$messages = array_merge(...array_values($this->violationsByFile));

if (null === $level) {
return $messages;
Expand All @@ -118,17 +118,17 @@ public function getAllMessages(?string $level = null): array
*/
public function getFiles(): array
{
return array_keys($this->messagesByFiles);
return array_keys($this->violationsByFile);
}

public function getTotalFiles(): int
{
return \count($this->messagesByFiles);
return \count($this->violationsByFile);
}

public function addFixedFile(string $filename): self
{
if (!isset($this->messagesByFiles[$filename])) {
if (!isset($this->violationsByFile[$filename])) {
throw new InvalidArgumentException(
sprintf('The file "%s" is not handled by this report.', $filename)
);
Expand Down
16 changes: 8 additions & 8 deletions src/Report/Reporter/CheckstyleReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ public function display(OutputInterface $output, Report $report, ?string $level
$text .= '<checkstyle>'."\n";

foreach ($report->getFiles() as $file) {
$fileMessages = $report->getMessages($file, $level);
if (0 === \count($fileMessages)) {
$fileViolations = $report->getFileViolations($file, $level);
if (0 === \count($fileViolations)) {
continue;
}

$text .= sprintf(' <file name="%s">', $this->xmlEncode($file))."\n";
foreach ($fileMessages as $message) {
$line = (string) $message->getLine();
$linePosition = (string) $message->getLinePosition();
$sniffName = $message->getSniffName();
foreach ($fileViolations as $violation) {
$line = (string) $violation->getLine();
$linePosition = (string) $violation->getLinePosition();
$sniffName = $violation->getSniffName();

$text .= ' <error';
if ('' !== $line) {
Expand All @@ -37,8 +37,8 @@ public function display(OutputInterface $output, Report $report, ?string $level
if ('' !== $linePosition) {
$text .= ' column="'.$linePosition.'"';
}
$text .= ' severity="'.strtolower(SniffViolation::getLevelAsString($message->getLevel())).'"';
$text .= ' message="'.$this->xmlEncode($message->getMessage()).'"';
$text .= ' severity="'.strtolower(SniffViolation::getLevelAsString($violation->getLevel())).'"';
$text .= ' message="'.$this->xmlEncode($violation->getMessage()).'"';
if (null !== $sniffName) {
$text .= ' source="'.$sniffName.'"';
}
Expand Down
48 changes: 48 additions & 0 deletions src/Report/Reporter/GithubReporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace TwigCsFixer\Report\Reporter;

use Symfony\Component\Console\Output\OutputInterface;
use TwigCsFixer\Report\Report;
use TwigCsFixer\Report\SniffViolation;

/**
* Allow errors to be reported in pull-requests diff when run in a GitHub Action
*
* @see https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
*/
final class GithubReporter implements ReporterInterface
{
public const NAME = 'github';

public function display(OutputInterface $output, Report $report, ?string $level = null): void
{
$violations = $report->getViolations($level);
foreach ($violations as $violation) {
$text = match ($violation->getLevel()) {
SniffViolation::LEVEL_NOTICE => '::notice',
SniffViolation::LEVEL_WARNING => '::warning',
default => '::error',
};

$text .= ' file='.$violation->getFilename();

$line = (string) $violation->getLine();
if ('' !== $line) {
$text .= ',line='.$line;
}
$linePosition = (string) $violation->getLinePosition();
if ('' !== $linePosition) {
$text .= ',col='.$linePosition;
}

// newlines need to be encoded
// see https://github.com/actions/starter-workflows/issues/68#issuecomment-581479448
$text .= '::'.str_replace("\n", '%0A', $violation->getMessage());

$output->writeln($text);
}
}
}
18 changes: 9 additions & 9 deletions src/Report/Reporter/JUnitReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ final class JUnitReporter implements ReporterInterface

public function display(OutputInterface $output, Report $report, ?string $level = null): void
{
$messages = $report->getAllMessages($level);
$totalErrors = \count($messages);
$violations = $report->getViolations($level);
$count = \count($violations);

$text = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$text .= '<testsuites>'."\n";
$text .= ' '.sprintf(
'<testsuite name="Twig CS Fixer" tests="%d" failures="%d">',
max($totalErrors, 1),
$totalErrors
max($count, 1),
$count
)."\n";

if ($totalErrors > 0) {
foreach ($messages as $message) {
if ($count > 0) {
foreach ($violations as $violation) {
$text .= $this->createTestCase(
sprintf('%s:%s', $message->getFilename(), $message->getLine() ?? 0),
strtolower(SniffViolation::getLevelAsString($message->getLevel())),
$message->getMessage()
sprintf('%s:%s', $violation->getFilename(), $violation->getLine() ?? 0),
strtolower(SniffViolation::getLevelAsString($violation->getLevel())),
$violation->getMessage()
);
}
} else {
Expand Down
16 changes: 8 additions & 8 deletions src/Report/Reporter/TextReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ public function display(OutputInterface $output, Report $report, ?string $level
}

foreach ($report->getFiles() as $file) {
$fileMessages = $report->getMessages($file, $level);
if (\count($fileMessages) > 0) {
$fileViolations = $report->getFileViolations($file, $level);
if (\count($fileViolations) > 0) {
$io->text(sprintf('<fg=red>KO</fg=red> %s', $file));
}

$content = @file_get_contents($file);
$rows = [];
foreach ($fileMessages as $message) {
foreach ($fileViolations as $violation) {
$formattedText = [];
$line = $message->getLine();
$line = $violation->getLine();

if (null === $line || false === $content) {
$formattedText[] = $this->formatErrorMessage($message);
$formattedText[] = $this->formatErrorMessage($violation);
} else {
$lines = $this->getContext($content, $line);
foreach ($lines as $no => $code) {
Expand All @@ -58,8 +58,8 @@ public function display(OutputInterface $output, Report $report, ?string $level
wordwrap($code, self::ERROR_LINE_WIDTH)
);

if ($no === $message->getLine()) {
$formattedText[] = $this->formatErrorMessage($message);
if ($no === $violation->getLine()) {
$formattedText[] = $this->formatErrorMessage($violation);
}
}
}
Expand All @@ -68,7 +68,7 @@ public function display(OutputInterface $output, Report $report, ?string $level
$rows[] = new TableSeparator();
}

$messageLevel = SniffViolation::getLevelAsString($message->getLevel());
$messageLevel = SniffViolation::getLevelAsString($violation->getLevel());
$rows[] = [
new TableCell(sprintf('<comment>%s</comment>', $messageLevel)),
implode("\n", $formattedText),
Expand Down
2 changes: 2 additions & 0 deletions src/Report/ReporterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use InvalidArgumentException;
use TwigCsFixer\Report\Reporter\CheckstyleReporter;
use TwigCsFixer\Report\Reporter\GithubReporter;
use TwigCsFixer\Report\Reporter\JUnitReporter;
use TwigCsFixer\Report\Reporter\NullReporter;
use TwigCsFixer\Report\Reporter\ReporterInterface;
Expand All @@ -20,6 +21,7 @@ public function getReporter(string $format = TextReporter::NAME): ReporterInterf
TextReporter::NAME => new TextReporter(),
CheckstyleReporter::NAME => new CheckstyleReporter(),
JUnitReporter::NAME => new JUnitReporter(),
GithubReporter::NAME => new GithubReporter(),
default => throw new InvalidArgumentException(
sprintf('No reporter supports the format "%s".', $format)
),
Expand Down
14 changes: 7 additions & 7 deletions src/Runner/Linter.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
$filePath
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
continue;
}

Expand All @@ -71,7 +71,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
$error->getTemplateLine()
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
continue;
}

Expand All @@ -91,7 +91,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
$filePath
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
continue;
} catch (CannotFixFileException $exception) {
$sniffViolation = new SniffViolation(
Expand All @@ -100,7 +100,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
$filePath
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
}
}

Expand All @@ -116,7 +116,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
$filePath
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
continue;
}
restore_error_handler();
Expand All @@ -129,7 +129,7 @@ public function run(iterable $files, Ruleset $ruleset, ?FixerInterface $fixer =
// Only cache the file if there is no error in order to
// - still see the errors when running again the linter
// - still having the possibility to fix the file
if ([] === $report->getMessages($filePath)) {
if ([] === $report->getFileViolations($filePath)) {
$this->cacheManager->setFile($filePath, $content);
}
}
Expand All @@ -146,7 +146,7 @@ private function setErrorHandler(Report $report, string $file): void
$file
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);

return true;
}, \E_USER_DEPRECATED);
Expand Down
2 changes: 1 addition & 1 deletion src/Sniff/AbstractSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private function addMessage(int $messageType, string $message, Token $token): vo
$this->getName(),
);

$report->addMessage($sniffViolation);
$report->addViolation($sniffViolation);
}

private function addFixableMessage(int $messageType, string $message, Token $token): ?FixerInterface
Expand Down
Loading

0 comments on commit dd28e60

Please sign in to comment.