diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml
index c735702..25024c1 100644
--- a/.github/workflows/code_analysis.yaml
+++ b/.github/workflows/code_analysis.yaml
@@ -36,6 +36,10 @@ jobs:
name: 'Check Active Classes'
run: vendor/bin/class-leak check bin src tests --ansi
+ -
+ name: 'Run "Compare Projects" command'
+ run: php bin/monitor compare-projects tests/project-fixture/first-project --merge-project tests/project-fixture/second-project --ansi
+
-
name: 'Composer dependency Analyser'
run: vendor/bin/composer-dependency-analyser
@@ -48,7 +52,7 @@ jobs:
# see https://github.com/shivammathur/setup-php
- uses: shivammathur/setup-php@v2
with:
- php-version: 8.2
+ php-version: 8.3
coverage: none
# composer install cache - https://github.com/ramsey/composer-install
diff --git a/LICENSE b/LICENSE
index bd1ea72..a8fc2ae 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
The MIT License
---------------
-Copyright (c) 2020 Tomas Votruba (https://tomasvotruba.com)
+Copyright (c) 2025 Tomas Votruba (https://tomasvotruba.com)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -22,4 +22,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 85da66d..d040268 100644
--- a/README.md
+++ b/README.md
@@ -27,15 +27,14 @@ composer require rector/monitor --dev
### 1. Quality control for `composer.json` in multiple repositories
```bash
-vendor/bin/monitor quality-control
+vendor/bin/monitor analyze
```
```bash
-vendor/bin/monitor quality-control --clear-cache
+vendor/bin/monitor analyze --clear-cache
```
-
### 2. See full Matrix of repositories's dependencies
diff --git a/bin/monitor.php b/bin/monitor.php
index dfe4e1e..65977be 100755
--- a/bin/monitor.php
+++ b/bin/monitor.php
@@ -4,8 +4,6 @@
use Rector\Monitor\DependencyInjection\ContainerFactory;
use Symfony\Component\Console\Application;
-use Symfony\Component\Console\Input\ArgvInput;
-use Symfony\Component\Console\Output\ConsoleOutput;
$scoperAutoloadFilepath = __DIR__ . '/../vendor/scoper-autoload.php';
if (file_exists($scoperAutoloadFilepath)) {
@@ -33,6 +31,4 @@
$container = $containerFactory->create();
$application = $container->make(Application::class);
-
-$exitCode = $application->run(new ArgvInput(), new ConsoleOutput());
-exit($exitCode);
+exit($application->run());
diff --git a/composer.json b/composer.json
index 6aa992c..00147bc 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
"bin/monitor"
],
"require": {
- "php": ">=8.2",
+ "php": ">=8.3",
"composer/semver": "^3.4",
"illuminate/container": "12.40.*",
"nette/neon": "^3.4",
diff --git a/monitor.php b/monitor.php
index 815ff6c..11370d2 100644
--- a/monitor.php
+++ b/monitor.php
@@ -5,21 +5,25 @@
use Rector\Monitor\Config\MonitorConfig;
return MonitorConfig::configure()
- ->addRepositories(['git@bitbucket.org:arestravelinc/lib-client.git'])
- ->addRepositoryBranch('git@bitbucket.org:arestravelinc/legacy-appserver-service.git', 'stage')
- ->addRepositoryBranch('git@bitbucket.org:arestravelinc/be5.git', 'stage')
- ->addRepositoryBranch('git@bitbucket.org:arestravelinc/ares-admin.git', 'stage')
- ->addRepositoryBranch('git@bitbucket.org:arestravelinc/content-service.git', 'stage')
- ->addRepositoryBranch('git@bitbucket.org:arestravelinc/payment-service.git', 'stage')
+ ->addRepositories([
+ // rector repositories
+ 'https://github.com/rectorphp/rector-src',
+ 'https://github.com/rectorphp/rector-symfony',
+ 'https://github.com/rectorphp/rector-doctrine',
+ 'https://github.com/rectorphp/rector-phpunit',
+ 'https://github.com/rectorphp/rector-downgrade-php',
+ ])
+ // ->addRepositoryBranch('...', 'stage')
// composer rules
- ->disallowPackages(['symfony/phpunit-bridge'])
+ // ->disallowPackages(['symfony/phpunit-bridge'])
->requirePackages([
'phpstan/phpstan',
'phpecs/phpecs',
'rector/rector',
'phpstan/phpstan-deprecation-rules',
'phpstan/extension-installer',
+ 'symplify/phpstan-rules',
])
// version requirements
diff --git a/phpstan.neon b/phpstan.neon
index ad1dc96..6fde2e3 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,3 +1,9 @@
+includes:
+ - vendor/symplify/phpstan-rules/config/code-complexity-rules.neon
+ - vendor/symplify/phpstan-rules/config/configurable-rules.neon
+ - vendor/symplify/phpstan-rules/config/naming-rules.neon
+ - vendor/symplify/phpstan-rules/config/static-rules.neon
+
parameters:
level: 8
diff --git a/src/Command/AnalyzeCommand.php b/src/Analyze/Command/AnalyzeCommand.php
similarity index 85%
rename from src/Command/AnalyzeCommand.php
rename to src/Analyze/Command/AnalyzeCommand.php
index be2ee9b..edc119a 100644
--- a/src/Command/AnalyzeCommand.php
+++ b/src/Analyze/Command/AnalyzeCommand.php
@@ -2,17 +2,17 @@
declare(strict_types=1);
-namespace Rector\Monitor\Command;
-
+namespace Rector\Monitor\Analyze\Command;
+
+use Rector\Monitor\Analyze\Contract\RuleProcessorInterface;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
+use Rector\Monitor\Analyze\RuleProcessor\DisallowedPackagesRuleProcessor;
+use Rector\Monitor\Analyze\RuleProcessor\MetafileProcessor\NoPHPStanBaselineMetafileProcessor;
+use Rector\Monitor\Analyze\RuleProcessor\MissingPackagesRuleProcessor;
+use Rector\Monitor\Analyze\RuleProcessor\TooLowPackagesRulesProcessor;
+use Rector\Monitor\Config\ConfigInitializer;
use Rector\Monitor\Config\MonitorConfigProvider;
-use Rector\Monitor\Configuration\ConfigInitializer;
-use Rector\Monitor\Contract\RuleProcessorInterface;
use Rector\Monitor\Git\RepositoryMetafilesResolver;
-use Rector\Monitor\Reporting\ErrorCollector;
-use Rector\Monitor\RuleProcessor\DisallowedPackagesRuleProcessor;
-use Rector\Monitor\RuleProcessor\MetafileProcessor\NoPHPStanBaselineMetafileProcessor;
-use Rector\Monitor\RuleProcessor\MissingPackagesRuleProcessor;
-use Rector\Monitor\RuleProcessor\TooLowPackagesRulesProcessor;
use Rector\Monitor\ValueObject\RepositoryCollection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
@@ -51,7 +51,7 @@ protected function configure(): void
$this->setAliases(['analyse']);
$this->setDescription(
- 'Check repositoryCollection composer.json files, assess "require" section, root files, tooling setup and min PHP version with defined quality control rules'
+ 'Check repositories composer.json files, assess "require" section, root files, tooling setup and min PHP version with defined quality control rules'
);
$this->addOption(
@@ -117,7 +117,7 @@ private function printAnalysisSummary(RepositoryCollection $repositoryCollection
$this->symfonyStyle->writeln(sprintf(
' Summary: %d %s analyzed, %d with issues',
$repositoryCollection->count(),
- $repositoryCollection->count() === 1 ? 'repository' : 'repositoryCollection',
+ $repositoryCollection->count() === 1 ? 'repository' : 'repositories',
$erroredRepositoryCount
));
diff --git a/src/Contract/RuleProcessorInterface.php b/src/Analyze/Contract/RuleProcessorInterface.php
similarity index 76%
rename from src/Contract/RuleProcessorInterface.php
rename to src/Analyze/Contract/RuleProcessorInterface.php
index 8d01c61..6c093b7 100644
--- a/src/Contract/RuleProcessorInterface.php
+++ b/src/Analyze/Contract/RuleProcessorInterface.php
@@ -2,10 +2,10 @@
declare(strict_types=1);
-namespace Rector\Monitor\Contract;
+namespace Rector\Monitor\Analyze\Contract;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Reporting\ErrorCollector;
use Rector\Monitor\ValueObject\ComposerJson;
interface RuleProcessorInterface
diff --git a/src/Reporting/ErrorCollector.php b/src/Analyze/Reporting/ErrorCollector.php
similarity index 91%
rename from src/Reporting/ErrorCollector.php
rename to src/Analyze/Reporting/ErrorCollector.php
index 324c90e..bf0c512 100644
--- a/src/Reporting/ErrorCollector.php
+++ b/src/Analyze/Reporting/ErrorCollector.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Rector\Monitor\Reporting;
+namespace Rector\Monitor\Analyze\Reporting;
final class ErrorCollector
{
diff --git a/src/RuleProcessor/DisallowedPackagesRuleProcessor.php b/src/Analyze/RuleProcessor/DisallowedPackagesRuleProcessor.php
similarity index 85%
rename from src/RuleProcessor/DisallowedPackagesRuleProcessor.php
rename to src/Analyze/RuleProcessor/DisallowedPackagesRuleProcessor.php
index f1bba29..1345cdd 100644
--- a/src/RuleProcessor/DisallowedPackagesRuleProcessor.php
+++ b/src/Analyze/RuleProcessor/DisallowedPackagesRuleProcessor.php
@@ -2,11 +2,11 @@
declare(strict_types=1);
-namespace Rector\Monitor\RuleProcessor;
+namespace Rector\Monitor\Analyze\RuleProcessor;
+use Rector\Monitor\Analyze\Contract\RuleProcessorInterface;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Contract\RuleProcessorInterface;
-use Rector\Monitor\Reporting\ErrorCollector;
use Rector\Monitor\ValueObject\ComposerJson;
final class DisallowedPackagesRuleProcessor implements RuleProcessorInterface
diff --git a/src/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php b/src/Analyze/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php
similarity index 87%
rename from src/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php
rename to src/Analyze/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php
index 7a0c87f..0b604f3 100644
--- a/src/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php
+++ b/src/Analyze/RuleProcessor/MetafileProcessor/NoPHPStanBaselineMetafileProcessor.php
@@ -2,11 +2,11 @@
declare(strict_types=1);
-namespace Rector\Monitor\RuleProcessor\MetafileProcessor;
+namespace Rector\Monitor\Analyze\RuleProcessor\MetafileProcessor;
+use Rector\Monitor\Analyze\Contract\RuleProcessorInterface;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Contract\RuleProcessorInterface;
-use Rector\Monitor\Reporting\ErrorCollector;
use Rector\Monitor\ValueObject\ComposerJson;
final readonly class NoPHPStanBaselineMetafileProcessor implements RuleProcessorInterface
diff --git a/src/RuleProcessor/MissingPackagesRuleProcessor.php b/src/Analyze/RuleProcessor/MissingPackagesRuleProcessor.php
similarity index 85%
rename from src/RuleProcessor/MissingPackagesRuleProcessor.php
rename to src/Analyze/RuleProcessor/MissingPackagesRuleProcessor.php
index db0e001..b458600 100644
--- a/src/RuleProcessor/MissingPackagesRuleProcessor.php
+++ b/src/Analyze/RuleProcessor/MissingPackagesRuleProcessor.php
@@ -2,11 +2,11 @@
declare(strict_types=1);
-namespace Rector\Monitor\RuleProcessor;
+namespace Rector\Monitor\Analyze\RuleProcessor;
+use Rector\Monitor\Analyze\Contract\RuleProcessorInterface;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Contract\RuleProcessorInterface;
-use Rector\Monitor\Reporting\ErrorCollector;
use Rector\Monitor\ValueObject\ComposerJson;
final class MissingPackagesRuleProcessor implements RuleProcessorInterface
diff --git a/src/RuleProcessor/TooLowPackagesRulesProcessor.php b/src/Analyze/RuleProcessor/TooLowPackagesRulesProcessor.php
similarity index 91%
rename from src/RuleProcessor/TooLowPackagesRulesProcessor.php
rename to src/Analyze/RuleProcessor/TooLowPackagesRulesProcessor.php
index 5b4ce96..1b4900d 100644
--- a/src/RuleProcessor/TooLowPackagesRulesProcessor.php
+++ b/src/Analyze/RuleProcessor/TooLowPackagesRulesProcessor.php
@@ -2,12 +2,12 @@
declare(strict_types=1);
-namespace Rector\Monitor\RuleProcessor;
+namespace Rector\Monitor\Analyze\RuleProcessor;
use Composer\Semver\Semver;
+use Rector\Monitor\Analyze\Contract\RuleProcessorInterface;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Contract\RuleProcessorInterface;
-use Rector\Monitor\Reporting\ErrorCollector;
use Rector\Monitor\ValueObject\ComposerJson;
/**
diff --git a/src/Configuration/ConfigInitializer.php b/src/Config/ConfigInitializer.php
similarity index 94%
rename from src/Configuration/ConfigInitializer.php
rename to src/Config/ConfigInitializer.php
index f3361cf..726ff76 100644
--- a/src/Configuration/ConfigInitializer.php
+++ b/src/Config/ConfigInitializer.php
@@ -2,12 +2,12 @@
declare(strict_types=1);
-namespace Rector\Monitor\Configuration;
+namespace Rector\Monitor\Config;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
-final class ConfigInitializer
+final readonly class ConfigInitializer
{
public function __construct(
private SymfonyStyle $symfonyStyle,
diff --git a/src/Config/MonitorConfig.php b/src/Config/MonitorConfig.php
index f5ecf21..9ca5260 100644
--- a/src/Config/MonitorConfig.php
+++ b/src/Config/MonitorConfig.php
@@ -53,8 +53,12 @@ public function addRepositories(array $repositories): self
Assert::allString($repositories);
foreach ($repositories as $repository) {
+ if (! str_ends_with($repository, '.git')) {
+ $repository .= '.git';
+ }
+
MonitorAssert::assertRepositoryUrl($repository);
- $repositories[] = $repository;
+ $this->repositories[] = $repository;
}
return $this;
diff --git a/src/Console/Command/CleanListCommand.php b/src/Console/Command/CleanListCommand.php
index 4801f1f..c61ec4e 100644
--- a/src/Console/Command/CleanListCommand.php
+++ b/src/Console/Command/CleanListCommand.php
@@ -4,6 +4,7 @@
namespace Rector\Monitor\Console\Command;
+use Override;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Command\ListCommand;
@@ -17,6 +18,7 @@
*/
final class CleanListCommand extends ListCommand
{
+ #[Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
Assert::isInstanceOf($this->getApplication(), Application::class);
diff --git a/src/Console/MonitorConsoleApplication.php b/src/Console/MonitorConsoleApplication.php
index 65a83c7..727fa45 100644
--- a/src/Console/MonitorConsoleApplication.php
+++ b/src/Console/MonitorConsoleApplication.php
@@ -4,6 +4,7 @@
namespace Rector\Monitor\Console;
+use Override;
use Rector\Monitor\Console\Command\CleanListCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\CompleteCommand;
@@ -12,6 +13,7 @@
final class MonitorConsoleApplication extends Application
{
+ #[Override]
protected function getDefaultCommands(): array
{
return [
diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php
index 67eff0c..5ddc928 100644
--- a/src/DependencyInjection/ContainerFactory.php
+++ b/src/DependencyInjection/ContainerFactory.php
@@ -5,13 +5,14 @@
namespace Rector\Monitor\DependencyInjection;
use Illuminate\Container\Container;
+use Rector\Monitor\Analyze\Command\AnalyzeCommand;
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;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
-use Symfony\Component\Finder\Finder;
-use Webmozart\Assert\Assert;
final class ContainerFactory
{
@@ -26,7 +27,7 @@ public function create(): Container
$container->singleton(Application::class, function (Container $container): MonitorConsoleApplication {
$monitorConsoleApplication = new MonitorConsoleApplication('Rector Monitor');
- $commandClasses = $this->findCommandClasses();
+ $commandClasses = [AnalyzeCommand::class, MatrixCommand::class, CompareProjectsCommand::class];
// register commands
foreach ($commandClasses as $commandClass) {
@@ -57,27 +58,4 @@ public function hideDefaultCommands(Application $application): void
$application->get('help')
->setHidden(true);
}
-
- /**
- * @return string[]
- */
- private function findCommandClasses(): array
- {
- $commandFinder = Finder::create()
- ->files()
- ->name('*Command.php')
- ->in(__DIR__ . '/../Command');
-
- $commandClasses = [];
- foreach ($commandFinder as $commandFile) {
- $commandClass = 'Rector\\Monitor\\Command\\' . $commandFile->getBasename('.php');
-
- // make sure it exists
- Assert::classExists($commandClass);
-
- $commandClasses[] = $commandClass;
- }
-
- return $commandClasses;
- }
}
diff --git a/src/Git/RepositoryMetafilesResolver.php b/src/Git/RepositoryMetafilesResolver.php
index 6926a26..b5d8d85 100644
--- a/src/Git/RepositoryMetafilesResolver.php
+++ b/src/Git/RepositoryMetafilesResolver.php
@@ -25,7 +25,9 @@ public function __construct(
public function decorateRepositories(RepositoryCollection $repositoryCollection, bool $clearCache = false): void
{
foreach ($repositoryCollection->all() as $repository) {
- $repositoryCacheDirectory = getcwd() . '/monitor-cache/repository-' . md5($repository->getRepositoryUrl());
+ $repositoryCacheDirectory = sys_get_temp_dir() . '/rector-monitor-cache/repository-' . md5(
+ $repository->getRepositoryUrl()
+ );
if (file_exists($repositoryCacheDirectory) && $this->hasDirectorySomeFiles($repositoryCacheDirectory)) {
if ($clearCache) {
diff --git a/src/Helper/SymfonyColumnStyler.php b/src/Helper/SymfonyColumnStyler.php
index 436ff26..f529074 100644
--- a/src/Helper/SymfonyColumnStyler.php
+++ b/src/Helper/SymfonyColumnStyler.php
@@ -20,7 +20,7 @@ final class SymfonyColumnStyler
public static function styleHighsAndLows(array $tableRow): array
{
// set highs and lows
- $stringValues = array_filter($tableRow, 'is_string');
+ $stringValues = array_filter($tableRow, is_string(...));
$stringValues = array_unique($stringValues);
if (count($stringValues) < 2) {
diff --git a/src/Macro/Command/CompareProjectsCommand.php b/src/Macro/Command/CompareProjectsCommand.php
index fd70861..d6e69fd 100644
--- a/src/Macro/Command/CompareProjectsCommand.php
+++ b/src/Macro/Command/CompareProjectsCommand.php
@@ -5,10 +5,10 @@
namespace Rector\Monitor\Macro\Command;
use Rector\Monitor\Macro\Comparator\ComposerAutoloadComparator;
-use Rector\Monitor\Macro\Comparator\ConfigFilesComparator;
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 Symfony\Component\Console\Command\Command;
@@ -29,7 +29,7 @@ public function __construct(
private readonly SymfonyStyle $symfonyStyle,
ComposerAutoloadComparator $composerComparator,
MutuallyMissingPackagesComparator $mutuallyMissingPackagesComparator,
- ConfigFilesComparator $configFilesComparator,
+ SymfonyConfigFilesComparator $configFilesComparator,
PHPStanExtensionsComparator $phpStanExtensionsComparator,
PHPStanPathsComparator $phpStanPathsComparator
) {
@@ -66,9 +66,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->symfonyStyle->writeln('Both directories found. Comparing 2 projects>');
- foreach ($this->comparators as $key => $comparator) {
- $comparator->compare($key + 1, $monorepoProjectMetadata, $mergeProjectMetadata);
- $this->symfonyStyle->newLine();
+ foreach ($this->comparators as $comparator) {
+ $comparator->compare($monorepoProjectMetadata, $mergeProjectMetadata);
}
return self::SUCCESS;
diff --git a/src/Macro/Comparator/ComposerAutoloadComparator.php b/src/Macro/Comparator/ComposerAutoloadComparator.php
index 5ac1b6a..22618c1 100644
--- a/src/Macro/Comparator/ComposerAutoloadComparator.php
+++ b/src/Macro/Comparator/ComposerAutoloadComparator.php
@@ -15,7 +15,7 @@
/**
* @var string[]
*/
- private const AUTOLOAD_KEYS = ['autoload', 'autoload-dev'];
+ private const array AUTOLOAD_KEYS = ['autoload', 'autoload-dev'];
public function __construct(
private SymfonyStyle $symfonyStyle
@@ -23,11 +23,10 @@ public function __construct(
}
public function compare(
- int $step,
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
- $this->symfonyStyle->title(sprintf('%d) PSR-4 autoload differences', $step));
+ $this->symfonyStyle->title('PSR-4 autoload differences');
$hasDifference = false;
@@ -71,5 +70,7 @@ public function compare(
if ($hasDifference === false) {
$this->symfonyStyle->success('Autoloads are identical, nothing spotted');
}
+
+ $this->symfonyStyle->newLine();
}
}
diff --git a/src/Macro/Comparator/MutuallyMissingPackagesComparator.php b/src/Macro/Comparator/MutuallyMissingPackagesComparator.php
index f70a7d0..e4e9925 100644
--- a/src/Macro/Comparator/MutuallyMissingPackagesComparator.php
+++ b/src/Macro/Comparator/MutuallyMissingPackagesComparator.php
@@ -13,7 +13,7 @@
/**
* @var string[]
*/
- private const REQUIRE_KEYS = ['require', 'require-dev'];
+ private const array REQUIRE_KEYS = ['require', 'require-dev'];
public function __construct(
private SymfonyStyle $symfonyStyle
@@ -21,11 +21,10 @@ public function __construct(
}
public function compare(
- int $step,
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
- $this->symfonyStyle->title(sprintf('%d. Composer dependencies', $step));
+ $this->symfonyStyle->title('Composer dependencies');
$hasDifference = false;
@@ -65,5 +64,7 @@ public function compare(
if ($hasDifference === false) {
$this->symfonyStyle->success('Monorepo project has all required dependencies from the merge project');
}
+
+ $this->symfonyStyle->newLine();
}
}
diff --git a/src/Macro/Comparator/PHPStanExtensionsComparator.php b/src/Macro/Comparator/PHPStanExtensionsComparator.php
index ff8f09b..3723013 100644
--- a/src/Macro/Comparator/PHPStanExtensionsComparator.php
+++ b/src/Macro/Comparator/PHPStanExtensionsComparator.php
@@ -16,11 +16,15 @@ public function __construct(
}
public function compare(
- int $step,
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
- $this->symfonyStyle->title(sprintf('%d) PHPStan extensions differences', $step));
+ if (! $monorepoProjectMetadata->hasPHPStanConfig() && ! $mergeProjectMetadata->hasPHPStanConfig()) {
+ // nothing to compare
+ return;
+ }
+
+ $this->symfonyStyle->title('PHPStan extensions differences');
$monorepoPHPStanPackageNames = $monorepoProjectMetadata->getPackagesMatchingName('phpstan');
$mergePHPStanPackageNames = $mergeProjectMetadata->getPackagesMatchingName('phpstan');
diff --git a/src/Macro/Comparator/PHPStanPathsComparator.php b/src/Macro/Comparator/PHPStanPathsComparator.php
index 1bf2229..b614dcf 100644
--- a/src/Macro/Comparator/PHPStanPathsComparator.php
+++ b/src/Macro/Comparator/PHPStanPathsComparator.php
@@ -16,11 +16,15 @@ public function __construct(
}
public function compare(
- int $step,
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
- $this->symfonyStyle->title(sprintf('%d) PHPStan paths differences', $step));
+ if (! $monorepoProjectMetadata->hasPHPStanConfig() && ! $mergeProjectMetadata->hasPHPStanConfig()) {
+ // nothing to compare
+ return;
+ }
+
+ $this->symfonyStyle->title('PHPStan paths differences');
$monorepoPHPStanConfig = $monorepoProjectMetadata->getPHPStanConfig();
$mergePHPStanConfig = $mergeProjectMetadata->getPHPStanConfig();
diff --git a/src/Macro/Comparator/ConfigFilesComparator.php b/src/Macro/Comparator/SymfonyConfigFilesComparator.php
similarity index 88%
rename from src/Macro/Comparator/ConfigFilesComparator.php
rename to src/Macro/Comparator/SymfonyConfigFilesComparator.php
index 33a2af9..396d381 100644
--- a/src/Macro/Comparator/ConfigFilesComparator.php
+++ b/src/Macro/Comparator/SymfonyConfigFilesComparator.php
@@ -8,7 +8,7 @@
use Rector\Monitor\Macro\ValueObject\ProjectMetadata;
use Symfony\Component\Console\Style\SymfonyStyle;
-final readonly class ConfigFilesComparator implements ComparatorInterface
+final readonly class SymfonyConfigFilesComparator implements ComparatorInterface
{
public function __construct(
private SymfonyStyle $symfonyStyle
@@ -16,7 +16,6 @@ public function __construct(
}
public function compare(
- int $step,
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
@@ -24,7 +23,12 @@ public function compare(
$monorepoConfigDirectory = $monorepoProjectMetadata->getConfigDirectory();
$mergeConfigDirectory = $mergeProjectMetadata->getConfigDirectory();
- $this->symfonyStyle->title(sprintf('%d. Comparing config directories', $step));
+ if ($monorepoConfigDirectory === null && $mergeConfigDirectory === null) {
+ // both projects do not have config directories
+ return;
+ }
+
+ $this->symfonyStyle->title('Comparing Symfony config directories');
if ($monorepoConfigDirectory !== $mergeConfigDirectory) {
$this->symfonyStyle->warning('Projects have different /config directory location');
diff --git a/src/Macro/Contract/ComparatorInterface.php b/src/Macro/Contract/ComparatorInterface.php
index f81a0e4..262ef5b 100644
--- a/src/Macro/Contract/ComparatorInterface.php
+++ b/src/Macro/Contract/ComparatorInterface.php
@@ -8,9 +8,5 @@
interface ComparatorInterface
{
- public function compare(
- int $step,
- ProjectMetadata $monorepoProjectMetadata,
- ProjectMetadata $mergeProjectMetadata
- ): void;
+ public function compare(ProjectMetadata $monorepoProjectMetadata, ProjectMetadata $mergeProjectMetadata): void;
}
diff --git a/src/Macro/DependencyInjection/ContainerFactory.php b/src/Macro/DependencyInjection/ContainerFactory.php
index d892359..8419c42 100644
--- a/src/Macro/DependencyInjection/ContainerFactory.php
+++ b/src/Macro/DependencyInjection/ContainerFactory.php
@@ -34,11 +34,11 @@ static function (): SymfonyStyle {
);
$container->singleton(Application::class, function (Container $container): Application {
- /** @var CompareProjectsCommand $addTypesCommand */
- $addTypesCommand = $container->make(CompareProjectsCommand::class);
+ /** @var CompareProjectsCommand $compareProjectsCommand */
+ $compareProjectsCommand = $container->make(CompareProjectsCommand::class);
$application = new Application();
- $application->add($addTypesCommand);
+ $application->add($compareProjectsCommand);
$this->hideDefaultCommands($application);
diff --git a/src/Macro/ValueObject/ProjectMetadata.php b/src/Macro/ValueObject/ProjectMetadata.php
index 3cfbcaa..75efcc7 100644
--- a/src/Macro/ValueObject/ProjectMetadata.php
+++ b/src/Macro/ValueObject/ProjectMetadata.php
@@ -8,7 +8,9 @@
use Nette\Utils\FileSystem;
use Nette\Utils\Strings;
use Rector\Monitor\Macro\Utils\JsonLoader;
+use RuntimeException;
use Symfony\Component\Finder\Finder;
+use Throwable;
use Webmozart\Assert\Assert;
final readonly class ProjectMetadata
@@ -85,13 +87,19 @@ public function getConfigFiles(): array
->sortByName();
$configFiles = [];
- foreach ($configFilesFinder as $configFileInfo) {
- $configFiles[] = $configFileInfo->getRelativePathname();
+ foreach ($configFilesFinder as $configFileFinder) {
+ $configFiles[] = $configFileFinder->getRelativePathname();
}
return $configFiles;
}
+ public function hasPHPStanConfig(): bool
+ {
+ $phpstanConfigPath = $this->projectDirectory . '/phpstan.neon';
+ return file_exists($phpstanConfigPath);
+ }
+
/**
* @return mixed[]|null
*/
@@ -104,9 +112,9 @@ public function getPHPStanConfig(): ?array
try {
return Neon::decodeFile($phpstanConfigPath);
- } catch (\Throwable $throwable) {
+ } catch (Throwable $throwable) {
// give more context about the file path and its contents
- throw new \RuntimeException(sprintf(
+ throw new RuntimeException(sprintf(
'Failed to decode NEON file "%s" with contents:%s%s %s',
$phpstanConfigPath,
PHP_EOL,
diff --git a/src/Command/MatrixCommand.php b/src/Matrix/Command/MatrixCommand.php
similarity index 96%
rename from src/Command/MatrixCommand.php
rename to src/Matrix/Command/MatrixCommand.php
index 3ba01e8..c26ed2d 100644
--- a/src/Command/MatrixCommand.php
+++ b/src/Matrix/Command/MatrixCommand.php
@@ -2,14 +2,14 @@
declare(strict_types=1);
-namespace Rector\Monitor\Command;
+namespace Rector\Monitor\Matrix\Command;
use Nette\Utils\Strings;
-use Rector\Monitor\Composer\PackageSorter;
+use Rector\Monitor\Config\ConfigInitializer;
use Rector\Monitor\Config\MonitorConfigProvider;
-use Rector\Monitor\Configuration\ConfigInitializer;
use Rector\Monitor\Git\RepositoryMetafilesResolver;
use Rector\Monitor\Helper\SymfonyColumnStyler;
+use Rector\Monitor\Matrix\Composer\PackageSorter;
use Rector\Monitor\ValueObject\RepositoryCollection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\TableStyle;
@@ -20,10 +20,7 @@
final class MatrixCommand extends Command
{
- /**
- * @var string
- */
- private const MISSING_LABEL = '*MISSING*';
+ private const string MISSING_LABEL = '*MISSING*';
public function __construct(
private readonly SymfonyStyle $symfonyStyle,
diff --git a/src/Composer/PackageSorter.php b/src/Matrix/Composer/PackageSorter.php
similarity index 93%
rename from src/Composer/PackageSorter.php
rename to src/Matrix/Composer/PackageSorter.php
index def4c5c..b967228 100644
--- a/src/Composer/PackageSorter.php
+++ b/src/Matrix/Composer/PackageSorter.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Rector\Monitor\Composer;
+namespace Rector\Monitor\Matrix\Composer;
final class PackageSorter
{
diff --git a/src/Validation/MonitorAssert.php b/src/Validation/MonitorAssert.php
index c67103b..4e37034 100644
--- a/src/Validation/MonitorAssert.php
+++ b/src/Validation/MonitorAssert.php
@@ -24,7 +24,7 @@ public static function assertRepositoryUrl(string $repository): void
{
Assert::regex(
$repository,
- '#git@[\w.-]+:[\w.-]+/[\w.-]+\.git#',
+ '#^(git@[\w.-]+:[\w.-]+/[\w.-]+\.git|https://[\w.-]+/[\w.-]+/[\w.-]+\.git)$#',
sprintf('"%s" is not a valid repository URL', $repository)
);
}
diff --git a/src/ValueObject/Repository.php b/src/ValueObject/Repository.php
index a042421..f8b6b67 100644
--- a/src/ValueObject/Repository.php
+++ b/src/ValueObject/Repository.php
@@ -4,6 +4,7 @@
namespace Rector\Monitor\ValueObject;
+use Rector\Monitor\Helper\JsonFileSystem;
use Symfony\Component\Finder\SplFileInfo;
use Webmozart\Assert\Assert;
@@ -38,7 +39,7 @@ public function getClonableRepositoryUrl(): string
return $this->repositoryUrl;
}
- $authJson = \Rector\Monitor\Helper\JsonFileSystem::readFilePath($bitbucketAuthJson);
+ $authJson = JsonFileSystem::readFilePath($bitbucketAuthJson);
// access bitbucket-oauth, bitbucket.org, consumer-key
$username = $authJson['bitbucket-oauth']['bitbucket.org']['consumer-key'] ?? null;
diff --git a/tests/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php b/tests/Analyze/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php
similarity index 81%
rename from tests/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php
rename to tests/Analyze/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php
index 787c538..8963eeb 100644
--- a/tests/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php
+++ b/tests/Analyze/RuleProcessor/TooLowPackagesRulesProcessor/TooLowPackagesRulesProcessorTest.php
@@ -2,11 +2,12 @@
declare(strict_types=1);
-namespace Rector\Monitor\Tests\RuleProcessor\TooLowPackagesRulesProcessor;
+namespace Rector\Monitor\Tests\Analyze\RuleProcessor\TooLowPackagesRulesProcessor;
+use Override;
+use Rector\Monitor\Analyze\Reporting\ErrorCollector;
+use Rector\Monitor\Analyze\RuleProcessor\TooLowPackagesRulesProcessor;
use Rector\Monitor\Config\MonitorConfig;
-use Rector\Monitor\Reporting\ErrorCollector;
-use Rector\Monitor\RuleProcessor\TooLowPackagesRulesProcessor;
use Rector\Monitor\Tests\AbstractTestCase;
use Rector\Monitor\ValueObject\ComposerJson;
@@ -14,6 +15,7 @@ final class TooLowPackagesRulesProcessorTest extends AbstractTestCase
{
private TooLowPackagesRulesProcessor $tooLowPackagesRulesProcessor;
+ #[Override]
protected function setUp(): void
{
parent::setUp();
diff --git a/tests/project-fixture/first-project/composer.json b/tests/project-fixture/first-project/composer.json
new file mode 100644
index 0000000..58a1c5e
--- /dev/null
+++ b/tests/project-fixture/first-project/composer.json
@@ -0,0 +1,7 @@
+{
+ "require": {
+ "php": ">=8.2",
+ "symfony/console": "^6.4",
+ "symfony/filesystem": "^7.4"
+ }
+}
diff --git a/tests/project-fixture/second-project/composer.json b/tests/project-fixture/second-project/composer.json
new file mode 100644
index 0000000..e8459e4
--- /dev/null
+++ b/tests/project-fixture/second-project/composer.json
@@ -0,0 +1,6 @@
+{
+ "require": {
+ "php": ">=8.0",
+ "symfony/http-kernel": "^8.0"
+ }
+}