Skip to content

Commit

Permalink
Merge pull request #84 from BackEndTea/feature/warning
Browse files Browse the repository at this point in the history
Allow to lint for warnings
  • Loading branch information
overtrue authored Oct 2, 2020
2 parents 36f3726 + 8ea28ba commit 11f1ac8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 5 deletions.
1 change: 1 addition & 0 deletions .phplint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ extensions:
- php
exclude:
- vendor
warning: true
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Options:
--cache=CACHE Path to the cache file.
--json[=JSON] Output JSON results to a file.
--xml[=XML] Output JUnit XML results to a file.
-w, --warning Also show warnings
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
Expand Down Expand Up @@ -72,6 +73,7 @@ extensions:
- php
exclude:
- vendor
warning: false
```
```shell
Expand All @@ -82,6 +84,14 @@ By default, the command will read configuration from file `.phplint.yml` of path

If you want to disable the config file, you can add option `--no-configuration`.

### Warnings

Not all linting problems are errors, PHP also has warnings, for example when using a `continue` statement within a
`switch` `case`. By default these errors are not reported, but you can turn this on with the `warning` cli flag, or
by setting the `warning` to true in the configuration.



### Program

```php
Expand All @@ -90,8 +100,9 @@ use Overtrue\PHPLint\Linter;
$path = __DIR__ .'/app';
$exclude = ['vendor'];
$extensions = ['php'];
$warnings = true;

$linter = new Linter($path, $exclude, $extensions);
$linter = new Linter($path, $exclude, $extensions, $warnings);

// get errors
$errors = $linter->lint();
Expand Down
32 changes: 29 additions & 3 deletions src/Command/LintCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LintCommand extends Command
'path' => '.',
'exclude' => [],
'extensions' => ['php'],
'warning' => false
];

/**
Expand Down Expand Up @@ -126,6 +127,12 @@ protected function configure()
null,
InputOption::VALUE_OPTIONAL,
'Path to store JUnit XML results.'
)
->addOption(
'warning',
'w',
InputOption::VALUE_NONE,
'Also show warnings'
);
}

Expand Down Expand Up @@ -177,7 +184,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$output->writeln('Options: ' . json_encode($options) . "\n");
}

$linter = new Linter($options['path'], $options['exclude'], $options['extensions']);
$linter = new Linter($options['path'], $options['exclude'], $options['extensions'], $options['warning']);
$linter->setProcessLimit($options['jobs']);

if (!empty($options['cache'])) {
Expand Down Expand Up @@ -304,13 +311,29 @@ protected function executeLint($linter, $input, $output, $fileCount)

if ($verbosity >= OutputInterface::VERBOSITY_VERBOSE) {
$filename = str_pad(" {$i}: " . $file->getRelativePathname(), $maxColumns - 10, ' ', \STR_PAD_RIGHT);
$status = \str_pad(('ok' === $status ? '<info>OK</info>' : '<error>Error</error>'), 20, ' ', \STR_PAD_RIGHT);
if ($status === 'ok') {
$status = '<info>OK</info>';
} elseif ($status === 'error') {
$status = '<error>Error</error>';
} else {
$status = '<error>Warning</error>';
}

$status = \str_pad($status, 20, ' ', \STR_PAD_RIGHT);
$output->writeln(\sprintf("%s\t%s\t%s", $filename, $status, $process));
} else {
if ($i && 0 === $i % $maxColumns) {
$output->writeln($process);
}
$output->write('ok' === $status ? '<info>.</info>' : '<error>E</error>');
if ($status === 'ok') {
$status = '<info>.</info>';
} elseif ($status === 'error') {
$status = '<error>E</error>';
} else {
$status = '<error>W</error>';
}

$output->write($status);
}
++$i;
});
Expand Down Expand Up @@ -404,6 +427,9 @@ protected function mergeOptions()
$options = $this->input->getOptions();
$options['path'] = $this->input->getArgument('path');
$options['cache'] = $this->input->getOption('cache');
if ($options['warning'] === false) {
unset($options['warning']);
}

$config = [];

Expand Down
12 changes: 11 additions & 1 deletion src/Linter.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,27 @@ class Linter
*/
private $processLimit = 5;

/**
* @var bool
*/
private $warning;

/**
* Constructor.
*
* @param string|array $path
* @param array $excludes
* @param array $extensions
* @param bool $warning
*/
public function __construct($path, array $excludes = [], array $extensions = ['php'])
public function __construct($path, array $excludes = [], array $extensions = ['php'], $warning = false)
{
$this->path = (array)$path;
$this->excludes = $excludes;
$this->extensions = \array_map(function ($extension) {
return \sprintf('*.%s', \ltrim($extension, '.'));
}, $extensions);
$this->warning = $warning;
}

/**
Expand Down Expand Up @@ -124,6 +131,9 @@ public function lint($files = [], $cache = true)
if ($lint->hasSyntaxError()) {
$processCallback('error', $item['file']);
$errors[$filename] = array_merge(['file' => $filename, 'file_name' => $item['relativePath']], $lint->getSyntaxError());
} elseif ($this->warning && $lint->hasSyntaxWarning()) {
$processCallback('warning', $item['file']);
$errors[$filename] = array_merge(['file' => $filename, 'file_name' => $item['relativePath']], $lint->getSyntaxWarning());
} else {
$newCache[$item['relativePath']] = md5_file($filename);
$processCallback('ok', $item['file']);
Expand Down
52 changes: 52 additions & 0 deletions src/Process/Lint.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,56 @@ public function parseError($message)
'line' => $matched ? abs($match['line']) : 0,
];
}

/**
* @return bool
*/
public function hasSyntaxWarning()
{
$output = trim($this->getOutput());

if (defined('HHVM_VERSION') && empty($output)) {
return false;
}


return false !== strpos($output, 'Warning: ');
}

/**
* @return bool|array
*/
public function getSyntaxWarning()
{
if ($this->hasSyntaxWarning()) {
$out = explode("\n", trim($this->getOutput()));

return $this->parseWarning(array_shift($out));
}

return false;
}

/**
* Parse error message.
*
* @param string $message
*
* @return array
*/
public function parseWarning($message)
{
$pattern = '/^(PHP\s+)?Warning:\s*\s*?(?<error>.+?)\s+in\s+.+?\s*line\s+(?<line>\d+)/';

$matched = preg_match($pattern, $message, $match);

if (empty($message)) {
$message = 'Unknown';
}

return [
'error' => $matched ? "{$match['error']} in line {$match['line']}" : $message,
'line' => $matched ? abs($match['line']) : 0,
];
}
}

0 comments on commit 11f1ac8

Please sign in to comment.