From 9fc8a2f61b197ca2de8297ece559513683001922 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Wed, 27 Aug 2014 17:29:31 -0700 Subject: [PATCH] Adding php -l linter Summary: Adds a linter that checks php files for syntax errors using php -l Test Plan: Add a section to your .arclint file similar to: ``` "php": { "type": "php", "include": "(\\.php$)" } ``` Then run arc lint on a php file with a syntax error. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: epriestley, jacobwalker0814, Korvin Differential Revision: https://secure.phabricator.com/D10370 --- src/__phutil_library_map__.php | 4 + src/lint/linter/ArcanistPhpLinter.php | 85 +++++++++++++++++++ .../__tests__/ArcanistPhpLinterTestCase.php | 11 +++ src/lint/linter/__tests__/php/fatal.lint-test | 7 ++ .../linter/__tests__/php/no-errors.lint-test | 6 ++ .../linter/__tests__/php/syntax.lint-test | 7 ++ 6 files changed, 120 insertions(+) create mode 100644 src/lint/linter/ArcanistPhpLinter.php create mode 100644 src/lint/linter/__tests__/ArcanistPhpLinterTestCase.php create mode 100644 src/lint/linter/__tests__/php/fatal.lint-test create mode 100644 src/lint/linter/__tests__/php/no-errors.lint-test create mode 100644 src/lint/linter/__tests__/php/syntax.lint-test diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index bc1b07d2..aaf92d11 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -132,6 +132,8 @@ phutil_register_library_map(array( 'ArcanistPEP8LinterTestCase' => 'lint/linter/__tests__/ArcanistPEP8LinterTestCase.php', 'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php', 'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php', + 'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php', + 'ArcanistPhpLinterTestCase' => 'lint/linter/__tests__/ArcanistPhpLinterTestCase.php', 'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php', 'ArcanistPhpcsLinterTestCase' => 'lint/linter/__tests__/ArcanistPhpcsLinterTestCase.php', 'ArcanistPhrequentWorkflow' => 'workflow/ArcanistPhrequentWorkflow.php', @@ -313,6 +315,8 @@ phutil_register_library_map(array( 'ArcanistPEP8LinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistPasteWorkflow' => 'ArcanistWorkflow', 'ArcanistPatchWorkflow' => 'ArcanistWorkflow', + 'ArcanistPhpLinter' => 'ArcanistExternalLinter', + 'ArcanistPhpLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistPhpcsLinter' => 'ArcanistExternalLinter', 'ArcanistPhpcsLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistPhrequentWorkflow' => 'ArcanistWorkflow', diff --git a/src/lint/linter/ArcanistPhpLinter.php b/src/lint/linter/ArcanistPhpLinter.php new file mode 100644 index 00000000..7daf7553 --- /dev/null +++ b/src/lint/linter/ArcanistPhpLinter.php @@ -0,0 +1,85 @@ +getExecutableCommand()); + + $matches = array(); + $regex = '/^PHP (?P\d+\.\d+\.\d+)\b/'; + if (preg_match($regex, $stdout, $matches)) { + return $matches['version']; + } else { + return false; + } + } + + public function shouldExpectCommandErrors() { + return true; + } + + public function supportsReadDataFromStdin() { + return false; + } + + protected function parseLinterOutput($path, $err, $stdout, $stderr) { + // Older versions of php had both on $stdout, newer ones split it + // Combine $stdout and $stderr for consistency + $stdout = $stderr."\n".$stdout; + $matches = array(); + $regex = '/PHP (?.+?) error:\s+(?.*?)\s+in\s+(?.*?)'. + '\s+on line\s+(?\d*)/'; + if (preg_match($regex, $stdout, $matches)) { + $type = strtolower($matches['type']); + $message = new ArcanistLintMessage(); + $message->setPath($matches['file']); + $message->setLine($matches['line']); + $message->setCode('php.'.$type); + $message->setDescription('This file contains a '.$type.' error: '. + $matches['error'].' on line '.$matches['line']); + $message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR); + + // php -l only returns the first error + return array($message); + } + + return array(); + } + +} diff --git a/src/lint/linter/__tests__/ArcanistPhpLinterTestCase.php b/src/lint/linter/__tests__/ArcanistPhpLinterTestCase.php new file mode 100644 index 00000000..a3fc56ec --- /dev/null +++ b/src/lint/linter/__tests__/ArcanistPhpLinterTestCase.php @@ -0,0 +1,11 @@ +executeTestsInDirectory( + dirname(__FILE__).'/php/', + new ArcanistPhpLinter()); + } + +} diff --git a/src/lint/linter/__tests__/php/fatal.lint-test b/src/lint/linter/__tests__/php/fatal.lint-test new file mode 100644 index 00000000..cf13b0cd --- /dev/null +++ b/src/lint/linter/__tests__/php/fatal.lint-test @@ -0,0 +1,7 @@ +