Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.

<br>

Expand All @@ -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;
Expand Down Expand Up @@ -61,7 +61,7 @@ return MonitorConfig::configure()

<br>

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
Expand All @@ -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.

<br>
* 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 <monorepo-project> --merge-project <project-to-be-merged>

# 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

<br>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
52 changes: 52 additions & 0 deletions src/Compare/Comparator/PHPStanLevelComparator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace Rector\Monitor\Compare\Comparator;

use Rector\Monitor\Compare\Contract\ComparatorInterface;
use Rector\Monitor\Compare\ValueObject\ProjectMetadata;
use Symfony\Component\Console\Style\SymfonyStyle;

final readonly class PHPStanLevelComparator implements ComparatorInterface
{
public function __construct(
private SymfonyStyle $symfonyStyle
) {
}

public function compare(
ProjectMetadata $monorepoProjectMetadata,
ProjectMetadata $mergeProjectMetadata
): void {
if (! $monorepoProjectMetadata->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('<fg=yellow>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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Rector\Monitor\Macro\Utils;
namespace Rector\Monitor\Compare\Utils;

final class ArrayUtils
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
29 changes: 28 additions & 1 deletion src/DependencyInjection/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand All @@ -58,4 +76,13 @@ public function hideDefaultCommands(Application $application): void
$application->get('help')
->setHidden(true);
}

/**
* @param class-string<ComparatorInterface> $comparatorClass
*/
private function registerComparator(Container $container, string $comparatorClass): void
{
$container->singleton($comparatorClass);
$container->tag($comparatorClass, ComparatorInterface::class);
}
}