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 GitHub Actions Output Formatter #305

Merged
merged 13 commits into from
Jun 5, 2020
4 changes: 4 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use SensioLabs\Deptrac\DependencyEmitter\InheritanceDependencyEmitter;
use SensioLabs\Deptrac\FileResolver;
use SensioLabs\Deptrac\OutputFormatter\ConsoleOutputFormatter;
use SensioLabs\Deptrac\OutputFormatter\GithubActionsOutputFormatter;
use SensioLabs\Deptrac\OutputFormatter\GraphVizOutputFormatter;
use SensioLabs\Deptrac\OutputFormatter\JUnitOutputFormatter;
use SensioLabs\Deptrac\OutputFormatter\XMLOutputFormatter;
Expand Down Expand Up @@ -107,6 +108,9 @@
$services
->set(ConsoleOutputFormatter::class)
->tag('output_formatter');
$services
->set(GithubActionsOutputFormatter::class)
->tag('output_formatter');
$services
->set(GraphVizOutputFormatter::class)
->tag('output_formatter');
Expand Down
70 changes: 70 additions & 0 deletions src/OutputFormatter/GithubActionsOutputFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace SensioLabs\Deptrac\OutputFormatter;

use SensioLabs\Deptrac\RulesetEngine\Context;
use SensioLabs\Deptrac\RulesetEngine\Rule;
use SensioLabs\Deptrac\RulesetEngine\SkippedViolation;
use SensioLabs\Deptrac\RulesetEngine\Violation;
use Symfony\Component\Console\Output\OutputInterface;

class GithubActionsOutputFormatter implements OutputFormatterInterface
{
/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'github-actions';
}

/**
* {@inheritdoc}
*/
public function configureOptions(): array
{
return [];
}

public function enabledByDefault(): bool
{
return false;
}

/**
* {@inheritdoc}
*/
public function finish(Context $context, OutputInterface $output, OutputFormatterInput $outputFormatterInput): void
{
foreach ($context->all() as $rule) {
if (!$rule instanceof Violation && !$rule instanceof SkippedViolation) {
continue;
}

$dependency = $rule->getDependency();
$output->writeln(sprintf(
'::%s file=%s,line=%s::%s%s must not depend on %s (%s on %s)',
$this->determineLogLevel($rule),
$dependency->getFileOccurrence()->getFilepath(),
$dependency->getFileOccurrence()->getLine(),
$rule instanceof SkippedViolation ? '[SKIPPED] ' : '',
$dependency->getClassLikeNameA()->toString(),
$dependency->getClassLikeNameB()->toString(),
$rule->getLayerA(),
$rule->getLayerB()
));
}
}

public function determineLogLevel(Rule $rule): string
{
switch (get_class($rule)) {
case Violation::class:
return 'error';
case SkippedViolation::class:
return 'warning';
default:
return 'debug';
}
}
}
77 changes: 77 additions & 0 deletions tests/OutputFormatter/GithubActionsOutputFormatterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Tests\SensioLabs\Deptrac\OutputFormatter;

use PHPUnit\Framework\TestCase;
use SensioLabs\Deptrac\AstRunner\AstMap\ClassLikeName;
use SensioLabs\Deptrac\AstRunner\AstMap\FileOccurrence;
use SensioLabs\Deptrac\Dependency\Dependency;
use SensioLabs\Deptrac\OutputFormatter\GithubActionsOutputFormatter;
use SensioLabs\Deptrac\OutputFormatter\OutputFormatterInput;
use SensioLabs\Deptrac\RulesetEngine\Context;
use SensioLabs\Deptrac\RulesetEngine\SkippedViolation;
use SensioLabs\Deptrac\RulesetEngine\Violation;
use Symfony\Component\Console\Output\BufferedOutput;

class GithubActionsOutputFormatterTest extends TestCase
{
public function testGetName()
{
static::assertEquals('github-actions', (new GithubActionsOutputFormatter())->getName());
}

/**
* @dataProvider finishProvider
*/
public function testFinish(array $rules, string $expectedOutput): void
{
$output = new BufferedOutput();

$formatter = new GithubActionsOutputFormatter();
$formatter->finish(
new Context($rules),
$output,
new OutputFormatterInput([])
);

$o = $output->fetch();
static::assertEquals(
$expectedOutput,
$o
);
}

public function finishProvider()
{
yield 'No Rules, No Output' => [
[],
'',
];

$originalA = ClassLikeName::fromFQCN('\ACME\OriginalA');
$originalB = ClassLikeName::fromFQCN('\ACME\OriginalB');
$originalAOccurrence = FileOccurrence::fromFilepath('/home/testuser/originalA.php', 12);

yield 'Simple Violation' => [
[
new Violation(
new Dependency($originalA, $originalB, $originalAOccurrence),
'LayerA',
'LayerB'
),
],
"::error file=/home/testuser/originalA.php,line=12::ACME\OriginalA must not depend on ACME\OriginalB (LayerA on LayerB)\n",
];

yield 'Skipped Violation' => [
[
new SkippedViolation(
new Dependency($originalA, $originalB, $originalAOccurrence),
'LayerA',
'LayerB'
),
],
"::warning file=/home/testuser/originalA.php,line=12::[SKIPPED] ACME\OriginalA must not depend on ACME\OriginalB (LayerA on LayerB)\n",
];
}
}