config,
// This allows globally installing plugins even with eslint 6+
'--resolve-plugins-relative-to',
strtok($stdout, "\n")
);
}
public function getLinterConfigurationOptions() {
$options = array(
'config' => array(
'type' => 'optional string',
'help' => pht('Link to the config file.'),
),
);
return $options + parent::getLinterConfigurationOptions();
}
public function setLinterConfigurationValue($key, $value) {
switch ($key) {
case 'config':
$this->config = $value;
return;
}
return parent::setLinterConfigurationValue($key, $value);
}
protected function parseLinterOutput($path, $err, $stdout, $stderr) {
// Gate on $stderr b/c $err (exit code) is expected.
if ($stderr) {
return false;
}
$json = json_decode($stdout, true);
$messages = array();
foreach ($json as $file) {
foreach ($file['messages'] as $offense) {
// Skip file ignored warning: if a file is ignored by .eslintingore
// but linted explicitly (by arcanist), a warning will be reported,
// containing only: `{fatal:false,severity:1,message:...}`.
if (strpos($offense['message'], "File ignored ") === 0) {
continue;
}
$message = new ArcanistLintMessage();
$message->setPath($file['filePath']);
$message->setSeverity($this->mapSeverity(idx($offense, 'severity', '0')));
$message->setName(nonempty(idx($offense, 'ruleId'), 'unknown'));
$message->setDescription(idx($offense, 'message'));
$message->setLine(idx($offense, 'line'));
$message->setChar(idx($offense, 'column'));
$message->setCode($this->getLinterName());
$messages[] = $message;
}
}
return $messages;
}
private function mapSeverity($eslintSeverity) {
switch($eslintSeverity) {
case '0':
return ArcanistLintSeverity::SEVERITY_ADVICE;
case '1':
return ArcanistLintSeverity::SEVERITY_WARNING;
case '2':
default:
return ArcanistLintSeverity::SEVERITY_ERROR;
}
}
}