mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 16:22:42 +01:00
Add a very basic Scala (SBT) linter.
Summary: SBT is the most common Scala buildsystem. This adds an extremely basic and slightly horrible linter to check SBT's output for warnings and errors. Test Plan: Tested this with a Scala project I've been working on for some time. It seemed relatively sane. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4064
This commit is contained in:
parent
6cb8d483b2
commit
b549f565c9
3 changed files with 111 additions and 0 deletions
|
@ -104,6 +104,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistRepositoryAPI' => 'repository/api/ArcanistRepositoryAPI.php',
|
||||
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
|
||||
'ArcanistRubyLinterTestCase' => 'lint/linter/__tests__/ArcanistRubyLinterTestCase.php',
|
||||
'ArcanistScalaSBTLinter' => 'lint/linter/ArcanistScalaSBTLinter.php',
|
||||
'ArcanistScriptAndRegexLinter' => 'lint/linter/ArcanistScriptAndRegexLinter.php',
|
||||
'ArcanistSetConfigWorkflow' => 'workflow/ArcanistSetConfigWorkflow.php',
|
||||
'ArcanistSettings' => 'configuration/ArcanistSettings.php',
|
||||
|
@ -215,6 +216,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistPyLintLinter' => 'ArcanistLinter',
|
||||
'ArcanistRubyLinter' => 'ArcanistLinter',
|
||||
'ArcanistRubyLinterTestCase' => 'ArcanistArcanistLinterTestCase',
|
||||
'ArcanistScalaSBTLinter' => 'ArcanistLinter',
|
||||
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
|
||||
'ArcanistSetConfigWorkflow' => 'ArcanistBaseWorkflow',
|
||||
'ArcanistShellCompleteWorkflow' => 'ArcanistBaseWorkflow',
|
||||
|
|
|
@ -45,6 +45,9 @@ final class ComprehensiveLintEngine extends ArcanistLintEngine {
|
|||
$linters[] = id(new ArcanistRubyLinter())
|
||||
->setPaths(preg_grep('/\.rb$/', $paths));
|
||||
|
||||
$linters[] = id(new ArcanistScalaSBTLinter())
|
||||
->setPaths(preg_grep('/\.scala$/', $paths));
|
||||
|
||||
$linters[] = id(new ArcanistJSHintLinter())
|
||||
->setPaths(preg_grep('/\.js$/', $paths));
|
||||
|
||||
|
|
106
src/lint/linter/ArcanistScalaSBTLinter.php
Normal file
106
src/lint/linter/ArcanistScalaSBTLinter.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Uses `sbt compile` to detect various warnings/errors in Scala code.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
final class ArcanistScalaSBTLinter extends ArcanistLinter {
|
||||
|
||||
public function willLintPaths(array $paths) {
|
||||
return;
|
||||
}
|
||||
|
||||
public function getLinterName() {
|
||||
return 'ScalaSBT';
|
||||
}
|
||||
|
||||
public function getLintSeverityMap() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getLintNameMap() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function canRun() {
|
||||
// Check if this looks like a SBT project. If it doesn't, throw, because
|
||||
// we rely fairly heavily on `sbt compile` working, below. We don't want
|
||||
// to call out to scalac ourselves, because then we'll end up in Class Path
|
||||
// Hell. We let the build system handle this for us.
|
||||
if (!Filesystem::pathExists('project/Build.scala') &&
|
||||
!Filesystem::pathExists('build.sbt')) {
|
||||
throw new ArcanistUsageException(
|
||||
"This directory does not appear to be maintained by SBT, as we can't ".
|
||||
"seem to find a working build file (project/Build.scala or ".
|
||||
"build.sbt).");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getSBTPath() {
|
||||
$sbt_bin = "sbt";
|
||||
|
||||
// Use the SBT prefix specified in the config file
|
||||
$working_copy = $this->getEngine()->getWorkingCopy();
|
||||
$prefix = $working_copy->getConfig('lint.scala_sbt.prefix');
|
||||
if ($prefix !== null) {
|
||||
$sbt_bin = $prefix . $sbt_bin;
|
||||
}
|
||||
|
||||
if (!Filesystem::pathExists($sbt_bin)) {
|
||||
|
||||
list($err) = exec_manual('which %s', $sbt_bin);
|
||||
if ($err) {
|
||||
throw new ArcanistUsageException(
|
||||
"SBT does not appear to be installed on this system. Install it or ".
|
||||
"add 'lint.scala_sbt.prefix' in your .arcconfig to point to ".
|
||||
"the directory where it resides.");
|
||||
}
|
||||
}
|
||||
|
||||
return $sbt_bin;
|
||||
}
|
||||
|
||||
private function getMessageCodeSeverity($type_of_error) {
|
||||
switch ($type_of_error) {
|
||||
case 'warn':
|
||||
return ArcanistLintSeverity::SEVERITY_WARNING;
|
||||
case 'error':
|
||||
return ArcanistLintSeverity::SEVERITY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public function lintPath($path) {
|
||||
$sbt = $this->getSBTPath();
|
||||
|
||||
// Tell SBT to not use color codes so our regex life is easy.
|
||||
// TODO: Should this be "clean compile" instead of "compile"?
|
||||
$f = new ExecFuture("%s -Dsbt.log.noformat=true compile", $sbt);
|
||||
list($err, $stdout, $stderr) = $f->resolve();
|
||||
|
||||
$lines = explode("\n", $stdout);
|
||||
$messages = array();
|
||||
foreach ($lines as $line) {
|
||||
$matches = null;
|
||||
if (!preg_match(
|
||||
"/\[(warn|error)\] (.*?):(\d+): (.*?)$/",
|
||||
$line,
|
||||
$matches)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($matches as $key => $match) {
|
||||
$matches[$key] = trim($match);
|
||||
}
|
||||
|
||||
$message = new ArcanistLintMessage();
|
||||
$message->setPath($matches[2]);
|
||||
$message->setLine($matches[3]);
|
||||
$message->setCode($this->getLinterName());
|
||||
$message->setDescription($matches[4]);
|
||||
$message->setSeverity($this->getMessageCodeSeverity($matches[1]));
|
||||
$this->addLintMessage($message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue