Refactor duplicated dependencies

This commit is contained in:
Florian Brinker 2021-05-09 01:57:02 +02:00
parent 7f2305ec04
commit dc91a39b4c
5 changed files with 84 additions and 105 deletions

View File

@ -6,7 +6,6 @@ namespace Fbrinker\ExtensionCheck\Command;
use Closure;
use Fbrinker\ExtensionCheck\Extension\ExtensionCheck;
use Fbrinker\ExtensionCheck\Extension\ExtensionDetails;
use Fbrinker\ExtensionCheck\Output\SymfonyStyleFactory;
use Fbrinker\ExtensionCheck\Parser\FileParser;
use Symfony\Component\Console\Command\Command;
@ -14,28 +13,27 @@ use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CheckCommand extends Command
{
private const ARG_DIRECTORY = 'directory';
private const OPT_EXCLUDE = 'exclude';
protected static $defaultName = 'check';
private $symfonyStyleFactory;
private $fileParser;
private $extensionDetails;
private $extensionCheck;
public function __construct(
SymfonyStyleFactory $symfonyStyleFactory,
FileParser $fileParser,
ExtensionDetails $extensionDetails,
ExtensionCheck $extensionCheck
) {
parent::__construct();
$this->symfonyStyleFactory = $symfonyStyleFactory;
$this->fileParser = $fileParser;
$this->extensionDetails = $extensionDetails;
$this->extensionCheck = $extensionCheck;
}
@ -47,6 +45,7 @@ class CheckCommand extends Command
->setDefinition(
new InputDefinition([
new InputArgument(self::ARG_DIRECTORY, InputArgument::OPTIONAL, "The directory to scan", "./"),
new InputOption(self::OPT_EXCLUDE, null, InputArgument::OPTIONAL | InputOption::VALUE_IS_ARRAY, "Exclude specific extensions", []),
])
);
}
@ -61,8 +60,20 @@ class CheckCommand extends Command
if (empty($scanDir) || !\is_string($scanDir)) {
$scanDir = './';
}
$this->fileParser->scanForFiles($scanDir);
$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);
$fileCount = $this->fileParser->getFileCount();
$io->text(sprintf('Files: %d', $fileCount));
$io->newLine();
@ -85,7 +96,10 @@ class CheckCommand extends Command
));
$io->section("Checking Extension Usages");
$io->text(sprintf('Loaded Extensions: %d', $this->extensionDetails->getLoadedExtensionsCount()));
$io->text(sprintf('Loaded Extensions: %d', $this->extensionCheck->getLoadedExtensionsCount()));
if (!empty($excludedExtensions)) {
$io->text(sprintf("Excluded Extensions: %s", implode(", ", $excludedExtensions)));
}
$io->newLine();
$totalUsagesToCheck = count($classes) + count($functions);
$progressBar = $this->getStyledProgressBar($output, $totalUsagesToCheck);

View File

@ -21,7 +21,6 @@ class CheckCommandFactory implements FactoryInterface
return new CheckCommand(
$container->get(SymfonyStyleFactory::class),
$container->get(FileParser::class),
$container->get(ExtensionDetails::class),
$container->get(ExtensionCheck::class)
);
}

View File

