Skip to content

Commit

Permalink
[PSR-4] Add "find-multi-classes" command to check files with multiple…
Browse files Browse the repository at this point in the history
… classes (#15)
  • Loading branch information
TomasVotruba authored Jan 29, 2024
1 parent cf9e445 commit e254733
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/Command/FindMultiClassesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCI\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\EasyCI\Finder\MultipleClassInOneFileFinder;

final class FindMultiClassesCommand extends Command
{
public function __construct(
private readonly MultipleClassInOneFileFinder $multipleClassInOneFileFinder,
private readonly SymfonyStyle $symfonyStyle,
) {
parent::__construct();
}

protected function configure(): void
{
$this->setName('find-multi-classes');

$this->setDescription('Find multiple classes in one file');

$this->addArgument(
'sources',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'Path to source to analyse'
);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var string[] $source */
$source = $input->getArgument('sources');

$multipleClassesByFile = $this->multipleClassInOneFileFinder->findInDirectories($source);
if ($multipleClassesByFile === []) {
$this->symfonyStyle->success('No files with 2+ classes found');

return self::SUCCESS;
}

foreach ($multipleClassesByFile as $file => $classes) {
$message = sprintf('File "%s" has %d classes', $file, count($classes));
$this->symfonyStyle->section($message);
$this->symfonyStyle->listing($classes);
}

return self::FAILURE;
}
}
3 changes: 3 additions & 0 deletions src/DependencyInjection/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Symfony\Component\Console\Style\SymfonyStyle;
use Symplify\EasyCI\Command\CheckCommentedCodeCommand;
use Symplify\EasyCI\Command\CheckConflictsCommand;
use Symplify\EasyCI\Command\FindMultiClassesCommand;
use Symplify\EasyCI\Command\ValidateFileLengthCommand;
use Symplify\EasyCI\Testing\Command\DetectUnitTestsCommand;

Expand All @@ -37,7 +38,9 @@ public function create(): Container
$container->make(CheckConflictsCommand::class),
$container->make(ValidateFileLengthCommand::class),
$container->make(DetectUnitTestsCommand::class),
$container->make(FindMultiClassesCommand::class),
];

$application->addCommands($commands);

// remove basic command to make output clear
Expand Down
31 changes: 31 additions & 0 deletions src/Finder/MultipleClassInOneFileFinder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Symplify\EasyCI\Finder;

use Symplify\EasyCI\RobotLoader\PhpClassLoader;

final readonly class MultipleClassInOneFileFinder
{
public function __construct(
private PhpClassLoader $phpClassLoader
) {
}

/**
* @param string[] $directories
* @return string[][]
*/
public function findInDirectories(array $directories): array
{
$fileByClasses = $this->phpClassLoader->load($directories);

$classesByFile = [];
foreach ($fileByClasses as $class => $file) {
$classesByFile[$file][] = $class;
}

return array_filter($classesByFile, static fn(array $classes): bool => count($classes) >= 2);
}
}
22 changes: 22 additions & 0 deletions src/RobotLoader/PhpClassLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Symplify\EasyCI\RobotLoader;

use Nette\Loaders\RobotLoader;

final class PhpClassLoader
{
/**
* @param string[] $directories
* @return array<string, string>
*/
public function load(array $directories): array
{
$robotLoader = new RobotLoader();
$robotLoader->addDirectory(...$directories);
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/multiple-classes');
$robotLoader->rebuild();

return $robotLoader->getIndexedClasses();
}
}

0 comments on commit e254733

Please sign in to comment.