1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-26 07:20:56 +01:00

Add an ArcanistCoffeeLintLinter linter.

Summary:
Add a wrapper around [[http://www.coffeelint.org/ | CoffeeLint]] as an `ArcanistExternalLinter`.

Depends on D9041.

Test Plan: Wrote and executed unit tests.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D9051
This commit is contained in:
Joshua Spence 2014-05-16 21:58:01 -07:00 committed by epriestley
parent 7bde5941cf
commit 1493e043e1
13 changed files with 221 additions and 0 deletions

View file

@ -38,6 +38,8 @@ phutil_register_library_map(array(
'ArcanistCloseWorkflow' => 'workflow/ArcanistCloseWorkflow.php',
'ArcanistClosureLinter' => 'lint/linter/ArcanistClosureLinter.php',
'ArcanistClosureLinterTestCase' => 'lint/linter/__tests__/ArcanistClosureLinterTestCase.php',
'ArcanistCoffeeLintLinter' => 'lint/linter/ArcanistCoffeeLintLinter.php',
'ArcanistCoffeeLintLinterTestCase' => 'lint/linter/__tests__/ArcanistCoffeeLintLinterTestCase.php',
'ArcanistCommentRemover' => 'parser/ArcanistCommentRemover.php',
'ArcanistCommentRemoverTestCase' => 'parser/__tests__/ArcanistCommentRemoverTestCase.php',
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
@ -226,6 +228,8 @@ phutil_register_library_map(array(
'ArcanistCloseWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistClosureLinter' => 'ArcanistExternalLinter',
'ArcanistClosureLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCoffeeLintLinter' => 'ArcanistExternalLinter',
'ArcanistCoffeeLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCommentRemoverTestCase' => 'ArcanistTestCase',
'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistConduitLinter' => 'ArcanistLinter',

View file

@ -0,0 +1,152 @@
<?php
final class ArcanistCoffeeLintLinter extends ArcanistExternalLinter {
private $config;
public function getInfoName() {
return 'CoffeeLint';
}
public function getInfoURI() {
return 'http://www.coffeelint.org';
}
public function getInfoDescription() {
return pht(
'CoffeeLint is a style checker that helps keep CoffeeScript '.
'code clean and consistent.');
}
public function getLinterName() {
return 'COFFEE';
}
public function getLinterConfigurationName() {
return 'coffeelint';
}
public function getDefaultBinary() {
return 'coffeelint';
}
public function getVersion() {
list($stdout) = execx('%C --version', $this->getExecutableCommand());
$matches = array();
if (preg_match('/^(?P<version>\d+\.\d+\.\d+)$/', $stdout, $matches)) {
return $matches['version'];
} else {
return false;
}
}
public function getInstallInstructions() {
return pht('Install CoffeeLint using `npm install -g coffeelint`.');
}
public function shouldExpectCommandErrors() {
return true;
}
public function supportsReadDataFromStdin() {
return true;
}
public function getReadDataFromStdinFilename() {
return '--stdin';
}
protected function getMandatoryFlags() {
$options = array(
'--checkstyle',
'--nocolor',
'--quiet',
);
if ($this->config) {
$options[] = '--file='.$this->config;
}
return $options;
}
public function getLinterConfigurationOptions() {
$options = array(
'coffeelint.config' => array(
'type' => 'optional string',
'help' => pht('A custom configuration file.'),
),
);
return $options + parent::getLinterConfigurationOptions();
}
public function setLinterConfigurationValue($key, $value) {
switch ($key) {
case 'coffeelint.config':
$this->config = $value;
return;
}
return parent::setLinterConfigurationValue($key, $value);
}
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$report_dom = new DOMDocument();
$ok = @$report_dom->loadXML($stdout);
if (!$ok) {
return false;
}
$files = $report_dom->getElementsByTagName('file');
$messages = array();
foreach ($files as $file) {
foreach ($file->getElementsByTagName('error') as $error) {
// Column number is not provided in the output.
// See https://github.com/clutchski/coffeelint/issues/87
$message = new ArcanistLintMessage();
$message->setPath($path);
$message->setLine($error->getAttribute('line'));
$message->setCode($this->getLinterName());
$message->setDescription(preg_replace(
'/; context: .*$/',
'.',
$error->getAttribute('message')));
switch ($error->getAttribute('severity')) {
case 'warning':
$message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING);
break;
case 'error':
$message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR);
break;
default:
$message->setSeverity(ArcanistLintSeverity::SEVERITY_ADVICE);
break;
}
$messages[] = $message;
}
}
return $messages;
}
protected function getLintCodeFromLinterConfigurationKey($code) {
// NOTE: We can't figure out which rule generated each message, so we
// can not customize severities.
throw new Exception(
pht(
"CoffeeLint does not currently support custom severity levels, ".
"because rules can't be identified from messages in output."));
}
}

View file

@ -0,0 +1,12 @@
<?php
final class ArcanistCoffeeLintLinterTestCase
extends ArcanistArcanistLinterTestCase {
public function testCoffeeLintLinter() {
$this->executeTestsInDirectory(
dirname(__FILE__).'/coffeelint/',
new ArcanistCoffeeLintLinter());
}
}

View file

@ -0,0 +1,3 @@
class boaConstrictor
~~~~~~~~~~
error:1:

View file

@ -0,0 +1,18 @@
class SomeThing
getConfig: ->
one = 1
one = 5
@config =
keyA: one
keyB: one
keyA: 2
getConfig: ->
@config =
foo: 1
@getConfig: ->
config =
foo: 1
~~~~~~~~~~
error:8:
error:9:

View file

@ -0,0 +1,7 @@
twoSpaces = () ->
fourSpaces = () ->
eightSpaces = () ->
'this is valid CoffeeScript'
~~~~~~~~~~
error:3:
error:4:

View file

@ -0,0 +1,3 @@
#--------------------------------------------------------------------------------
~~~~~~~~~~
error:1:

View file

@ -0,0 +1,3 @@
`with(document) alert(height);`
~~~~~~~~~~
error:1:

View file

@ -0,0 +1,3 @@
debugger
~~~~~~~~~~
warning:1:

View file

@ -0,0 +1,6 @@
x = () ->
y = () ->
return 1234
~~~~~~~~~~
error:2:
error:3:

View file

@ -0,0 +1,3 @@
throw "i made a boo boo"
~~~~~~~~~~
error:1:

View file

@ -0,0 +1,3 @@
alert('end of line');
~~~~~~~~~~
error:1:

View file

@ -0,0 +1,4 @@
x = 1234
y = 1
~~~~~~~~~~
error:1: