Skip to content

Commit 11f1ac8

Browse files
authored
Merge pull request #84 from BackEndTea/feature/warning
Allow to lint for warnings
2 parents 36f3726 + 8ea28ba commit 11f1ac8

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

.phplint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ extensions:
44
- php
55
exclude:
66
- vendor
7+
warning: true

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Options:
4545
--cache=CACHE Path to the cache file.
4646
--json[=JSON] Output JSON results to a file.
4747
--xml[=XML] Output JUnit XML results to a file.
48+
-w, --warning Also show warnings
4849
-h, --help Display this help message
4950
-q, --quiet Do not output any message
5051
-V, --version Display this application version
@@ -72,6 +73,7 @@ extensions:
7273
- php
7374
exclude:
7475
- vendor
76+
warning: false
7577
```
7678
7779
```shell
@@ -82,6 +84,14 @@ By default, the command will read configuration from file `.phplint.yml` of path
8284

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

87+
### Warnings
88+
89+
Not all linting problems are errors, PHP also has warnings, for example when using a `continue` statement within a
90+
`switch` `case`. By default these errors are not reported, but you can turn this on with the `warning` cli flag, or
91+
by setting the `warning` to true in the configuration.
92+
93+
94+
8595
### Program
8696

8797
```php
@@ -90,8 +100,9 @@ use Overtrue\PHPLint\Linter;
90100
$path = __DIR__ .'/app';
91101
$exclude = ['vendor'];
92102
$extensions = ['php'];
103+
$warnings = true;
93104

94-
$linter = new Linter($path, $exclude, $extensions);
105+
$linter = new Linter($path, $exclude, $extensions, $warnings);
95106

96107
// get errors
97108
$errors = $linter->lint();

src/Command/LintCommand.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class LintCommand extends Command
4242
'path' => '.',
4343
'exclude' => [],
4444
'extensions' => ['php'],
45+
'warning' => false
4546
];
4647

4748
/**
@@ -126,6 +127,12 @@ protected function configure()
126127
null,
127128
InputOption::VALUE_OPTIONAL,
128129
'Path to store JUnit XML results.'
130+
)
131+
->addOption(
132+
'warning',
133+
'w',
134+
InputOption::VALUE_NONE,
135+
'Also show warnings'
129136
);
130137
}
131138

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

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

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

305312
if ($verbosity >= OutputInterface::VERBOSITY_VERBOSE) {
306313
$filename = str_pad(" {$i}: " . $file->getRelativePathname(), $maxColumns - 10, ' ', \STR_PAD_RIGHT);
307-
$status = \str_pad(('ok' === $status ? '<info>OK</info>' : '<error>Error</error>'), 20, ' ', \STR_PAD_RIGHT);
314+
if ($status === 'ok') {
315+
$status = '<info>OK</info>';
316+
} elseif ($status === 'error') {
317+
$status = '<error>Error</error>';
318+
} else {
319+
$status = '<error>Warning</error>';
320+
}
321+
322+
$status = \str_pad($status, 20, ' ', \STR_PAD_RIGHT);
308323
$output->writeln(\sprintf("%s\t%s\t%s", $filename, $status, $process));
309324
} else {
310325
if ($i && 0 === $i % $maxColumns) {
311326
$output->writeln($process);
312327
}
313-
$output->write('ok' === $status ? '<info>.</info>' : '<error>E</error>');
328+
if ($status === 'ok') {
329+
$status = '<info>.</info>';
330+
} elseif ($status === 'error') {
331+
$status = '<error>E</error>';
332+
} else {
333+
$status = '<error>W</error>';
334+
}
335+
336+
$output->write($status);
314337
}
315338
++$i;
316339
});
@@ -404,6 +427,9 @@ protected function mergeOptions()
404427
$options = $this->input->getOptions();
405428
$options['path'] = $this->input->getArgument('path');
406429
$options['cache'] = $this->input->getOption('cache');
430+
if ($options['warning'] === false) {
431+
unset($options['warning']);
432+
}
407433

408434
$config = [];
409435

src/Linter.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,27 @@ class Linter
5656
*/
5757
private $processLimit = 5;
5858

59+
/**
60+
* @var bool
61+
*/
62+
private $warning;
63+
5964
/**
6065
* Constructor.
6166
*
6267
* @param string|array $path
6368
* @param array $excludes
6469
* @param array $extensions
70+
* @param bool $warning
6571
*/
66-
public function __construct($path, array $excludes = [], array $extensions = ['php'])
72+
public function __construct($path, array $excludes = [], array $extensions = ['php'], $warning = false)
6773
{
6874
$this->path = (array)$path;
6975
$this->excludes = $excludes;
7076
$this->extensions = \array_map(function ($extension) {
7177
return \sprintf('*.%s', \ltrim($extension, '.'));
7278
}, $extensions);
79+
$this->warning = $warning;
7380
}
7481

7582
/**
@@ -124,6 +131,9 @@ public function lint($files = [], $cache = true)
124131
if ($lint->hasSyntaxError()) {
125132
$processCallback('error', $item['file']);
126133
$errors[$filename] = array_merge(['file' => $filename, 'file_name' => $item['relativePath']], $lint->getSyntaxError());
134+
} elseif ($this->warning && $lint->hasSyntaxWarning()) {
135+
$processCallback('warning', $item['file']);
136+
$errors[$filename] = array_merge(['file' => $filename, 'file_name' => $item['relativePath']], $lint->getSyntaxWarning());
127137
} else {
128138
$newCache[$item['relativePath']] = md5_file($filename);
129139
$processCallback('ok', $item['file']);

src/Process/Lint.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,56 @@ public function parseError($message)
6868
'line' => $matched ? abs($match['line']) : 0,
6969
];
7070
}
71+
72+
/**
73+
* @return bool
74+
*/
75+
public function hasSyntaxWarning()
76+
{
77+
$output = trim($this->getOutput());
78+
79+
if (defined('HHVM_VERSION') && empty($output)) {
80+
return false;
81+
}
82+
83+
84+
return false !== strpos($output, 'Warning: ');
85+
}
86+
87+
/**
88+
* @return bool|array
89+
*/
90+
public function getSyntaxWarning()
91+
{
92+
if ($this->hasSyntaxWarning()) {
93+
$out = explode("\n", trim($this->getOutput()));
94+
95+
return $this->parseWarning(array_shift($out));
96+
}
97+
98+
return false;
99+
}
100+
101+
/**
102+
* Parse error message.
103+
*
104+
* @param string $message
105+
*
106+
* @return array
107+
*/
108+
public function parseWarning($message)
109+
{
110+
$pattern = '/^(PHP\s+)?Warning:\s*\s*?(?<error>.+?)\s+in\s+.+?\s*line\s+(?<line>\d+)/';
111+
112+
$matched = preg_match($pattern, $message, $match);
113+
114+
if (empty($message)) {
115+
$message = 'Unknown';
116+
}
117+
118+
return [
119+
'error' => $matched ? "{$match['error']} in line {$match['line']}" : $message,
120+
'line' => $matched ? abs($match['line']) : 0,
121+
];
122+
}
71123
}

0 commit comments

Comments
 (0)