mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Add Closure linter to arcanist
Summary: Found https://secure.phabricator.com/D4519 but it was horribly out of date, so decided to write a new version. Kinda clobbered together form that diff and the new version of ArcanistJSHintLinter Test Plan: Tested on personal projects with js files. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Differential Revision: https://secure.phabricator.com/D9131
This commit is contained in:
parent
fcdacc28b8
commit
6c6035d04b
4 changed files with 121 additions and 0 deletions
|
@ -36,6 +36,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistChooseNoRevisionsException' => 'exception/ArcanistChooseNoRevisionsException.php',
|
'ArcanistChooseNoRevisionsException' => 'exception/ArcanistChooseNoRevisionsException.php',
|
||||||
'ArcanistCloseRevisionWorkflow' => 'workflow/ArcanistCloseRevisionWorkflow.php',
|
'ArcanistCloseRevisionWorkflow' => 'workflow/ArcanistCloseRevisionWorkflow.php',
|
||||||
'ArcanistCloseWorkflow' => 'workflow/ArcanistCloseWorkflow.php',
|
'ArcanistCloseWorkflow' => 'workflow/ArcanistCloseWorkflow.php',
|
||||||
|
'ArcanistClosureLinter' => 'lint/linter/ArcanistClosureLinter.php',
|
||||||
|
'ArcanistClosureLinterTestCase' => 'lint/linter/__tests__/ArcanistClosureLinterTestCase.php',
|
||||||
'ArcanistCommentRemover' => 'parser/ArcanistCommentRemover.php',
|
'ArcanistCommentRemover' => 'parser/ArcanistCommentRemover.php',
|
||||||
'ArcanistCommentRemoverTestCase' => 'parser/__tests__/ArcanistCommentRemoverTestCase.php',
|
'ArcanistCommentRemoverTestCase' => 'parser/__tests__/ArcanistCommentRemoverTestCase.php',
|
||||||
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
|
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
|
||||||
|
@ -222,6 +224,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistChooseNoRevisionsException' => 'Exception',
|
'ArcanistChooseNoRevisionsException' => 'Exception',
|
||||||
'ArcanistCloseRevisionWorkflow' => 'ArcanistBaseWorkflow',
|
'ArcanistCloseRevisionWorkflow' => 'ArcanistBaseWorkflow',
|
||||||
'ArcanistCloseWorkflow' => 'ArcanistBaseWorkflow',
|
'ArcanistCloseWorkflow' => 'ArcanistBaseWorkflow',
|
||||||
|
'ArcanistClosureLinter' => 'ArcanistExternalLinter',
|
||||||
|
'ArcanistClosureLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||||
'ArcanistCommentRemoverTestCase' => 'ArcanistTestCase',
|
'ArcanistCommentRemoverTestCase' => 'ArcanistTestCase',
|
||||||
'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow',
|
'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow',
|
||||||
'ArcanistConduitLinter' => 'ArcanistLinter',
|
'ArcanistConduitLinter' => 'ArcanistLinter',
|
||||||
|
|
82
src/lint/linter/ArcanistClosureLinter.php
Normal file
82
src/lint/linter/ArcanistClosureLinter.php
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses gJSLint to detect errors and potential problems in JavaScript code.
|
||||||
|
*/
|
||||||
|
final class ArcanistClosureLinter extends ArcanistExternalLinter {
|
||||||
|
|
||||||
|
public function getInfoName() {
|
||||||
|
return 'Closure Linter';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInfoURI() {
|
||||||
|
return 'https://developers.google.com/closure/utilities/';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInfoDescription() {
|
||||||
|
return pht(
|
||||||
|
'Uses Google\'s Closure Linter to check Javascript code.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLinterName() {
|
||||||
|
return 'Closure Linter';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLinterConfigurationName() {
|
||||||
|
return 'gjslint';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDefaultMessageSeverity($code) {
|
||||||
|
return ArcanistLintSeverity::SEVERITY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultBinary() {
|
||||||
|
return 'gjslint';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInstallInstructions() {
|
||||||
|
return pht('Install gJSLint using `sudo easy_install http://closure-linter'.
|
||||||
|
'.googlecode.com/files/closure_linter-latest.tar.gz`');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shouldExpectCommandErrors() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsReadDataFromStdin() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
|
||||||
|
// Each line looks like this:
|
||||||
|
// Line 46, E:0110: Line too long (87 characters).
|
||||||
|
$regex = '/^Line (\d+), (E:\d+): (.*)/';
|
||||||
|
$severity_code = ArcanistLintSeverity::SEVERITY_ERROR;
|
||||||
|
|
||||||
|
$lines = explode("\n", $stdout);
|
||||||
|
|
||||||
|
$messages = array();
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$line = trim($line);
|
||||||
|
$matches = null;
|
||||||
|
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->setName($matches[2]);
|
||||||
|
$message->setCode($this->getLinterName());
|
||||||
|
$message->setDescription($matches[3]);
|
||||||
|
$message->setSeverity($severity_code);
|
||||||
|
|
||||||
|
$messages[] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
}
|
15
src/lint/linter/__tests__/ArcanistClosureLinterTestCase.php
Normal file
15
src/lint/linter/__tests__/ArcanistClosureLinterTestCase.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistClosureLinterTestCase
|
||||||
|
extends ArcanistArcanistLinterTestCase {
|
||||||
|
|
||||||
|
public function testClosureLinter() {
|
||||||
|
$linter = new ArcanistClosureLinter();
|
||||||
|
$linter->setFlags(array("--additional_extensions=lint-test"));
|
||||||
|
|
||||||
|
$this->executeTestsInDirectory(
|
||||||
|
dirname(__FILE__).'/gjslint/',
|
||||||
|
$linter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
src/lint/linter/__tests__/gjslint/gjslint.lint-test
Normal file
20
src/lint/linter/__tests__/gjslint/gjslint.lint-test
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
var x = 'some really really really really really really really long string';
|
||||||
|
var y = 'some really really really really really really really really really long string',
|
||||||
|
z = 14;
|
||||||
|
var obj = {name : 'vm'};
|
||||||
|
var x
|
||||||
|
var result = true
|
||||||
|
|| false;
|
||||||
|
/**
|
||||||
|
* @param x
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function foo(x) {
|
||||||
|
return 'bar';
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:2:
|
||||||
|
error:4:
|
||||||
|
error:5:
|
||||||
|
error:7:
|
||||||
|
error:9:
|
Loading…
Reference in a new issue