diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fbb073 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +/composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..8ccdc91 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "gordinskiy/line-length-checker", + "description": " PHP-CS-Fixer rule to check line length", + "type": "library", + "require": { + "php": "^7.4 || ^8.0", + "friendsofphp/php-cs-fixer": "^3.35" + }, + "license": "MIT", + "autoload": { + "psr-4": { + "Gordinskiy\\LineLengthChecker\\": "src/" + } + }, + "authors": [ + { + "name": "Dmitriy Gordinskiy", + "email": "dmitriy.gordinskiy94@gmail.com" + } + ] +} diff --git a/src/Rules/LineLengthLimit.php b/src/Rules/LineLengthLimit.php new file mode 100644 index 0000000..c160bee --- /dev/null +++ b/src/Rules/LineLengthLimit.php @@ -0,0 +1,151 @@ +getContent(); + + if (str_contains($tokenContent, PHP_EOL)) { + $lines = explode(PHP_EOL, $tokenContent); + + $previousLineEnd = array_shift($lines); + $nextLineBegin = array_pop($lines); + + if (!self::isValidLength($lineLength + strlen($previousLineEnd))) { + return true; + } + + foreach ($lines as $line) { + if (!self::isValidLength(strlen($line))) { + return true; + } + } + + $lineLength = strlen($nextLineBegin); + } else { + $lineLength += strlen($tokenContent); + } + } + + return false; + } + + private static function isValidLength(int $length): bool + { + return $length <= 120; + } + + public function fix(\SplFileInfo $file, Tokens $tokens): void + { + if (!$this->isDryRun()) { + return; + } + + $index = 0; + $lineLength = 0; + + while ($token = $tokens[$index] ?? null) { + $tokenContent = $token->getContent(); + + $lineBreaksCount = substr_count($tokenContent, PHP_EOL); + + if ($lineBreaksCount === 0) { + $lineLength += strlen($tokenContent); + } elseif ($lineBreaksCount === 1) { + if (!self::isValidLength($lineLength)) { + $tokens->insertAt($index, [ + new Token([T_WHITESPACE, ' ']), + new Token([T_COMMENT, '# Line too long']) + ]); + } + + $lineLength = strlen(str_replace(PHP_EOL, '', $tokenContent)); + } else { + $mustBeRebuild = false; + $buffer = $lines = explode(PHP_EOL, $tokenContent); + + $previousLineEnd = array_shift($lines); + $nextLineBegin = array_pop($lines); + + if (!self::isValidLength($lineLength + strlen($previousLineEnd))) { + $buffer[0] = $buffer[0] . ' # Line too long'; + $mustBeRebuild = true; + } + + foreach ($lines as $key => $line) { + if (!self::isValidLength(strlen($line))) { + $buffer[$key + 1] .= ' # Line too long'; + $mustBeRebuild = true; + } + } + + if ($mustBeRebuild) { + $tokens->clearAt($index); + $tokens->insertAt($index, [new Token([$token->getId(), implode(PHP_EOL, $buffer)])]); + } + + $lineLength = strlen($nextLineBegin); + } + + $index++; + } + } + + private function isDryRun(): bool + { + if (in_array('check', $_SERVER['argv'])) { + return true; + } + + if (in_array('--dry-run', $_SERVER['argv'])) { + return true; + } + + return false; + } +}