Page MenuHomePhabricator

D14145.id34197.diff
No OneTemporary

D14145.id34197.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -219,6 +219,7 @@
'ArcanistRuboCopLinterTestCase' => 'lint/linter/__tests__/ArcanistRuboCopLinterTestCase.php',
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
'ArcanistRubyLinterTestCase' => 'lint/linter/__tests__/ArcanistRubyLinterTestCase.php',
+ 'ArcanistScalastyleLinter' => 'lint/linter/ArcanistScalastyleLinter.php',
'ArcanistScriptAndRegexLinter' => 'lint/linter/ArcanistScriptAndRegexLinter.php',
'ArcanistSelfMemberReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php',
'ArcanistSemicolonSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSemicolonSpacingXHPASTLinterRule.php',
@@ -505,6 +506,7 @@
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
'ArcanistRubyLinterTestCase' => 'ArcanistExternalLinterTestCase',
+ 'ArcanistScalastyleLinter' => 'ArcanistExternalLinter',
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
'ArcanistSelfMemberReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistSemicolonSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
diff --git a/src/lint/linter/ArcanistScalastyleLinter.php b/src/lint/linter/ArcanistScalastyleLinter.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/ArcanistScalastyleLinter.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * Scalastyle linter for Arcanist.
+ */
+final class ArcanistScalastyleLinter extends ArcanistExternalLinter {
+ private $configPath = null;
+ private $jarPath = null;
+
+ public function getDefaultBinary() {
+ return 'java';
+ }
+
+ public function getInstallInstructions() {
+ return pht('Download scalastyle-batch jar from '.
+ 'http://www.scalastyle.org/command-line.html and set the jarPath');
+ }
+
+ public function getInfoURI() {
+ return 'http://www.scalastyle.org';
+ }
+
+ public function getInfoDescription() {
+ return pht('Scalastyle linter');
+ }
+
+ public function getLinterConfigurationName() {
+ return 'scalastyle';
+ }
+
+ protected function getMandatoryFlags() {
+ return array(
+ '-jar',
+ $this->jarPath,
+ '--config',
+ $this->configPath,
+ '--quiet',
+ 'true',
+ );
+ }
+
+ public function getLinterConfigurationOptions() {
+ return parent::getLinterConfigurationOptions() + array(
+ 'scalastyle.config' => array(
+ 'type' => 'string',
+ 'help' => pht('Path to the scalastyle-configuration.xml'),
+ ),
+ 'scalastyle.jar' => array(
+ 'type' => 'string',
+ 'help' => pht('Path to the scalastyle-batch jar file'),
+ ),
+ );
+ }
+
+ public function setLinterConfigurationValue($key, $value) {
+ switch ($key) {
+ case 'scalastyle.config':
+ $this->configPath = Filesystem::resolvePath($value,
+ $this->getProjectRoot());
+ if (!file_exists($this->configPath)) {
+ throw new ArcanistMissingLinterException(
+ pht('Unable to locate scalastyle configuration at "%s"',
+ $this->configPath));
+ }
+ return;
+ case 'scalastyle.jar':
+ $this->jarPath = Filesystem::resolvePath($value,
+ $this->getProjectRoot());
+ if (!file_exists($this->jarPath)) {
+ throw new ArcanistMissingLinterException(
+ pht('Unable to locate scalastyle jar at "%s"',
+ $this->jarPath));
+ }
+ return;
+ }
+
+ parent::setLinterConfigurationValue($key, $value);
+ }
+
+ protected function parseLinterOutput($path, $err, $stdout, $stderr) {
+ $output_pattern = '/^(?P<severity>warning|error|exception) '.
+ 'file=(?P<path>.*) message=(?P<description>.*) line=(?P<line>\d+)'.
+ '(?: column=(?P<char>\d+))?$/';
+ $messages = array();
+ $lines = explode(PHP_EOL, trim($stdout));
+
+ foreach ($lines as $line) {
+ $matches = null;
+ if (preg_match($output_pattern, $line, $matches)) {
+ $message = new ArcanistLintMessage();
+ $message->setCode($this->getLinterName());
+ $message->setSeverity(
+ $this->mapScalastyleSeverity($matches['severity']));
+ $message->setPath($matches['path']);
+ $message->setDescription($matches['description']);
+ $message->setLine($matches['line']);
+ if (array_key_exists('char', $matches)) {
+ $message->setChar($matches['char']);
+ }
+ $messages[] = $message;
+ }
+ }
+
+ return $messages;
+ }
+
+ public function getLinterName() {
+ return 'scalastyle';
+ }
+
+ private function mapScalastyleSeverity($severity) {
+ switch ($severity) {
+ case 'warning':
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ case 'error':
+ return ArcanistLintSeverity::SEVERITY_ERROR;
+ case 'exception':
+ return ArcanistLintSeverity::SEVERITY_DISABLED;
+ }
+ throw new Exception(
+ pht('Unrecognized scalastyle severity "%s"', $severity),
+ $this->getLinterName());
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 5:55 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7715835
Default Alt Text
D14145.id34197.diff (5 KB)

Event Timeline