Skip to content

Commit

Permalink
Merge pull request friendsoftwig#177 from franmomu/display_config
Browse files Browse the repository at this point in the history
Allow configuring `display` from config file and honor config file options
  • Loading branch information
OwlyCode authored Apr 30, 2021
2 parents 1f2439c + f082471 commit fbb854c
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 38 deletions.
13 changes: 13 additions & 0 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Config implements ConfigInterface
private $reporter = 'console';
private $ruleset = Official::class;
private $specificRulesets = [];
private $display = ConfigInterface::DISPLAY_ALL;

public function __construct($name = 'default')
{
Expand Down Expand Up @@ -146,4 +147,16 @@ public function setSpecificRulesets(array $ruleSet): self

return $this;
}

public function getDisplay(): string
{
return $this->display;
}

public function setDisplay(string $display): self
{
$this->display = $display;

return $this;
}
}
7 changes: 5 additions & 2 deletions src/Config/ConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

namespace FriendsOfTwig\Twigcs\Config;

use Symfony\Component\Finder\Finder;

/**
* Special thanks to https://github.com/c33s/twigcs/ which this feature was inspired from.
*
* @method string getDisplay()
*/
interface ConfigInterface
{
public const DISPLAY_BLOCKING = 'blocking';
public const DISPLAY_ALL = 'all';

/**
* Returns the name of the configuration.
*
Expand Down
14 changes: 14 additions & 0 deletions src/Config/ConfigResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ final class ConfigResolver
'exclude' => [],
'config' => null,
'twig-version' => null,
'display' => null,
];

private $finders;
Expand Down Expand Up @@ -171,6 +172,19 @@ public function getSeverityLimit()
}
}

public function getDisplay(): string
{
if (null !== $this->options['display']) {
return $this->options['display'];
}

if (!method_exists($this->getConfig(), 'getDisplay')) {
return ConfigInterface::DISPLAY_ALL;
}

return $this->getConfig()->getDisplay();
}

public function getConfig(): ConfigInterface
{
if (null === $this->config) {
Expand Down
51 changes: 21 additions & 30 deletions src/Console/LintCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace FriendsOfTwig\Twigcs\Console;

use FriendsOfTwig\Twigcs\Config\ConfigInterface;
use FriendsOfTwig\Twigcs\Config\ConfigResolver;
use FriendsOfTwig\Twigcs\TwigPort\Source;
use FriendsOfTwig\Twigcs\TwigPort\SyntaxError;
Expand All @@ -13,7 +14,14 @@

class LintCommand extends ContainerAwareCommand
{
/**
* @deprecated use ConfigInterface::DISPLAY_BLOCKING instead
*/
const DISPLAY_BLOCKING = 'blocking';

/**
* @deprecated use ConfigInterface::DISPLAY_ALL instead
*/
const DISPLAY_ALL = 'all';

public function configure()
Expand All @@ -23,9 +31,9 @@ public function configure()
->addArgument('paths', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'The path to scan for twig files.', null)
->addOption('twig-version', 't', InputOption::VALUE_REQUIRED, 'The major version of twig to use.', 3)
->addOption('exclude', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Excluded folder of path.', [])
->addOption('severity', 's', InputOption::VALUE_REQUIRED, 'The maximum allowed error level.', 'warning')
->addOption('severity', 's', InputOption::VALUE_OPTIONAL, 'The maximum allowed error level.')
->addOption('reporter', 'r', InputOption::VALUE_REQUIRED, 'The reporter to use.')
->addOption('display', 'd', InputOption::VALUE_REQUIRED, 'The violations to display, "'.self::DISPLAY_ALL.'" or "'.self::DISPLAY_BLOCKING.'".', self::DISPLAY_ALL)
->addOption('display', 'd', InputOption::VALUE_OPTIONAL, 'The violations to display, "'.ConfigInterface::DISPLAY_ALL.'" or "'.ConfigInterface::DISPLAY_BLOCKING.'".')
->addOption('throw-syntax-error', 'e', InputOption::VALUE_NONE, 'Throw syntax error when a template contains an invalid token.')
->addOption('ruleset', null, InputOption::VALUE_REQUIRED, 'Ruleset class to use')
->addOption('config', null, InputOption::VALUE_REQUIRED, 'Config file to use', null)
Expand All @@ -44,6 +52,7 @@ public function execute(InputInterface $input, OutputInterface $output)
'ruleset-class-name' => $input->getOption('ruleset'),
'twig-version' => $input->getOption('twig-version'),
'config' => $input->getOption('config'),
'display' => $input->getOption('display'),
]);

$finders = $resolver->getFinders();
Expand Down Expand Up @@ -73,52 +82,34 @@ public function execute(InputInterface $input, OutputInterface $output)
}
}

$violations = $this->filterDisplayViolations($input, $violations);
$severityLimit = $resolver->getSeverityLimit();

$violations = $this->filterDisplayViolations($resolver->getDisplay(), $severityLimit, $violations);

$resolver->getReporter()->report($output, $violations);

return $this->determineExitCode($input, $violations);
return $this->determineExitCode($severityLimit, $violations);
}

private function determineExitCode(InputInterface $input, array $violations): int
private function determineExitCode(int $severityLevel, array $violations): int
{
$limit = $this->getSeverityLimit($input);

foreach ($violations as $violation) {
if ($violation->getSeverity() > $limit) {
if ($violation->getSeverity() > $severityLevel) {
return 1;
}
}

return 0;
}

private function filterDisplayViolations(InputInterface $input, array $violations): array
private function filterDisplayViolations(string $display, int $severityLevel, array $violations): array
{
if (self::DISPLAY_ALL === $input->getOption('display')) {
if (ConfigInterface::DISPLAY_ALL === $display) {
return $violations;
}

$limit = $this->getSeverityLimit($input);

return array_filter($violations, function (Violation $violation) use ($limit) {
return $violation->getSeverity() > $limit;
return array_filter($violations, function (Violation $violation) use ($severityLevel) {
return $violation->getSeverity() > $severityLevel;
});
}

private function getSeverityLimit(InputInterface $input): int
{
switch ($input->getOption('severity')) {
case 'ignore':
return Violation::SEVERITY_IGNORE - 1;
case 'info':
return Violation::SEVERITY_INFO - 1;
case 'warning':
return Violation::SEVERITY_WARNING - 1;
case 'error':
return Violation::SEVERITY_ERROR - 1;
default:
throw new \InvalidArgumentException('Invalid severity limit provided.');
}
}
}
27 changes: 21 additions & 6 deletions tests/Console/LintCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace FriendsOfTwig\Twigcs\Tests\Console;

use FriendsOfTwig\Twigcs\Config\ConfigInterface;
use FriendsOfTwig\Twigcs\Console\LintCommand;
use FriendsOfTwig\Twigcs\Container;
use FriendsOfTwig\Twigcs\TwigPort\SyntaxError;
Expand All @@ -13,7 +14,7 @@ class LintCommandTest extends TestCase
/** @var CommandTester */
private $commandTester;

public function setUp(): void
protected function setUp(): void
{
$container = new Container();
$command = new LintCommand();
Expand Down Expand Up @@ -113,7 +114,7 @@ public function testErrorsOnlyDisplayBlocking()
$this->commandTester->execute([
'paths' => ['tests/data/exclusion/bad/mixed.html.twig'],
'--severity' => 'error',
'--display' => LintCommand::DISPLAY_BLOCKING,
'--display' => ConfigInterface::DISPLAY_BLOCKING,
]);

$output = $this->commandTester->getDisplay();
Expand All @@ -130,7 +131,7 @@ public function testErrorsDisplayAll()
$this->commandTester->execute([
'paths' => ['tests/data/exclusion/bad/mixed.html.twig'],
'--severity' => 'error',
'--display' => LintCommand::DISPLAY_ALL,
'--display' => ConfigInterface::DISPLAY_ALL,
]);

$output = $this->commandTester->getDisplay();
Expand All @@ -148,7 +149,7 @@ public function testSyntaxErrorThrow()
$this->commandTester->execute([
'paths' => ['tests/data/syntax_error/syntax_errors.html.twig'],
'--severity' => 'error',
'--display' => LintCommand::DISPLAY_ALL,
'--display' => ConfigInterface::DISPLAY_ALL,
'--throw-syntax-error' => true,
]);

Expand All @@ -161,7 +162,7 @@ public function testSyntaxErrorNotThrow()
$this->commandTester->execute([
'paths' => ['tests/data/syntax_error/syntax_errors.html.twig'],
'--severity' => 'error',
'--display' => LintCommand::DISPLAY_ALL,
'--display' => ConfigInterface::DISPLAY_ALL,
'--throw-syntax-error' => false,
]);

Expand All @@ -177,7 +178,7 @@ public function testSyntaxErrorNotThrowOmitArgument()
$this->commandTester->execute([
'paths' => ['tests/data/syntax_error/syntax_errors.html.twig'],
'--severity' => 'error',
'--display' => LintCommand::DISPLAY_ALL,
'--display' => ConfigInterface::DISPLAY_ALL,
]);

$output = $this->commandTester->getDisplay();
Expand Down Expand Up @@ -223,6 +224,20 @@ public function testConfigFileWithCliPath()
3 violation(s) found', $output);
}

public function testConfigFileWithDisplayAndSeverity()
{
$this->commandTester->execute([
'--config' => 'tests/data/config/external/.twig_cs_with_display_blocking.dist',
]);

$output = $this->commandTester->getDisplay();
$statusCode = $this->commandTester->getStatusCode();
$this->assertSame($statusCode, 1);
$this->assertStringContainsString('tests/data/syntax_error/syntax_errors.html.twig
l.1 c.17 : ERROR Unexpected "}".
1 violation(s) found', $output);
}

public function testConfigFileSamePathWithRulesetOverrides()
{
chdir(__DIR__.'/../data/config/local');
Expand Down
11 changes: 11 additions & 0 deletions tests/data/config/external/.twig_cs_with_display_blocking.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

$finder = FriendsOfTwig\Twigcs\Finder\TemplateFinder::create()
->in(__DIR__.'/../../syntax_error')
;

return \FriendsOfTwig\Twigcs\Config\Config::create()
->addFinder($finder)
->setSeverity('error')
->setDisplay('blocking')
;

0 comments on commit fbb854c

Please sign in to comment.