diff --git a/composer.json b/composer.json index f4583fe..8310e61 100644 --- a/composer.json +++ b/composer.json @@ -23,10 +23,14 @@ "squizlabs/php_codesniffer": "dev-api-friendly as 3.x-dev", "drupal/coder": "^8.3", "phpmd/phpmd": "dev-api-friendly", - "phploc/phploc": "^6.0" + "phploc/phploc": "^6.0", + "symfony/console": "^5.2" }, "require-dev": { "clue/phar-composer": "^1.1" }, + "autoload": { + "psr-0": { "": "src/" } + }, "bin": ["src/index.php"] } diff --git a/src/PHPDebt/Console/Command/PHPDebtCommand.php b/src/PHPDebt/Console/Command/PHPDebtCommand.php new file mode 100644 index 0000000..b9cb37d --- /dev/null +++ b/src/PHPDebt/Console/Command/PHPDebtCommand.php @@ -0,0 +1,133 @@ +setName('phpdebt') + ->addArgument('path', InputArgument::REQUIRED, 'The path of the file or directory that needs to be scanned.') + ->addOption('standard', 's', InputOption::VALUE_REQUIRED, 'The path of the phpcs.xml.dist') + ->setDescription('This tool provides code quality score based on a number of standards from existing code analysis tools.'); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) { + $code_faults = 0; + $standards_faults = 0; + $path = $input->getArgument('path'); + $option = $input->getOption('standard'); + + $debt_md = new PHPDebtMD(); + $code_faults += $debt_md->process($path, 'cleancode'); + $code_faults += $debt_md->process($path, 'codesize'); + $code_faults += $debt_md->process($path, 'design'); + $code_faults += $debt_md->process($path, 'naming'); + $code_faults += $debt_md->process($path, 'unusedcode'); + + $runner = new Runner(); + // If PHPCS config is provided, then execute this. + if ($option) { + define('PHP_CODESNIFFER_CBF', FALSE); + $runner->config = new Config(["--standard=$option"]); + $runner->config->files = [$path]; + + $runner->init(); + $faults = $runner->run(); + print "phpcs Drupal: " . $faults . "\n"; + $standards_faults += $faults; + + $faults = $runner->run(); + print "phpcs DrupalPractice: " . $faults . "\n"; + $standards_faults += $faults; + } + else { + $runner->config = new Config(); + $runner->config->files = [$path]; + $runner->config->standards = ['Drupal']; + $runner->config->extensions = [ + 'php' => 'PHP', + 'module' => 'PHP', + 'inc' => 'PHP', + 'install' => 'PHP', + 'test' => 'PHP', + 'profile' => 'PHP', + 'theme' => 'PHP', + 'css' => 'CSS', + 'info' => 'PHP', + 'js' => 'JS', + ]; + $runner->init(); + $faults = $runner->run(); + print "phpcs Drupal: " . $faults . "\n"; + $standards_faults += $faults; + + $runner->config->standards = ['DrupalPractice']; + $runner->init(); + $faults = $runner->run(); + print "phpcs DrupalPractice: " . $faults . "\n"; + $standards_faults += $faults; + } + + // Lines of Code should be working on and anything unique about getting his local back up to date? + $files = (new FinderFacade([$path], [], ['*.php', '*.module', '*.install', '*.inc', '*.js', '*.scss'], []))->findFiles(); + $count = (new Analyser)->countFiles($files, TRUE); + $total_lines = $count['ncloc']; + + $faults = $code_faults + $standards_faults; + $percent = ($faults / $total_lines) * 100; + + // Summary + print "Total Faults: " . $faults . "\n"; + print "Total Lines: " . $total_lines . "\n"; + print "Quality Score: " . number_format($percent, 2) . " faults per 100 lines\n"; + + $ratio = 200; + $base = ($total_lines / $ratio) * sqrt($percent); + + if ($percent > 25) { + $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 25)); + print "Estimate to get to 25: " . number_format($base - $hours, 2) . " hours\n"; + } + + if ($percent > 10) { + $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 10)); + print "Estimate to get to 10: " . number_format($base - $hours, 2) . " hours\n"; + } + + if ($percent > 5) { + $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 5)); + print "Estimate to get to 5: " . number_format($base - $hours, 2) . " hours\n"; + } + + if ($percent > 3) { + $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 3)); + print "Estimate to get to 3: " . number_format($base - $hours, 2) . " hours\n"; + } + return 0; + } + +} diff --git a/src/PHPDebt/PHPDebtMD.php b/src/PHPDebt/PHPDebtMD.php new file mode 100644 index 0000000..209d874 --- /dev/null +++ b/src/PHPDebt/PHPDebtMD.php @@ -0,0 +1,42 @@ +runReport( + $path, + $type, + $ruleSetFactory + ); + + $faults = count($report->getRuleViolations()); + + print "phpmd " . $type . ": " . $faults . "\n"; + + return count($report->getRuleViolations()); + } + +} diff --git a/src/index.php b/src/index.php index 71c9a36..5e3005f 100644 --- a/src/index.php +++ b/src/index.php @@ -3,104 +3,11 @@ require __DIR__ . '/../vendor/autoload.php'; require __DIR__ . '/../vendor/squizlabs/php_codesniffer/autoload.php'; -use PHPMD\PHPMD; -use PHPMD\RuleSetFactory; - -use SebastianBergmann\FinderFacade\FinderFacade; -use SebastianBergmann\PHPLOC\Analyser; - -use PHP_CodeSniffer\Runner; -use PHP_CodeSniffer\Config; - -$code_faults = 0; -$standards_faults = 0; -$path = $argv[1]; - -function phpMD($path, $type) { - $ruleSetFactory = new RuleSetFactory(); - $phpmd = new PHPMD(); - - $report = $phpmd->runReport( - $path, - $type, - $ruleSetFactory - ); - - $faults = count($report->getRuleViolations()); - - print "phpmd " . $type . ": " . $faults . "\n"; - - return count($report->getRuleViolations()); -} - -$code_faults += phpMD($path, 'cleancode'); -$code_faults += phpMD($path, 'codesize'); -$code_faults += phpMD($path, 'design'); -$code_faults += phpMD($path, 'naming'); -$code_faults += phpMD($path, 'unusedcode'); - - -$runner = new Runner(); - -$runner->config = new Config(); -$runner->config->files = [$path]; -$runner->config->standards = ['Drupal']; -$runner->config->extensions = [ - 'php' => 'PHP', - 'module' => 'PHP', - 'inc' => 'PHP', - 'install' => 'PHP', - 'test' => 'PHP', - 'profile' => 'PHP', - 'theme' => 'PHP', - 'css' => 'CSS', - 'info' => 'PHP', - 'js' => 'JS' -]; -$runner->init(); - -$faults = $runner->run(); -print "phpcs Drupal: " . $faults . "\n"; -$standards_faults += $faults; - -$runner->config->standards = ['DrupalPractice']; -$runner->init(); -$faults = $runner->run(); -print "phpcs DrupalPractice: " . $faults . "\n"; -$standards_faults += $faults; - -// Lines of Code -$files = (new FinderFacade([$path], [], ['*.php', '*.module', '*.install', '*.inc', '*.js', '*.scss'], []))->findFiles(); -$count = (new Analyser)->countFiles($files, true); -$total_lines = $count['ncloc']; - -$faults = $code_faults + $standards_faults; -$percent = ($faults / $total_lines) * 100; - -// Summary -print "Total Faults: " . $faults . "\n"; -print "Total Lines: " . $total_lines . "\n"; -print "Quality Score: " . number_format($percent, 2) . " faults per 100 lines\n"; - -$ratio = 200; -$base = ($total_lines / $ratio) * sqrt($percent); - -if ($percent > 25) { - $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 25)); - print "Estimate to get to 25: " . number_format($base - $hours, 2) . " hours\n"; -} - -if ($percent > 10) { - $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 10)); - print "Estimate to get to 10: " . number_format($base - $hours, 2) . " hours\n"; -} - -if ($percent > 5) { - $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 5)); - print "Estimate to get to 5: " . number_format($base - $hours, 2) . " hours\n"; -} - -if ($percent > 3) { - $hours = ($total_lines / $ratio) * sqrt($percent - ($percent - 3)); - print "Estimate to get to 3: " . number_format($base - $hours, 2) . " hours\n"; -} \ No newline at end of file +use PHPDebt\Console\Command\PHPDebtCommand; +use Symfony\Component\Console\Application; + +$command = new PHPDebtCommand(); +$app = new Application(); +$app->add($command); +$app->setDefaultCommand($command->getName(), TRUE); +$app->run();