diff --git a/src/lint/linter/ArcanistTextLinter.php b/src/lint/linter/ArcanistTextLinter.php --- a/src/lint/linter/ArcanistTextLinter.php +++ b/src/lint/linter/ArcanistTextLinter.php @@ -5,8 +5,8 @@ */ final class ArcanistTextLinter extends ArcanistLinter { - const LINT_DOS_NEWLINE = 1; - const LINT_TAB_LITERAL = 2; + const LINT_NEWLINE = 1; + const LINT_INDENT_STYLE = 2; const LINT_LINE_WRAP = 3; const LINT_EOF_NEWLINE = 4; const LINT_BAD_CHARSET = 5; @@ -15,6 +15,7 @@ const LINT_EOF_WHITESPACE = 9; private $maxLineLength = 80; + private $parser; public function getInfoName() { return pht('Basic Text Linter'); @@ -77,8 +78,8 @@ public function getLintNameMap() { return array( - self::LINT_DOS_NEWLINE => pht('DOS Newlines'), - self::LINT_TAB_LITERAL => pht('Tab Literal'), + self::LINT_NEWLINE => pht('Newlines'), + self::LINT_INDENT_STYLE => pht('Indent Style'), self::LINT_LINE_WRAP => pht('Line Too Long'), self::LINT_EOF_NEWLINE => pht('File Does Not End in Newline'), self::LINT_BAD_CHARSET => pht('Bad Charset'), @@ -88,6 +89,11 @@ ); } + public function willLintPaths(array $paths) { + $root = $this->getEngine()->getWorkingCopy()->getProjectRoot(); + $this->parser = new PhutilEditorConfig($root); + } + public function lintPath($path) { if (!strlen($this->getData($path))) { // If the file is empty, don't bother; particularly, don't require @@ -117,6 +123,17 @@ } protected function lintNewlines($path) { + switch ($this->getEditorConfig($path, 'end_of_line')) { + case 'lf': + break; + + case 'cr': + case 'lfcr': + default: + // TODO: Handle these cases. + return; + } + $data = $this->getData($path); $pos = strpos($this->getData($path), "\r"); @@ -135,6 +152,10 @@ } protected function lintTabs($path) { + if ($this->getEditorConfig($path, 'indent_style') !== 'spaces') { + return; + } + $pos = strpos($this->getData($path), "\t"); if ($pos !== false) { $this->raiseLintAtOffset( @@ -166,6 +187,10 @@ } protected function lintEOFNewline($path) { + if ($this->getEditorConfig($path, 'insert_final_newline') !== false) { + return; + } + $data = $this->getData($path); if (!strlen($data) || $data[strlen($data) - 1] != "\n") { $this->raiseLintAtOffset( @@ -178,8 +203,13 @@ } protected function lintCharset($path) { - $data = $this->getData($path); + if ($this->getEditorConfig($path, 'charset') !== 'utf-8') { + return; + } + + // TODO: Handle other charsets. + $data = $this->getData($path); $matches = null; $bad = '[^\x09\x0A\x20-\x7E]'; $preg = preg_match_all( @@ -210,8 +240,11 @@ } protected function lintTrailingWhitespace($path) { - $data = $this->getData($path); + if ($this->getEditorConfig($path, 'trim_trailing_whitespace') !== false) { + return; + } + $data = $this->getData($path); $matches = null; $preg = preg_match_all( '/ +$/m', @@ -238,8 +271,11 @@ } protected function lintBOFWhitespace($path) { - $data = $this->getData($path); + if ($this->getEditorConfig($path, 'trim_trailing_whitespace') !== false) { + return; + } + $data = $this->getData($path); $matches = null; $preg = preg_match( '/^\s*\n/', @@ -263,8 +299,11 @@ } protected function lintEOFWhitespace($path) { - $data = $this->getData($path); + if ($this->getEditorConfig($path, 'trim_trailing_whitespace') !== false) { + return; + } + $data = $this->getData($path); $matches = null; $preg = preg_match( '/(?<=\n)\s+$/', @@ -287,4 +326,10 @@ ''); } + private function getEditorConfig($path, $key) { + return $this->parser->getConfig( + $this->getEngine()->getFilePathOnDisk($path), + $key); + } + }