From 2d47f1b48902db70537885adcbeb65e6b082b994 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 6 Dec 2025 15:42:38 +0100 Subject: [PATCH] misc --- README.md | 31 ++++++----- .../Command/CompareProjectsCommand.php | 32 ++++-------- .../Comparator/ComposerAutoloadComparator.php | 8 +-- .../MutuallyMissingPackagesComparator.php | 6 +-- .../PHPStanExtensionsComparator.php | 8 +-- .../Comparator/PHPStanLevelComparator.php | 52 +++++++++++++++++++ .../Comparator/PHPStanPathsComparator.php | 8 +-- .../SymfonyConfigFilesComparator.php | 6 +-- .../Contract/ComparatorInterface.php | 4 +- .../DependencyInjection/ContainerFactory.php | 4 +- src/{Macro => Compare}/Utils/ArrayUtils.php | 2 +- src/{Macro => Compare}/Utils/JsonLoader.php | 2 +- .../ValueObject/ProjectMetadata.php | 4 +- src/DependencyInjection/ContainerFactory.php | 29 ++++++++++- 14 files changed, 133 insertions(+), 63 deletions(-) rename src/{Macro => Compare}/Command/CompareProjectsCommand.php (60%) rename src/{Macro => Compare}/Comparator/ComposerAutoloadComparator.php (91%) rename src/{Macro => Compare}/Comparator/MutuallyMissingPackagesComparator.php (93%) rename src/{Macro => Compare}/Comparator/PHPStanExtensionsComparator.php (90%) create mode 100644 src/Compare/Comparator/PHPStanLevelComparator.php rename src/{Macro => Compare}/Comparator/PHPStanPathsComparator.php (90%) rename src/{Macro => Compare}/Comparator/SymfonyConfigFilesComparator.php (94%) rename src/{Macro => Compare}/Contract/ComparatorInterface.php (65%) rename src/{Macro => Compare}/DependencyInjection/ContainerFactory.php (93%) rename src/{Macro => Compare}/Utils/ArrayUtils.php (96%) rename src/{Macro => Compare}/Utils/JsonLoader.php (92%) rename src/{Macro => Compare}/ValueObject/ProjectMetadata.php (97%) diff --git a/README.md b/README.md index 3f43713..d32d9f2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# [PRIVATE BETA] Monitor: Know real quality of your packages and projects +# [PRIVATE BETA] Monitor quality of many Packages and Projects in one place +[![License](https://img.shields.io/packagist/l/rector/monitor.svg?style=flat-square)](https://packagist.org/packages/rector/monitor) [![Downloads total](https://img.shields.io/packagist/dt/rector/monitor.svg?style=flat-square)](https://packagist.org/packages/rector/monitor/stats) Monitor code quality for all your projects and packages in one place, ensuring consistency and eliminating conflicts across PHP versions. -> "Got 99 packages, but same version share none?" - +> "Got 99 packages, but same version share none" - unknown Have a single place to monitor your projects and packages code quality from -no more conflcits between packages, no more one project in PHP 8 and other in PHP 5 +no more conflicts between packages, no more one project in PHP 8.1 and other in PHP 7.2.
@@ -26,7 +26,7 @@ composer require rector/monitor --dev vendor/bin/monitor analyze ``` -This command will load `monitor.php` configuration file from project root. There you define repositories and requirements to meet. +This command will load `monitor.php` configuration file from project root. There you define repositories and requirements to meet: ```php use Rector\Monitor\Config\MonitorConfig; @@ -61,7 +61,7 @@ return MonitorConfig::configure()
-The repositories are cached to get fast performance. To refresh them: +The repositories are cloned locally and cached to get fast performance. To refresh them: ```bash vendor/bin/monitor analyze --clear-cache @@ -86,21 +86,26 @@ vendor/bin/monitor matrix ## 3. See Difference between Two Projects -Automate micro-services merge to one macro project, to make coding saint again. - -
+* Do you want to merge 2 projects into one monorepo? +* Are you curious how much are 2 project different to each other? -See how the monorepo project and the merge one are different. Use this knowledge to fill gaps in monorepo project. Only then create a final merge pull-request. +Compare them to eliminate their differences first, then make their merge smooth and easy: ```bash -vendor/bin/monitor diff-projects ../monorepo-project ../project-to-be-merged +vendor/bin/monitor compare --merge-project + +# e.g. +vendor/bin/monitor compare ../monorepo-project --merge-project ../project-to-be-merged ``` -That's it! This command will check: +This command will check: * differences in dependencies * differences in autoload -* +* if Symfony, difference between config files +* PHPStan analyzed paths +* PHPStan extensions +* PHPStan level
diff --git a/src/Macro/Command/CompareProjectsCommand.php b/src/Compare/Command/CompareProjectsCommand.php similarity index 60% rename from src/Macro/Command/CompareProjectsCommand.php rename to src/Compare/Command/CompareProjectsCommand.php index d6e69fd..11f1918 100644 --- a/src/Macro/Command/CompareProjectsCommand.php +++ b/src/Compare/Command/CompareProjectsCommand.php @@ -2,46 +2,32 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Command; +namespace Rector\Monitor\Compare\Command; -use Rector\Monitor\Macro\Comparator\ComposerAutoloadComparator; -use Rector\Monitor\Macro\Comparator\MutuallyMissingPackagesComparator; -use Rector\Monitor\Macro\Comparator\PHPStanExtensionsComparator; -use Rector\Monitor\Macro\Comparator\PHPStanPathsComparator; -use Rector\Monitor\Macro\Comparator\SymfonyConfigFilesComparator; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Webmozart\Assert\Assert; final class CompareProjectsCommand extends Command { /** - * @var ComparatorInterface[] + * @param ComparatorInterface[] $comparators */ - private readonly array $comparators; - public function __construct( private readonly SymfonyStyle $symfonyStyle, - ComposerAutoloadComparator $composerComparator, - MutuallyMissingPackagesComparator $mutuallyMissingPackagesComparator, - SymfonyConfigFilesComparator $configFilesComparator, - PHPStanExtensionsComparator $phpStanExtensionsComparator, - PHPStanPathsComparator $phpStanPathsComparator + private readonly array $comparators ) { parent::__construct(); - $this->comparators = [ - $composerComparator, - $mutuallyMissingPackagesComparator, - $configFilesComparator, - $phpStanExtensionsComparator, - $phpStanPathsComparator, - ]; + // make sure not empty to verify DI works + Assert::notEmpty($comparators); + Assert::allIsInstanceOf($comparators, ComparatorInterface::class); } protected function configure(): void diff --git a/src/Macro/Comparator/ComposerAutoloadComparator.php b/src/Compare/Comparator/ComposerAutoloadComparator.php similarity index 91% rename from src/Macro/Comparator/ComposerAutoloadComparator.php rename to src/Compare/Comparator/ComposerAutoloadComparator.php index 22618c1..d002cd5 100644 --- a/src/Macro/Comparator/ComposerAutoloadComparator.php +++ b/src/Compare/Comparator/ComposerAutoloadComparator.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Comparator; +namespace Rector\Monitor\Compare\Comparator; use Nette\Utils\Json; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\Utils\ArrayUtils; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\Utils\ArrayUtils; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Style\SymfonyStyle; final readonly class ComposerAutoloadComparator implements ComparatorInterface diff --git a/src/Macro/Comparator/MutuallyMissingPackagesComparator.php b/src/Compare/Comparator/MutuallyMissingPackagesComparator.php similarity index 93% rename from src/Macro/Comparator/MutuallyMissingPackagesComparator.php rename to src/Compare/Comparator/MutuallyMissingPackagesComparator.php index e4e9925..f69e3e0 100644 --- a/src/Macro/Comparator/MutuallyMissingPackagesComparator.php +++ b/src/Compare/Comparator/MutuallyMissingPackagesComparator.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Comparator; +namespace Rector\Monitor\Compare\Comparator; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Style\SymfonyStyle; final readonly class MutuallyMissingPackagesComparator implements ComparatorInterface diff --git a/src/Macro/Comparator/PHPStanExtensionsComparator.php b/src/Compare/Comparator/PHPStanExtensionsComparator.php similarity index 90% rename from src/Macro/Comparator/PHPStanExtensionsComparator.php rename to src/Compare/Comparator/PHPStanExtensionsComparator.php index 3723013..d68eaea 100644 --- a/src/Macro/Comparator/PHPStanExtensionsComparator.php +++ b/src/Compare/Comparator/PHPStanExtensionsComparator.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Comparator; +namespace Rector\Monitor\Compare\Comparator; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Style\SymfonyStyle; final readonly class PHPStanExtensionsComparator implements ComparatorInterface @@ -33,7 +33,7 @@ public function compare( $mergeExtraPackages = array_diff($mergePHPStanPackageNames, $monorepoPHPStanPackageNames); if ($monorepoExtraPackages === [] && $mergeExtraPackages === []) { - $this->symfonyStyle->success('No differences in PHPStan extensions found'); + $this->symfonyStyle->success('No differences found'); return; } diff --git a/src/Compare/Comparator/PHPStanLevelComparator.php b/src/Compare/Comparator/PHPStanLevelComparator.php new file mode 100644 index 0000000..8d2fcbd --- /dev/null +++ b/src/Compare/Comparator/PHPStanLevelComparator.php @@ -0,0 +1,52 @@ +hasPHPStanConfig() && ! $mergeProjectMetadata->hasPHPStanConfig()) { + // nothing to compare + return; + } + + $this->symfonyStyle->title('PHPStan level differences'); + + $monorepoPHPStanLevel = $monorepoProjectMetadata->getPHPStanConfig()['parameters']['level'] ?? null; + $mergePHPStanLeve = $mergeProjectMetadata->getPHPStanConfig()['parameters']['level'] ?? null; + + if ($monorepoPHPStanLevel === $mergePHPStanLeve) { + $this->symfonyStyle->success('No differences in PHPStan levels found'); + return; + } + + $this->symfonyStyle->writeln('Different PHPStan levels found:'); + $this->symfonyStyle->newLine(); + $this->symfonyStyle->writeln(sprintf( + ' * monorepo project ("%s"): level %s', + $monorepoProjectMetadata->getName(), + (string) $monorepoPHPStanLevel + )); + $this->symfonyStyle->writeln(sprintf( + ' * merge project ("%s"): level %s', + $mergeProjectMetadata->getName(), + (string) $mergePHPStanLeve + )); + + $this->symfonyStyle->newLine(); + } +} diff --git a/src/Macro/Comparator/PHPStanPathsComparator.php b/src/Compare/Comparator/PHPStanPathsComparator.php similarity index 90% rename from src/Macro/Comparator/PHPStanPathsComparator.php rename to src/Compare/Comparator/PHPStanPathsComparator.php index b614dcf..506439d 100644 --- a/src/Macro/Comparator/PHPStanPathsComparator.php +++ b/src/Compare/Comparator/PHPStanPathsComparator.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Comparator; +namespace Rector\Monitor\Compare\Comparator; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Style\SymfonyStyle; final readonly class PHPStanPathsComparator implements ComparatorInterface @@ -43,7 +43,7 @@ public function compare( $mergeExtraPaths = array_diff($mergePaths, $monorepoPaths); if ($monorepoExtraPaths === [] && $mergeExtraPaths === []) { - $this->symfonyStyle->success('No differences in PHPStan paths found'); + $this->symfonyStyle->success('No differences found'); return; } diff --git a/src/Macro/Comparator/SymfonyConfigFilesComparator.php b/src/Compare/Comparator/SymfonyConfigFilesComparator.php similarity index 94% rename from src/Macro/Comparator/SymfonyConfigFilesComparator.php rename to src/Compare/Comparator/SymfonyConfigFilesComparator.php index 396d381..6798482 100644 --- a/src/Macro/Comparator/SymfonyConfigFilesComparator.php +++ b/src/Compare/Comparator/SymfonyConfigFilesComparator.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Comparator; +namespace Rector\Monitor\Compare\Comparator; -use Rector\Monitor\Macro\Contract\ComparatorInterface; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\Contract\ComparatorInterface; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; use Symfony\Component\Console\Style\SymfonyStyle; final readonly class SymfonyConfigFilesComparator implements ComparatorInterface diff --git a/src/Macro/Contract/ComparatorInterface.php b/src/Compare/Contract/ComparatorInterface.php similarity index 65% rename from src/Macro/Contract/ComparatorInterface.php rename to src/Compare/Contract/ComparatorInterface.php index 262ef5b..10945be 100644 --- a/src/Macro/Contract/ComparatorInterface.php +++ b/src/Compare/Contract/ComparatorInterface.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Contract; +namespace Rector\Monitor\Compare\Contract; -use Rector\Monitor\Macro\ValueObject\ProjectMetadata; +use Rector\Monitor\Compare\ValueObject\ProjectMetadata; interface ComparatorInterface { diff --git a/src/Macro/DependencyInjection/ContainerFactory.php b/src/Compare/DependencyInjection/ContainerFactory.php similarity index 93% rename from src/Macro/DependencyInjection/ContainerFactory.php rename to src/Compare/DependencyInjection/ContainerFactory.php index 8419c42..cc29e15 100644 --- a/src/Macro/DependencyInjection/ContainerFactory.php +++ b/src/Compare/DependencyInjection/ContainerFactory.php @@ -2,10 +2,10 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\DependencyInjection; +namespace Rector\Monitor\Compare\DependencyInjection; use Illuminate\Container\Container; -use Rector\Monitor\Macro\Command\CompareProjectsCommand; +use Rector\Monitor\Compare\Command\CompareProjectsCommand; use Symfony\Component\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\ConsoleOutput; diff --git a/src/Macro/Utils/ArrayUtils.php b/src/Compare/Utils/ArrayUtils.php similarity index 96% rename from src/Macro/Utils/ArrayUtils.php rename to src/Compare/Utils/ArrayUtils.php index ca89cab..abb10ee 100644 --- a/src/Macro/Utils/ArrayUtils.php +++ b/src/Compare/Utils/ArrayUtils.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Utils; +namespace Rector\Monitor\Compare\Utils; final class ArrayUtils { diff --git a/src/Macro/Utils/JsonLoader.php b/src/Compare/Utils/JsonLoader.php similarity index 92% rename from src/Macro/Utils/JsonLoader.php rename to src/Compare/Utils/JsonLoader.php index 9b5c8b7..7e1ad4d 100644 --- a/src/Macro/Utils/JsonLoader.php +++ b/src/Compare/Utils/JsonLoader.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\Utils; +namespace Rector\Monitor\Compare\Utils; use Nette\Utils\FileSystem; use Nette\Utils\Json; diff --git a/src/Macro/ValueObject/ProjectMetadata.php b/src/Compare/ValueObject/ProjectMetadata.php similarity index 97% rename from src/Macro/ValueObject/ProjectMetadata.php rename to src/Compare/ValueObject/ProjectMetadata.php index 75efcc7..f2c793b 100644 --- a/src/Macro/ValueObject/ProjectMetadata.php +++ b/src/Compare/ValueObject/ProjectMetadata.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Rector\Monitor\Macro\ValueObject; +namespace Rector\Monitor\Compare\ValueObject; use Nette\Neon\Neon; use Nette\Utils\FileSystem; use Nette\Utils\Strings; -use Rector\Monitor\Macro\Utils\JsonLoader; +use Rector\Monitor\Compare\Utils\JsonLoader; use RuntimeException; use Symfony\Component\Finder\Finder; use Throwable; diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 5ddc928..11215d2 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -6,8 +6,15 @@ use Illuminate\Container\Container; use Rector\Monitor\Analyze\Command\AnalyzeCommand; +use Rector\Monitor\Compare\Command\CompareProjectsCommand; +use Rector\Monitor\Compare\Comparator\ComposerAutoloadComparator; +use Rector\Monitor\Compare\Comparator\MutuallyMissingPackagesComparator; +use Rector\Monitor\Compare\Comparator\PHPStanExtensionsComparator; +use Rector\Monitor\Compare\Comparator\PHPStanLevelComparator; +use Rector\Monitor\Compare\Comparator\PHPStanPathsComparator; +use Rector\Monitor\Compare\Comparator\SymfonyConfigFilesComparator; +use Rector\Monitor\Compare\Contract\ComparatorInterface; use Rector\Monitor\Console\MonitorConsoleApplication; -use Rector\Monitor\Macro\Command\CompareProjectsCommand; use Rector\Monitor\Matrix\Command\MatrixCommand; use Symfony\Component\Console\Application; use Symfony\Component\Console\Input\ArrayInput; @@ -41,6 +48,17 @@ public function create(): Container return $monitorConsoleApplication; }); + $this->registerComparator($container, ComposerAutoloadComparator::class); + $this->registerComparator($container, MutuallyMissingPackagesComparator::class); + $this->registerComparator($container, SymfonyConfigFilesComparator::class); + $this->registerComparator($container, PHPStanExtensionsComparator::class); + $this->registerComparator($container, PHPStanPathsComparator::class); + $this->registerComparator($container, PHPStanLevelComparator::class); + + $container->when(CompareProjectsCommand::class) + ->needs('$comparators') + ->giveTagged(ComparatorInterface::class); + $container->singleton( SymfonyStyle::class, static fn (): SymfonyStyle => new SymfonyStyle(new ArrayInput([]), new ConsoleOutput()) @@ -58,4 +76,13 @@ public function hideDefaultCommands(Application $application): void $application->get('help') ->setHidden(true); } + + /** + * @param class-string $comparatorClass + */ + private function registerComparator(Container $container, string $comparatorClass): void + { + $container->singleton($comparatorClass); + $container->tag($comparatorClass, ComparatorInterface::class); + } }