@ -8,14 +8,29 @@ use Closure;
class ExtensionCheck
{
private $extensionDetails;
/** @var string[] */
private $excludedExtensions = [];
public function __construct(ExtensionDetails $extensionDetails)
{
$this->extensionDetails = $extensionDetails;
}
/**
* @param string[] $excludedExtensions
*/
public function setExcludedExtenstions(array $excludedExtensions): void
{
$this->excludedExtensions = $excludedExtensions;
}
public function getLoadedExtensionsCount(): int
{
return $this->extensionDetails->getLoadedExtensionsCount();
}
/**
* @param string[] $usedExtensions
* @return string[]
@ -24,7 +39,8 @@ class ExtensionCheck
{
return array_diff(
$this->extensionDetails->getLoadedExtensions(),
$usedExtensions
$usedExtensions,
$this->excludedExtensions
);
}
@ -37,9 +53,10 @@ class ExtensionCheck
public function checkUsages(array $classes, array $functions, array $constants, Closure $callback)
{
$usedExtensions = [];
$extensionMap = $this->extensionDetails->getExtensionMap($this->excludedExtensions);
foreach ($classes as $class) {
$extension = $this->checkClass($class);
$extension = $extensionMap->checkClass($class);
if (!empty($extension)) {
$usedExtensions[$extension]['class'] = true;
@ -49,7 +66,7 @@ class ExtensionCheck
}
foreach ($functions as $function) {
$extension = $this->checkFunction($function);
$extension = $extensionMap->checkFunction($function);
if (!empty($extension)) {
$usedExtensions[$extension]['function'] = true;
@ -59,7 +76,7 @@ class ExtensionCheck
}
foreach ($constants as $constant) {
$extension = $this->checkConstant($constant);
$extension = $extensionMap->checkConstant($constant);
if (!empty($extension)) {
$usedExtensions[$extension]['constant'] = true;
@ -70,7 +87,7 @@ class ExtensionCheck
$tmp = array_keys($usedExtensions);
foreach ($tmp as $usedExtension) {
$requiredExtensions = $this->checkRequiredDependency($usedExtension);
$requiredExtensions = $extensionMap->checkRequiredDependency($usedExtension);
if (!empty($requiredExtensions)) {
foreach ($requiredExtensions as $requiredExtension) {
@ -83,51 +100,4 @@ class ExtensionCheck
return $usedExtensions;
}
private function checkClass(string $class): ?string
{
$classMap = $this->extensionDetails->getExtensionClassMap();
if (!isset($classMap[$class])) {
return null;
}
return $classMap[$class];
}
private function checkFunction(string $function): ?string
{
$functionMap = $this->extensionDetails->getExtensionFunctionMap();
if (!isset($functionMap[$function])) {
return null;
}
return $functionMap[$function];
}
private function checkConstant(string $function): ?string
{
$constantMap = $this->extensionDetails->getExtensionConstantMap();
if (!isset($constantMap[$function])) {
return null;
}
return $constantMap[$function];
}
/**
* @return string[]
*/
private function checkRequiredDependency(string $extension): array
{
$dependencyMap = $this->extensionDetails->getExtensionDependencyMap();
if (!isset($dependencyMap[$extension]['required'])) {
return [];
}
return $dependencyMap[$extension]['required'];
}
}

View File

@ -33,61 +33,25 @@ class ExtensionDetails
}
/**
* @return array<string,string>
* @param string[] $excludedExtensions
*/
public function getExtensionClassMap(): array
public function getExtensionMap(array $excludedExtensions): ExtensionMap
{
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
if ($this->extensionMap === null) {
$this->extensionMap = $this->buildExtensionMaps($excludedExtensions);
}
return $this->extensionMap->classes ?? [];
return $this->extensionMap;
}
/**
* @return array<string,string>
* @param string[] $excludedExtensions
*/
public function getExtensionFunctionMap(): array
{
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
return $this->extensionMap->functions ?? [];
}
/**
* @return array<string,string>
*/
public function getExtensionConstantMap(): array
{
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
return $this->extensionMap->constants ?? [];
}
/**
* @return array<string,array<string,string[]>>
*/
public function getExtensionDependencyMap(): array
{
if (empty($this->extensionMap)) {
$this->buildExtensionMaps();
}
return $this->extensionMap->dependencies ?? [];
}
/**
* @param string[] $extensionsToExclude
*/
private function buildExtensionMaps(array $extensionsToExclude = []): void
private function buildExtensionMaps(array $excludedExtensions): ExtensionMap
{
$extensionClasses = $extensionFunctions = $extensionConstants = $extensionDependencies = $uncheckedExtensions = [];
foreach ($this->loadedExtensions as $loadedExtension) {
if (in_array(strtolower($loadedExtension), array_map('strtolower', $extensionsToExclude))) {
if (in_array($loadedExtension, $excludedExtensions, true)) {
continue;
}
@ -121,9 +85,14 @@ class ExtensionDetails
if (!empty($dependencies)) {
natcasesort($dependencies);
foreach ($dependencies as $dependency => $status) {
if (in_array($dependency, $excludedExtensions, true)) {
continue;
}
if (!isset($extensionDependencies[$loadedExtension][strtolower($status)])) {
$extensionDependencies[$loadedExtension][strtolower($status)] = [];
}
$extensionDependencies[$loadedExtension][strtolower($status)][] = $dependency;
}
}
@ -136,7 +105,7 @@ class ExtensionDetails
}
}
$this->extensionMap = new ExtensionMap(
return new ExtensionMap(
$extensionClasses,
$extensionFunctions,
$extensionConstants,

View File

@ -39,4 +39,31 @@ class ExtensionMap
$this->dependencies = $dependencies;
$this->unchecked = $unchecked;
}
public function checkClass(string $class): ?string
{
return $this->classes[$class] ?? null;
}
public function checkFunction(string $function): ?string
{
return $this->functions[$function] ?? null;
}
public function checkConstant(string $constant): ?string
{
return $this->constants[$constant] ?? null;
}
/**
* @return string[]
*/
public function checkRequiredDependency(string $extension): array
{
if (!isset($this->dependencies[$extension]['required'])) {
return [];
}
return $this->dependencies[$extension]['required'];
}
}