php-extension-check/src/Command/CheckCommand.php

170 lines
5.6 KiB
PHP
Raw Normal View History

2021-05-08 21:09:48 +00:00
<?php
2021-05-08 22:50:26 +00:00
2021-05-08 21:09:48 +00:00
declare(strict_types=1);
namespace Fbrinker\ExtensionCheck\Command;
use Closure;
use Fbrinker\ExtensionCheck\Extension\ExtensionCheck;
2021-05-08 22:50:26 +00:00
use Fbrinker\ExtensionCheck\Output\SymfonyStyleFactory;
2021-05-08 21:09:48 +00:00
use Fbrinker\ExtensionCheck\Parser\FileParser;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
2021-05-08 23:57:02 +00:00
use Symfony\Component\Console\Input\InputOption;
2021-05-08 21:09:48 +00:00
use Symfony\Component\Console\Output\OutputInterface;
class CheckCommand extends Command
{
2021-05-08 22:50:26 +00:00
private const ARG_DIRECTORY = 'directory';
2021-05-08 23:57:02 +00:00
private const OPT_EXCLUDE = 'exclude';
2021-05-08 22:50:26 +00:00
2021-05-08 21:09:48 +00:00
protected static $defaultName = 'check';
2021-05-08 22:50:26 +00:00
private $symfonyStyleFactory;
2021-05-08 21:09:48 +00:00
private $fileParser;
private $extensionCheck;
public function __construct(
2021-05-08 22:50:26 +00:00
SymfonyStyleFactory $symfonyStyleFactory,
2021-05-08 21:09:48 +00:00
FileParser $fileParser,
ExtensionCheck $extensionCheck
) {
parent::__construct();
$this->symfonyStyleFactory = $symfonyStyleFactory;
$this->fileParser = $fileParser;
$this->extensionCheck = $extensionCheck;
}
protected function configure(): void
{
$this
->setDescription('Checks extensions...')
->setHelp('This command allows you to check your extensions...')
->setDefinition(
new InputDefinition([
2021-05-08 22:50:26 +00:00
new InputArgument(self::ARG_DIRECTORY, InputArgument::OPTIONAL, "The directory to scan", "./"),
2021-05-08 23:57:02 +00:00
new InputOption(self::OPT_EXCLUDE, null, InputArgument::OPTIONAL | InputOption::VALUE_IS_ARRAY, "Exclude specific extensions", []),
2021-05-08 21:09:48 +00:00
])
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = ($this->symfonyStyleFactory)($input, $output);
$io->section("Analyzing Files");
2021-05-08 22:50:26 +00:00
$scanDir = $input->getArgument(self::ARG_DIRECTORY);
if (empty($scanDir) || !\is_string($scanDir)) {
$scanDir = './';
}
2021-05-08 23:57:02 +00:00
$excludedExtensionOpts = $input->getOption(self::OPT_EXCLUDE);
$excludedExtensions = [];
if (is_array($excludedExtensionOpts) && !empty($excludedExtensionOpts)) {
foreach ($excludedExtensionOpts as $excludedExtensionOpt) {
$extensions = explode(",", $excludedExtensionOpt);
foreach ($extensions as $extension) {
$excludedExtensions[] = \strtolower(trim($extension));
}
}
$this->extensionCheck->setExcludedExtenstions($excludedExtensions);
}
$this->fileParser->scanForFiles($scanDir);
2021-05-08 21:09:48 +00:00
$fileCount = $this->fileParser->getFileCount();
$io->text(sprintf('Files: %d', $fileCount));
$io->newLine();
$progressBar = $this->getStyledProgressBar($output, $fileCount);
$progressBar->start();
[$classes, $functions, $constants] = $this->fileParser->parseFiles(
$this->getProgressBarClosure($progressBar)
);
$progressBar->finish();
$io->newLine(2);
2021-05-08 22:50:26 +00:00
$io->text("Calls to check:");
2021-05-08 21:09:48 +00:00
$io->text(sprintf(
"%d Classes, %d Functions, %d Constants",
count($classes),
count($functions),
count($constants)
));
$io->section("Checking Extension Usages");
2021-05-08 23:57:02 +00:00
$io->text(sprintf('Loaded Extensions: %d', $this->extensionCheck->getLoadedExtensionsCount()));
if (!empty($excludedExtensions)) {
$io->text(sprintf("Excluded Extensions: %s", implode(", ", $excludedExtensions)));
}
2021-05-08 21:09:48 +00:00
$io->newLine();
$totalUsagesToCheck = count($classes) + count($functions);
$progressBar = $this->getStyledProgressBar($output, $totalUsagesToCheck);
$progressBar->start();
$usedExtensions = $this->extensionCheck->checkUsages(
$classes,
$functions,
$constants,
$this->getProgressBarClosure($progressBar)
);
$progressBar->finish();
$io->newLine(2);
$unusedExtensions = $this->extensionCheck->getUnused(array_keys($usedExtensions));
$io->text(sprintf(
"<fg=green>%d</> Used, <fg=red>%d</> Unused",
count($usedExtensions),
2021-05-08 22:50:26 +00:00
count($unusedExtensions)
2021-05-08 21:09:48 +00:00
));
$io->section("Result");
$io->text("Used Extensions:");
$tmp = array_keys($usedExtensions);
natcasesort($tmp);
2021-05-08 22:50:26 +00:00
foreach ($tmp as $usedExtension) {
2021-05-08 21:09:48 +00:00
$reason = $usedExtensions[$usedExtension];
2021-05-08 22:50:26 +00:00
$io->text(sprintf(
' <fg=green>%s</> %s <comment>[Usage: %s]</>',
2021-05-08 21:09:48 +00:00
"\u{2713}",
$usedExtension,
implode(", ", array_keys($reason))
));
}
$io->newLine();
$io->text("Unused Extensions:");
2021-05-08 22:50:26 +00:00
foreach ($unusedExtensions as $unusedExtension) {
$io->text(sprintf(
' <fg=red>%s</> %s',
2021-05-08 21:09:48 +00:00
"\u{2717}",
$unusedExtension
));
}
return Command::SUCCESS;
}
2021-05-08 22:50:26 +00:00
private function getProgressBarClosure(ProgressBar $progressBar): Closure
{
return function () use ($progressBar) {
2021-05-08 21:09:48 +00:00
$progressBar->advance();
};
}
2021-05-08 22:50:26 +00:00
private function getStyledProgressBar(OutputInterface $output, int $maxValue): ProgressBar
{
2021-05-08 21:09:48 +00:00
$progressBar = new ProgressBar($output, $maxValue);
$progressBar->setBarCharacter('<info>=</info>');
$progressBar->setEmptyBarCharacter(' ');
$progressBar->setProgressCharacter('>');
return $progressBar;
}
2021-05-08 22:50:26 +00:00
}