Refactor duplicated dependencies
This commit is contained in:
parent
7f2305ec04
commit
dc91a39b4c
@ -6,7 +6,6 @@ namespace Fbrinker\ExtensionCheck\Command;
|
|||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
use Fbrinker\ExtensionCheck\Extension\ExtensionCheck;
|
use Fbrinker\ExtensionCheck\Extension\ExtensionCheck;
|
||||||
use Fbrinker\ExtensionCheck\Extension\ExtensionDetails;
|
|
||||||
use Fbrinker\ExtensionCheck\Output\SymfonyStyleFactory;
|
use Fbrinker\ExtensionCheck\Output\SymfonyStyleFactory;
|
||||||
use Fbrinker\ExtensionCheck\Parser\FileParser;
|
use Fbrinker\ExtensionCheck\Parser\FileParser;
|
||||||
use Symfony\Component\Console\Command\Command;
|
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\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputDefinition;
|
use Symfony\Component\Console\Input\InputDefinition;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
class CheckCommand extends Command
|
class CheckCommand extends Command
|
||||||
{
|
{
|
||||||
private const ARG_DIRECTORY = 'directory';
|
private const ARG_DIRECTORY = 'directory';
|
||||||
|
private const OPT_EXCLUDE = 'exclude';
|
||||||
|
|
||||||
protected static $defaultName = 'check';
|
protected static $defaultName = 'check';
|
||||||
private $symfonyStyleFactory;
|
private $symfonyStyleFactory;
|
||||||
private $fileParser;
|
private $fileParser;
|
||||||
private $extensionDetails;
|
|
||||||
private $extensionCheck;
|
private $extensionCheck;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SymfonyStyleFactory $symfonyStyleFactory,
|
SymfonyStyleFactory $symfonyStyleFactory,
|
||||||
FileParser $fileParser,
|
FileParser $fileParser,
|
||||||
ExtensionDetails $extensionDetails,
|
|
||||||
ExtensionCheck $extensionCheck
|
ExtensionCheck $extensionCheck
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->symfonyStyleFactory = $symfonyStyleFactory;
|
$this->symfonyStyleFactory = $symfonyStyleFactory;
|
||||||
$this->fileParser = $fileParser;
|
$this->fileParser = $fileParser;
|
||||||
$this->extensionDetails = $extensionDetails;
|
|
||||||
$this->extensionCheck = $extensionCheck;
|
$this->extensionCheck = $extensionCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +45,7 @@ class CheckCommand extends Command
|
|||||||
->setDefinition(
|
->setDefinition(
|
||||||
new InputDefinition([
|
new InputDefinition([
|
||||||
new InputArgument(self::ARG_DIRECTORY, InputArgument::OPTIONAL, "The directory to scan", "./"),
|
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)) {
|
if (empty($scanDir) || !\is_string($scanDir)) {
|
||||||
$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();
|
$fileCount = $this->fileParser->getFileCount();
|
||||||
$io->text(sprintf('Files: %d', $fileCount));
|
$io->text(sprintf('Files: %d', $fileCount));
|
||||||
$io->newLine();
|
$io->newLine();
|
||||||
@ -85,7 +96,10 @@ class CheckCommand extends Command
|
|||||||
));
|
));
|
||||||
|
|
||||||
$io->section("Checking Extension Usages");
|
$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();
|
$io->newLine();
|
||||||
$totalUsagesToCheck = count($classes) + count($functions);
|
$totalUsagesToCheck = count($classes) + count($functions);
|
||||||
$progressBar = $this->getStyledProgressBar($output, $totalUsagesToCheck);
|
$progressBar = $this->getStyledProgressBar($output, $totalUsagesToCheck);
|
||||||
|
@ -21,7 +21,6 @@ class CheckCommandFactory implements FactoryInterface
|
|||||||
return new CheckCommand(
|
return new CheckCommand(
|
||||||
$container->get(SymfonyStyleFactory::class),
|
$container->get(SymfonyStyleFactory::class),
|
||||||
$container->get(FileParser::class),
|
$container->get(FileParser::class),
|
||||||
$container->get(ExtensionDetails::class),
|
|
||||||
$container->get(ExtensionCheck::class)
|
$container->get(ExtensionCheck::class)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,29 @@ use Closure;
|
|||||||
|
|
||||||
class ExtensionCheck
|
class ExtensionCheck
|
||||||
{
|
{
|
||||||
|
|
||||||
private $extensionDetails;
|
private $extensionDetails;
|
||||||
|
|
||||||
|
/** @var string[] */
|
||||||
|
private $excludedExtensions = [];
|
||||||
|
|
||||||
public function __construct(ExtensionDetails $extensionDetails)
|
public function __construct(ExtensionDetails $extensionDetails)
|
||||||
{
|
{
|
||||||
$this->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
|
* @param string[] $usedExtensions
|
||||||
* @return string[]
|
* @return string[]
|
||||||
@ -24,7 +39,8 @@ class ExtensionCheck
|
|||||||
{
|
{
|
||||||
return array_diff(
|
return array_diff(
|
||||||
$this->extensionDetails->getLoadedExtensions(),
|
$this->extensionDetails->getLoadedExtensions(),
|
||||||
$usedExtensions
|
$usedExtensions,
|
||||||
|
$this->excludedExtensions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,9 +53,10 @@ class ExtensionCheck
|
|||||||
public function checkUsages(array $classes, array $functions, array $constants, Closure $callback)
|
public function checkUsages(array $classes, array $functions, array $constants, Closure $callback)
|
||||||
{
|
{
|
||||||
$usedExtensions = [];
|
$usedExtensions = [];
|
||||||
|
$extensionMap = $this->extensionDetails->getExtensionMap($this->excludedExtensions);
|
||||||
|
|
||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
$extension = $this->checkClass($class);
|
$extension = $extensionMap->checkClass($class);
|
||||||
|
|
||||||
if (!empty($extension)) {
|
if (!empty($extension)) {
|
||||||
$usedExtensions[$extension]['class'] = true;
|
$usedExtensions[$extension]['class'] = true;
|
||||||
@ -49,7 +66,7 @@ class ExtensionCheck
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($functions as $function) {
|
foreach ($functions as $function) {
|
||||||
$extension = $this->checkFunction($function);
|
$extension = $extensionMap->checkFunction($function);
|
||||||
|
|
||||||
if (!empty($extension)) {
|
if (!empty($extension)) {
|
||||||
$usedExtensions[$extension]['function'] = true;
|
$usedExtensions[$extension]['function'] = true;
|
||||||
@ -59,7 +76,7 @@ class ExtensionCheck
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($constants as $constant) {
|
foreach ($constants as $constant) {
|
||||||
$extension = $this->checkConstant($constant);
|
$extension = $extensionMap->checkConstant($constant);
|
||||||
|
|
||||||
if (!empty($extension)) {
|
if (!empty($extension)) {
|
||||||
$usedExtensions[$extension]['constant'] = true;
|
$usedExtensions[$extension]['constant'] = true;
|
||||||
@ -70,7 +87,7 @@ class ExtensionCheck
|
|||||||
|
|
||||||
$tmp = array_keys($usedExtensions);
|
$tmp = array_keys($usedExtensions);
|
||||||
foreach ($tmp as $usedExtension) {
|
foreach ($tmp as $usedExtension) {
|
||||||
$requiredExtensions = $this->checkRequiredDependency($usedExtension);
|
$requiredExtensions = $extensionMap->checkRequiredDependency($usedExtension);
|
||||||
|
|
||||||
if (!empty($requiredExtensions)) {
|
if (!empty($requiredExtensions)) {
|
||||||
foreach ($requiredExtensions as $requiredExtension) {
|
foreach ($requiredExtensions as $requiredExtension) {
|
||||||
@ -83,51 +100,4 @@ class ExtensionCheck
|
|||||||
|
|
||||||
return $usedExtensions;
|
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'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
if ($this->extensionMap === null) {
|
||||||
$this->buildExtensionMaps();
|
$this->extensionMap = $this->buildExtensionMaps($excludedExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->extensionMap->classes ?? [];
|
return $this->extensionMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string,string>
|
* @param string[] $excludedExtensions
|
||||||
*/
|
*/
|
||||||
public function getExtensionFunctionMap(): array
|
private function buildExtensionMaps(array $excludedExtensions): ExtensionMap
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
$extensionClasses = $extensionFunctions = $extensionConstants = $extensionDependencies = $uncheckedExtensions = [];
|
$extensionClasses = $extensionFunctions = $extensionConstants = $extensionDependencies = $uncheckedExtensions = [];
|
||||||
foreach ($this->loadedExtensions as $loadedExtension) {
|
foreach ($this->loadedExtensions as $loadedExtension) {
|
||||||
if (in_array(strtolower($loadedExtension), array_map('strtolower', $extensionsToExclude))) {
|
if (in_array($loadedExtension, $excludedExtensions, true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,9 +85,14 @@ class ExtensionDetails
|
|||||||
if (!empty($dependencies)) {
|
if (!empty($dependencies)) {
|
||||||
natcasesort($dependencies);
|
natcasesort($dependencies);
|
||||||
foreach ($dependencies as $dependency => $status) {
|
foreach ($dependencies as $dependency => $status) {
|
||||||
|
if (in_array($dependency, $excludedExtensions, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isset($extensionDependencies[$loadedExtension][strtolower($status)])) {
|
if (!isset($extensionDependencies[$loadedExtension][strtolower($status)])) {
|
||||||
$extensionDependencies[$loadedExtension][strtolower($status)] = [];
|
$extensionDependencies[$loadedExtension][strtolower($status)] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$extensionDependencies[$loadedExtension][strtolower($status)][] = $dependency;
|
$extensionDependencies[$loadedExtension][strtolower($status)][] = $dependency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +105,7 @@ class ExtensionDetails
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->extensionMap = new ExtensionMap(
|
return new ExtensionMap(
|
||||||
$extensionClasses,
|
$extensionClasses,
|
||||||
$extensionFunctions,
|
$extensionFunctions,
|
||||||
$extensionConstants,
|
$extensionConstants,
|
||||||
|
@ -39,4 +39,31 @@ class ExtensionMap
|
|||||||
$this->dependencies = $dependencies;
|
$this->dependencies = $dependencies;
|
||||||
$this->unchecked = $unchecked;
|
$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'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user