1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-10-25 10:08:50 +02:00
phorge-arcanist/src/lint/linter/ArcanistTextLinter.php

224 lines
5.6 KiB
PHP
Raw Normal View History

2011-01-10 00:22:25 +01:00
<?php
/*
* Copyright 2012 Facebook, Inc.
2011-01-10 00:22:25 +01:00
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Enforces basic text file rules.
*
* @group linter
*/
final class ArcanistTextLinter extends ArcanistLinter {
2011-01-10 00:22:25 +01:00
const LINT_DOS_NEWLINE = 1;
const LINT_TAB_LITERAL = 2;
const LINT_LINE_WRAP = 3;
const LINT_EOF_NEWLINE = 4;
const LINT_BAD_CHARSET = 5;
const LINT_TRAILING_WHITESPACE = 6;
const LINT_NO_COMMIT = 7;
2011-01-10 00:22:25 +01:00
private $maxLineLength = 80;
public function setMaxLineLength($new_length) {
$this->maxLineLength = $new_length;
return $this;
}
public function willLintPaths(array $paths) {
return;
}
public function getLinterName() {
return 'TXT';
}
public function getLintSeverityMap() {
return array(
self::LINT_LINE_WRAP => ArcanistLintSeverity::SEVERITY_WARNING,
self::LINT_TRAILING_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX,
2011-01-10 00:22:25 +01:00
);
}
public function getLintNameMap() {
return array(
self::LINT_DOS_NEWLINE => 'DOS Newlines',
self::LINT_TAB_LITERAL => 'Tab Literal',
self::LINT_LINE_WRAP => 'Line Too Long',
self::LINT_EOF_NEWLINE => 'File Does Not End in Newline',
self::LINT_BAD_CHARSET => 'Bad Charset',
self::LINT_TRAILING_WHITESPACE => 'Trailing Whitespace',
self::LINT_NO_COMMIT => 'Explicit @no'.'commit',
2011-01-10 00:22:25 +01:00
);
}
public function lintPath($path) {
if (!strlen($this->getData($path))) {
// If the file is empty, don't bother; particularly, don't require
// the user to add a newline.
return;
}
2011-01-10 00:22:25 +01:00
$this->lintNewlines($path);
$this->lintTabs($path);
if ($this->didStopAllLinters()) {
return;
}
$this->lintCharset($path);
if ($this->didStopAllLinters()) {
return;
}
$this->lintLineLength($path);
$this->lintEOFNewline($path);
$this->lintTrailingWhitespace($path);
if ($this->getEngine()->getCommitHookMode()) {
$this->lintNoCommit($path);
}
2011-01-10 00:22:25 +01:00
}
protected function lintNewlines($path) {
$pos = strpos($this->getData($path), "\r");
if ($pos !== false) {
$this->raiseLintAtOffset(
$pos,
self::LINT_DOS_NEWLINE,
'You must use ONLY Unix linebreaks ("\n") in source code.',
"\r");
if ($this->isMessageEnabled(self::LINT_DOS_NEWLINE)) {
$this->stopAllLinters();
}
2011-01-10 00:22:25 +01:00
}
}
protected function lintTabs($path) {
$pos = strpos($this->getData($path), "\t");
if ($pos !== false) {
$this->raiseLintAtOffset(
$pos,
self::LINT_TAB_LITERAL,
'Configure your editor to use spaces for indentation.',
"\t");
}
}
protected function lintLineLength($path) {
$lines = explode("\n", $this->getData($path));
$width = $this->maxLineLength;
foreach ($lines as $line_idx => $line) {
if (strlen($line) > $width) {
$this->raiseLintAtLine(
$line_idx + 1,
1,
self::LINT_LINE_WRAP,
'This line is '.number_format(strlen($line)).' characters long, '.
'but the convention is '.$width.' characters.',
$line);
}
}
}
protected function lintEOFNewline($path) {
$data = $this->getData($path);
if (!strlen($data) || $data[strlen($data) - 1] != "\n") {
$this->raiseLintAtOffset(
strlen($data),
self::LINT_EOF_NEWLINE,
"Files must end in a newline.",
'',
"\n");
}
}
protected function lintCharset($path) {
$data = $this->getData($path);
$matches = null;
$preg = preg_match_all(
'/[^\x09\x0A\x20-\x7E]+/',
$data,
$matches,
PREG_OFFSET_CAPTURE);
if (!$preg) {
return;
}
foreach ($matches[0] as $match) {
list($string, $offset) = $match;
$this->raiseLintAtOffset(
$offset,
self::LINT_BAD_CHARSET,
'Source code should contain only ASCII bytes with ordinal decimal '.
'values between 32 and 126 inclusive, plus linefeed. Do not use UTF-8 '.
'or other multibyte charsets.',
$string);
}
if ($this->isMessageEnabled(self::LINT_BAD_CHARSET)) {
$this->stopAllLinters();
}
2011-01-10 00:22:25 +01:00
}
protected function lintTrailingWhitespace($path) {
$data = $this->getData($path);
$matches = null;
$preg = preg_match_all(
'/ +$/m',
$data,
$matches,
PREG_OFFSET_CAPTURE);
if (!$preg) {
return;
}
foreach ($matches[0] as $match) {
list($string, $offset) = $match;
$this->raiseLintAtOffset(
$offset,
self::LINT_TRAILING_WHITESPACE,
'This line contains trailing whitespace.',
$string,
'');
}
}
private function lintNoCommit($path) {
$data = $this->getData($path);
$deadly = '@no'.'commit';
$offset = strpos($data, $deadly);
if ($offset !== false) {
$this->raiseLintAtOffset(
$offset,
self::LINT_NO_COMMIT,
'This file is explicitly marked as "'.$deadly.'", which blocks '.
'commits.',
$deadly);
}
}
2011-01-10 00:22:25 +01:00
}