1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-26 16:52:40 +01:00

Modernize ArcanistCpplintLinter.

Summary: Convert the `cpplint.py` wrapper linter to `ArcanistExternalLinter`. This is in preparation for T2039.

Test Plan: `arc unit`.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Maniphest Tasks: T2039

Differential Revision: https://secure.phabricator.com/D9033
This commit is contained in:
Joshua Spence 2014-05-10 01:32:53 -07:00 committed by epriestley
parent 88bb9909b9
commit 4a1b8a3299
2 changed files with 54 additions and 45 deletions

View file

@ -225,7 +225,7 @@ phutil_register_library_map(array(
'ArcanistConfigurationDrivenLintEngine' => 'ArcanistLintEngine', 'ArcanistConfigurationDrivenLintEngine' => 'ArcanistLintEngine',
'ArcanistCoverWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistCoverWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistCppcheckLinter' => 'ArcanistLinter', 'ArcanistCppcheckLinter' => 'ArcanistLinter',
'ArcanistCpplintLinter' => 'ArcanistLinter', 'ArcanistCpplintLinter' => 'ArcanistExternalLinter',
'ArcanistCpplintLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistCpplintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistDiffParserTestCase' => 'ArcanistTestCase', 'ArcanistDiffParserTestCase' => 'ArcanistTestCase',
'ArcanistDiffUtilsTestCase' => 'ArcanistTestCase', 'ArcanistDiffUtilsTestCase' => 'ArcanistTestCase',

View file

@ -1,68 +1,56 @@
<?php <?php
/** /**
* Uses google's cpplint.py to check code. * Uses Google's `cpplint.py` to check code.
*
* You can get it here:
* http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py
* @group linter
*/ */
final class ArcanistCpplintLinter extends ArcanistLinter { final class ArcanistCpplintLinter extends ArcanistExternalLinter {
public function getLinterName() { public function getLinterName() {
return 'cpplint.py'; return 'CPPLINT';
} }
public function getLintOptions() { public function getLinterConfigurationName() {
$config = $this->getEngine()->getConfigurationManager(); return 'cpplint';
return $config->getConfigFromAnySource('lint.cpplint.options', '');
} }
public function getLintPath() { public function getDefaultBinary() {
// TODO: Warn that all of this is deprecated.
$config = $this->getEngine()->getConfigurationManager(); $config = $this->getEngine()->getConfigurationManager();
$prefix = $config->getConfigFromAnySource('lint.cpplint.prefix'); $prefix = $config->getConfigFromAnySource('lint.cpplint.prefix');
$bin = $config->getConfigFromAnySource('lint.cpplint.bin', 'cpplint.py'); $bin = $config->getConfigFromAnySource('lint.cpplint.bin', 'cpplint.py');
if ($prefix !== null) { if ($prefix) {
if (!Filesystem::pathExists($prefix.'/'.$bin)) { return $prefix.'/'.$bin;
throw new ArcanistUsageException( } else {
"Unable to find cpplint.py binary in a specified directory. Make ".
"sure that 'lint.cpplint.prefix' and 'lint.cpplint.bin' keys are ".
"set correctly. If you'd rather use a copy of cpplint installed ".
"globally, you can just remove these keys from your .arcconfig.");
}
return csprintf("%s/%s", $prefix, $bin);
}
// Look for globally installed cpplint.py
list($err) = exec_manual('which %s', $bin);
if ($err) {
throw new ArcanistUsageException(
"cpplint.py does not appear to be installed on this system. Install ".
"it (e.g., with 'wget \"http://google-styleguide.googlecode.com/".
"svn/trunk/cpplint/cpplint.py\"') or configure 'lint.cpplint.prefix' ".
"in your .arcconfig to point to the directory where it resides. ".
"Also don't forget to chmod a+x cpplint.py!");
}
return $bin; return $bin;
} }
public function lintPath($path) {
$bin = $this->getLintPath();
$options = $this->getLintOptions();
$f = new ExecFuture("%C %C -", $bin, $options);
$f->write($this->getData($path));
list($err, $stdout, $stderr) = $f->resolve();
if ($err === 2) {
throw new Exception("cpplint failed to run correctly:\n".$stderr);
} }
public function getInstallInstructions() {
return pht('Install cpplint.py using `wget http://google-styleguide.'.
'googlecode.com/svn/trunk/cpplint/cpplint.py`.');
}
public function shouldExpectCommandErrors() {
return true;
}
public function supportsReadDataFromStdin() {
return true;
}
public function getReadDataFromStdinFilename() {
return '-';
}
protected function getDefaultFlags() {
$config = $this->getEngine()->getConfigurationManager();
return $config->getConfigFromAnySource('lint.cpplint.options', array());
}
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$lines = explode("\n", $stderr); $lines = explode("\n", $stderr);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {
$line = trim($line); $line = trim($line);
@ -81,8 +69,29 @@ final class ArcanistCpplintLinter extends ArcanistLinter {
$message->setName($matches[3]); $message->setName($matches[3]);
$message->setDescription($matches[2]); $message->setDescription($matches[2]);
$message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING);
$this->addLintMessage($message);
$messages[] = $message;
} }
if ($err && !$messages) {
return false;
}
return $messages;
}
protected function getLintCodeFromLinterConfigurationKey($code) {
if (!preg_match('@^[a-z_]+/[a-z_]+$@', $code)) {
throw new Exception(
pht(
'Unrecognized lint message code "%s". Expected a valid cpplint '.
'lint code like "%s" or "%s".',
$code,
'build/include_order',
'whitespace/braces'));
}
return $code;
} }
} }