diff --git a/src/lint/linter/ArcanistCppcheckLinter.php b/src/lint/linter/ArcanistCppcheckLinter.php index 7ed4e587..6b8fcf4e 100644 --- a/src/lint/linter/ArcanistCppcheckLinter.php +++ b/src/lint/linter/ArcanistCppcheckLinter.php @@ -1,137 +1,128 @@ getEngine()->getWorkingCopy(); // You will for sure want some options. The below default tends to be ok $options = $working_copy->getConfig( 'lint.cppcheck.options', '-j2 --inconclusive --enable=performance,style,portability,information' ); return $options; } public function getLintPath() { $working_copy = $this->getEngine()->getWorkingCopy(); $prefix = $working_copy->getConfig('lint.cppcheck.prefix'); - $bin = $working_copy->getConfig('lint.cppcheck.bin'); + $bin = $working_copy->getConfig('lint.cppcheck.bin', 'cppcheck'); - if ($bin === null && $prefix === null) { - $bin = 'cppcheck'; - } else { - if ($bin === null) { - $bin = 'cppcheck'; + if ($prefix !== null) { + if (!Filesystem::pathExists($prefix.'/'.$bin)) { + throw new ArcanistUsageException( + "Unable to find cppcheck binary in a specified directory. Make ". + "sure that 'lint.cppcheck.prefix' and 'lint.cppcheck.bin' keys are ". + "set correctly. If you'd rather use a copy of cppcheck installed ". + "globally, you can just remove these keys from your .arcconfig."); } - if ($prefix !== null) { - if (!Filesystem::pathExists($prefix.'/'.$bin)) { - throw new ArcanistUsageException( - "Unable to find cppcheck binary in a specified directory. Make ". - "sure that 'lint.cppcheck.prefix' and 'lint.cppcheck.bin' keys are". - " set correctly. If you'd rather use a copy of cppcheck installed ". - "globally, you can just remove these keys from your .arcconfig"); - } - - $bin = csprintf("%s/%s", $prefix, $bin); + $bin = csprintf("%s/%s", $prefix, $bin); - return $bin; - } + return $bin; + } - // Look for globally installed cppcheck - list($err) = exec_manual('which %s', $bin); - if ($err) { - throw new ArcanistUsageException( - "cppcheck does not appear to be installed on this system. Install". - "it (from http://cppcheck.sourceforge.net/) or configure". - "'lint.cppcheck.prefix' in your .arcconfig to point to the". - "directory where it resides." - ); - } + // Look for globally installed cppcheck + list($err) = exec_manual('which %s', $bin); + if ($err) { + throw new ArcanistUsageException( + "cppcheck does not appear to be installed on this system. Install ". + "it (from http://cppcheck.sourceforge.net/) or configure ". + "'lint.cppcheck.prefix' in your .arcconfig to point to the ". + "directory where it resides." + ); } return $bin; - } public function lintPath($path) { $bin = $this->getLintPath(); $options = $this->getLintOptions(); list($rc, $stdout, $stderr) = exec_manual( "%C %C --inline-suppr --xml-version=2 -q %s", $bin, $options, $this->getEngine()->getFilePathOnDisk($path) ); if ($rc === 1) { throw new Exception("cppcheck failed to run correctly:\n".$stderr); } $dom = new DOMDocument(); libxml_clear_errors(); if ($dom->loadXML($stderr) === false || libxml_get_errors()) { throw new ArcanistUsageException('cppcheck Linter failed to load ' . 'output. Something happened when running cppcheck. ' . "Output:\n$stderr" . "\nTry running lint with --trace flag to get more details."); } $errors = $dom->getElementsByTagName('error'); foreach ($errors as $error) { $loc_node = $error->getElementsByTagName('location'); if (!$loc_node) { continue; } $location = $loc_node->item(0); if (!$location) { continue; } $file = $location->getAttribute('file'); $line = $location->getAttribute('line'); $id = $error->getAttribute('id'); $severity = $error->getAttribute('severity'); $msg = $error->getAttribute('msg'); $inconclusive = $error->getAttribute('inconclusive'); $verbose_msg = $error->getAttribute('verbose'); $severity_code = ArcanistLintSeverity::SEVERITY_WARNING; if ($inconclusive) { $severity_code = ArcanistLintSeverity::SEVERITY_ADVICE; } else if (stripos($severity, 'error') !== false) { $severity_code = ArcanistLintSeverity::SEVERITY_ERROR; } $message = new ArcanistLintMessage(); $message->setPath($path); $message->setLine($line); $message->setCode($severity); $message->setName($id); $message->setDescription($msg); $message->setSeverity($severity_code); $this->addLintMessage($message); } } } diff --git a/src/lint/linter/ArcanistCpplintLinter.php b/src/lint/linter/ArcanistCpplintLinter.php index e2d3f137..24117790 100644 --- a/src/lint/linter/ArcanistCpplintLinter.php +++ b/src/lint/linter/ArcanistCpplintLinter.php @@ -1,105 +1,96 @@ getEngine()->getWorkingCopy(); $options = $working_copy->getConfig('lint.cpplint.options', ''); return $options; } public function getLintPath() { $working_copy = $this->getEngine()->getWorkingCopy(); $prefix = $working_copy->getConfig('lint.cpplint.prefix'); - $bin = $working_copy->getConfig('lint.cpplint.bin'); + $bin = $working_copy->getConfig('lint.cpplint.bin', 'cpplint.py'); - if ($bin === null && $prefix === null) { - $bin = 'cpplint.py'; - } else { - if ($bin === null) { - $bin = 'cpplint.py'; + if ($prefix !== null) { + if (!Filesystem::pathExists($prefix.'/'.$bin)) { + throw new ArcanistUsageException( + "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."); } - if ($prefix !== null) { - if (!Filesystem::pathExists($prefix.'/'.$bin)) { - throw new ArcanistUsageException( - "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"); - } - - $bin = csprintf("%s/%s", $prefix, $bin); + $bin = csprintf("%s/%s", $prefix, $bin); - return $bin; - } + return $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!"); - } + // 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; - } 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); } $lines = explode("\n", $stderr); $messages = array(); foreach ($lines as $line) { $line = trim($line); $matches = null; $regex = '/^-:(\d+):\s*(.*)\s*\[(.*)\] \[(\d+)\]$/'; if (!preg_match($regex, $line, $matches)) { continue; } foreach ($matches as $key => $match) { $matches[$key] = trim($match); } $message = new ArcanistLintMessage(); $message->setPath($path); $message->setLine($matches[1]); $message->setCode($matches[3]); $message->setName($matches[3]); $message->setDescription($matches[2]); $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); $this->addLintMessage($message); } } } diff --git a/src/lint/linter/ArcanistFlake8Linter.php b/src/lint/linter/ArcanistFlake8Linter.php index 28925dcc..2a7690a4 100644 --- a/src/lint/linter/ArcanistFlake8Linter.php +++ b/src/lint/linter/ArcanistFlake8Linter.php @@ -1,105 +1,105 @@ getEngine()->getWorkingCopy(); $options = $working_copy->getConfig('lint.flake8.options', ''); return $options; } public function getFlake8Path() { $working_copy = $this->getEngine()->getWorkingCopy(); $prefix = $working_copy->getConfig('lint.flake8.prefix'); $bin = $working_copy->getConfig('lint.flake8.bin', 'flake8'); if ($prefix !== null) { if (!Filesystem::pathExists($prefix.'/'.$bin)) { throw new ArcanistUsageException( "Unable to find flake8 binary in a specified directory. Make sure ". "that 'lint.flake8.prefix' and 'lint.flake8.bin' keys are set ". "correctly. If you'd rather use a copy of flake8 installed ". - "globally, you can just remove these keys from your .arcconfig"); + "globally, you can just remove these keys from your .arcconfig."); } $bin = csprintf("%s/%s", $prefix, $bin); return $bin; } // Look for globally installed flake8 list($err) = exec_manual('which %s', $bin); if ($err) { throw new ArcanistUsageException( "flake8 does not appear to be installed on this system. Install it ". "(e.g., with 'easy_install flake8') or configure ". "'lint.flake8.prefix' in your .arcconfig to point to the directory ". "where it resides."); } return $bin; } public function lintPath($path) { $flake8_bin = $this->getFlake8Path(); $options = $this->getFlake8Options(); $f = new ExecFuture("%C %C -", $flake8_bin, $options); $f->write($this->getData($path)); list($err, $stdout, $stderr) = $f->resolve(); if ($err === 2) { throw new Exception("flake8 failed to run correctly:\n".$stderr); } $lines = explode("\n", $stdout); $messages = array(); foreach ($lines as $line) { $matches = null; // stdin:2: W802 undefined name 'foo' # pyflakes // stdin:3:1: E302 expected 2 blank lines, found 1 # pep8 if (!preg_match('/^(.*?):(\d+):(?:(\d+):)? (\S+) (.*)$/', $line, $matches)) { continue; } foreach ($matches as $key => $match) { $matches[$key] = trim($match); } if (substr($matches[4], 0, 1) == 'E') { $severity = ArcanistLintSeverity::SEVERITY_ERROR; } else { $severity = ArcanistLintSeverity::SEVERITY_WARNING; } $message = new ArcanistLintMessage(); $message->setPath($path); $message->setLine($matches[2]); if (!empty($matches[3])) $message->setChar($matches[3]); $message->setCode($matches[4]); $message->setName($this->getLinterName().' '.$matches[3]); $message->setDescription($matches[5]); $message->setSeverity($severity); $this->addLintMessage($message); } } } diff --git a/src/lint/linter/ArcanistPEP8Linter.php b/src/lint/linter/ArcanistPEP8Linter.php index 6cd95ad8..80d7ac95 100644 --- a/src/lint/linter/ArcanistPEP8Linter.php +++ b/src/lint/linter/ArcanistPEP8Linter.php @@ -1,119 +1,119 @@ getEngine()->getWorkingCopy(); $options = $working_copy->getConfig('lint.pep8.options'); if ($options === null) { $options = $this->getConfig('options'); } return $options; } public function getPEP8Path() { $working_copy = $this->getEngine()->getWorkingCopy(); $prefix = $working_copy->getConfig('lint.pep8.prefix'); $bin = $working_copy->getConfig('lint.pep8.bin'); if ($bin === null && $prefix === null) { $bin = csprintf('/usr/bin/env python2.6 %s', phutil_get_library_root('arcanist'). '/../externals/pep8/pep8.py'); } else { if ($bin === null) { $bin = 'pep8'; } if ($prefix !== null) { if (!Filesystem::pathExists($prefix.'/'.$bin)) { throw new ArcanistUsageException( "Unable to find PEP8 binary in a specified directory. Make sure ". "that 'lint.pep8.prefix' and 'lint.pep8.bin' keys are set ". "correctly. If you'd rather use a copy of PEP8 installed ". - "globally, you can just remove these keys from your .arcconfig"); + "globally, you can just remove these keys from your .arcconfig."); } $bin = csprintf("%s/%s", $prefix, $bin); return $bin; } // Look for globally installed PEP8 list($err) = exec_manual('which %s', $bin); if ($err) { throw new ArcanistUsageException( "PEP8 does not appear to be installed on this system. Install it ". "(e.g., with 'easy_install pep8') or configure ". "'lint.pep8.prefix' in your .arcconfig to point to the directory ". "where it resides."); } } return $bin; } public function lintPath($path) { $pep8_bin = $this->getPEP8Path(); $options = $this->getPEP8Options(); list($rc, $stdout) = exec_manual( "%C %C %s", $pep8_bin, $options, $this->getEngine()->getFilePathOnDisk($path)); $lines = explode("\n", $stdout); $messages = array(); foreach ($lines as $line) { $matches = null; if (!preg_match('/^(.*?):(\d+):(\d+): (\S+) (.*)$/', $line, $matches)) { continue; } foreach ($matches as $key => $match) { $matches[$key] = trim($match); } if (!$this->isMessageEnabled($matches[4])) { continue; } $message = new ArcanistLintMessage(); $message->setPath($path); $message->setLine($matches[2]); $message->setChar($matches[3]); $message->setCode($matches[4]); $message->setName('PEP8 '.$matches[4]); $message->setDescription($matches[5]); $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); $this->addLintMessage($message); } } }