cms/build/check_ruleset_xml.php

107 lines
3.0 KiB
PHP

<?php
/**
* This file is used to check if the exclude patterns in a PHPCS ruleset XML file are still relevant,
* i.e. the files or folders still exist, and optionally fix the XML file.
*
* This script has three optional parameters:
* --file <path> - Path to the PHPCS ruleset XML file to be checked, defaults to 'ruleset.xml' in the parent folder.
* --fix - Fix the XML file if any obsolete exclude patterns were found..
* --help - Show the help and exit.
*
* @package Joomla.Build
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
function usage($command)
{
echo PHP_EOL;
echo 'Usage: php ' . $command . ' [options]' . PHP_EOL;
echo PHP_EOL;
echo "[options]:" . PHP_EOL;
echo "--file <path>:\tPath to the PHPCS ruleset XML file to be checked, defaults to '" . dirname(__DIR__) . "/ruleset.xml'." . PHP_EOL;
echo "--fix:\t\tFix the XML file if any obsolete exclude patterns were found." . PHP_EOL;
echo "--help:\t\tShow this help output." . PHP_EOL;
echo PHP_EOL;
}
$options = getopt('', ['file:', 'fix', 'help']);
if (isset($options['help'])) {
usage($argv[0]);
exit(0);
}
$rulesetFile = $options['file'] ?? dirname(__DIR__) . '/ruleset.xml';
// Exclude patterns to be skipped from the check because the file or folder might not exist
$ignoreList = [
'^configuration.php',
'^libraries/vendor/*',
'^media/*',
'^node_modules/*',
];
echo "Checking file '" . $rulesetFile . "' ..." . PHP_EOL;
$rulesetLines = file($rulesetFile, FILE_IGNORE_NEW_LINES);
$obsoleteLineIdxs = [];
foreach ($rulesetLines as $line => $text) {
if (!preg_match('/^(?:\s*<exclude-pattern type="relative">)(.*)(?:<\/exclude-pattern>\s*)$/', $text, $matches)) {
continue;
}
if (in_array($matches[1], $ignoreList)) {
continue;
}
// Unescape dots
$path = str_replace('\.', '.', $matches[1]);
// Remove start of string anchor if used
if (substr($path, 0, 1) === '^') {
$path = substr($path, 1);
}
// Remove asterisk from the end of paths of folders
if (substr($path, -2) === '/*') {
$path = substr($path, 0, -1);
}
if (substr($path, -1) === '/') {
if (!is_dir(dirname(__DIR__) . '/' . $path)) {
echo 'Line no. ' . $line + 1 . ': Folder "' . $path . '" doesn\'t exist.' . PHP_EOL;
$obsoleteLineIdxs[] = $line;
}
} elseif (!is_file(dirname(__DIR__) . '/' . $path)) {
echo 'Line no. ' . $line + 1 . ': File "' . $path . '" doesn\'t exist.' . PHP_EOL;
$obsoleteLineIdxs[] = $line;
}
}
echo "... done." . PHP_EOL;
if (!count($obsoleteLineIdxs)) {
echo "No obsolete lines found." . PHP_EOL;
exit(0);
}
if (!isset($options['fix'])) {
exit(0);
}
foreach ($obsoleteLineIdxs as $line) {
unset($rulesetLines[$line]);
}
echo "Updating file '" . $rulesetFile . "' ..." . PHP_EOL;
file_put_contents($rulesetFile, implode(PHP_EOL, $rulesetLines));
echo "... done." . PHP_EOL;