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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ This ensures upgrades stay on your radar without overwhelming you. No more "oops

<br>

It's safer to start upgrading dev packages first. You can spot them like this:

```bash
vendor/bin/jack breakpoint --dev
```

<br>

### 2. Open up Next Versions

We know we're behind the latest versions of our dependencies, but where to start? Which versions should be force to update first? We can get lot of conflicts if we try to bump wrong end of knot.
Expand Down
2 changes: 0 additions & 2 deletions ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

declare(strict_types=1);

use Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
->withPreparedSets(psr12: true, common: true, symplify: true)
->withRules([LineLengthFixer::class])
->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
->withRootFiles();
34 changes: 19 additions & 15 deletions src/Command/BreakPointCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
final class BreakPointCommand extends Command
{
public function __construct(
private readonly SymfonyStyle $symfonyStyle,
private readonly OutdatedComposerFactory $outdatedComposerFactory,
private readonly ComposerOutdatedResponseProvider $composerOutdatedResponseProvider
) {
Expand All @@ -28,6 +29,7 @@ protected function configure(): void
$this->setName('breakpoint');

$this->setDescription('Let your CI tell you, if there is too many major-version outdated packages');
$this->addOption('dev', null, InputOption::VALUE_NONE, 'Focus on dev packages only');

$this->addOption(
'limit',
Expand All @@ -41,15 +43,15 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
$maxOutdatePackages = (int) $input->getOption('limit');
$onlyDev = (bool) $input->getOption('dev');

$symfonyStyle = new SymfonyStyle($input, $output);
$symfonyStyle->writeln('<fg=green>Analyzing "composer.json" for major outdated packages</>');
$this->symfonyStyle->writeln('<fg=green>Analyzing "composer.json" for major outdated packages</>');

$responseJsonContents = $this->composerOutdatedResponseProvider->provide();

$responseJson = Json::decode($responseJsonContents, true);
if (! isset($responseJson[ComposerKey::INSTALLED_KEY])) {
$symfonyStyle->success('All packages are up to date');
$this->symfonyStyle->success('All packages are up to date');

return self::SUCCESS;
}
Expand All @@ -60,32 +62,34 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$composerJsonFilePath
);

$symfonyStyle->title(
$this->symfonyStyle->title(
sprintf(
'Found %d outdated package%s',
$outdatedComposer->count(),
$outdatedComposer->count() > 1 ? 's' : ''
$outdatedComposer->count($onlyDev),
$outdatedComposer->count($onlyDev) > 1 ? 's' : ''
)
);

foreach ($outdatedComposer->getPackages() as $outdatedPackage) {
$symfonyStyle->writeln(sprintf('The "<fg=green>%s</>" package is outdated', $outdatedPackage->getName()));
foreach ($outdatedComposer->getPackages($onlyDev) as $outdatedPackage) {
$this->symfonyStyle->writeln(
sprintf('The "<fg=green>%s</>" package is outdated', $outdatedPackage->getName())
);

$symfonyStyle->writeln(sprintf(
$this->symfonyStyle->writeln(sprintf(
' * Your version %s is <fg=%s>%s</>',
$outdatedPackage->getCurrentVersion(),
$outdatedPackage->isVeryOld() ? 'red' : 'yellow',
$outdatedPackage->getCurrentVersionAge(),
));

$symfonyStyle->writeln(sprintf(' * Bump to %s', $outdatedPackage->getLatestVersion()));
$symfonyStyle->newLine();
$this->symfonyStyle->writeln(sprintf(' * Bump to %s', $outdatedPackage->getLatestVersion()));
$this->symfonyStyle->newLine();
}

$symfonyStyle->newLine();
$this->symfonyStyle->newLine();
if ($outdatedComposer->count() >= $maxOutdatePackages) {
// to much → fail
$symfonyStyle->error(sprintf(
$this->symfonyStyle->error(sprintf(
'There %s %d outdated package%s. Update couple of them to get under %d limit',
$outdatedComposer->count() > 1 ? 'are' : 'is',
$outdatedComposer->count(),
Expand All @@ -98,7 +102,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if ($outdatedComposer->count() > max(1, $maxOutdatePackages - 5)) {
// to much → fail
$symfonyStyle->warning(sprintf(
$this->symfonyStyle->warning(sprintf(
'There are %d outdated packages. Soon, the count will go over %d limit and this job will fail.%sUpgrade in time',
$outdatedComposer->count(),
$maxOutdatePackages,
Expand All @@ -109,7 +113,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

// to many → fail
$symfonyStyle->success(
$this->symfonyStyle->success(
sprintf('Still far away from limit %d. Good job keeping your project up to date!', $maxOutdatePackages)
);

Expand Down
22 changes: 11 additions & 11 deletions src/Command/OpenVersionsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ final class OpenVersionsCommand extends Command
public function __construct(
private readonly NextVersionResolver $nextVersionResolver,
private readonly OutdatedComposerFactory $outdatedComposerFactory,
private readonly ComposerOutdatedResponseProvider $composerOutdatedResponseProvider
private readonly ComposerOutdatedResponseProvider $composerOutdatedResponseProvider,
private readonly SymfonyStyle $symfonyStyle
) {
parent::__construct();
}
Expand All @@ -42,15 +43,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
{
$composerJsonFilePath = getcwd() . '/composer.json';

$symfonyStyle = new SymfonyStyle($input, $output);
$symfonyStyle->title('Analyzing "composer.json" for outdated packages');
$symfonyStyle->writeln(' This might take 10-30 seconds to finish, depending on your dependency count');
$this->symfonyStyle->title('Analyzing "composer.json" for outdated packages');
$this->symfonyStyle->writeln(' This might take 10-30 seconds to finish, depending on your dependency count');

$responseJsonContents = $this->composerOutdatedResponseProvider->provide();

$responseJson = Json::decode($responseJsonContents, true);
if (! isset($responseJson[ComposerKey::INSTALLED_KEY])) {
$symfonyStyle->success('All packages are up to date. You are the best!');
$this->symfonyStyle->success('All packages are up to date. You are the best!');

return self::SUCCESS;
}
Expand All @@ -60,15 +60,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$composerJsonFilePath
);

$symfonyStyle->warning(
$this->symfonyStyle->warning(
sprintf(
'Found %d outdated package%s',
$outdatedComposer->count(),
$outdatedComposer->count() === 1 ? '' : 's'
)
);

$symfonyStyle->listing([
$this->symfonyStyle->listing([
sprintf(
'%d prod package%s',
$outdatedComposer->getProdPackagesCount(),
Expand All @@ -81,8 +81,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
),
]);

$symfonyStyle->newLine();
$symfonyStyle->title('Opening version constraints in "composer.json"');
$this->symfonyStyle->newLine();
$this->symfonyStyle->title('Opening version constraints in "composer.json"');

$limit = (int) $input->getOption('limit');
$isDryRun = (bool) $input->getOption('dry-run');
Expand Down Expand Up @@ -112,7 +112,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$openedVersion
);

$symfonyStyle->writeln(sprintf(
$this->symfonyStyle->writeln(sprintf(
' * Opened "<fg=green>%s</>" package to "<fg=yellow>%s</>" version',
$outdatedPackage->getName(),
$openedVersion
Expand All @@ -130,7 +130,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
FileSystem::write($composerJsonFilePath, $composerJsonContents . PHP_EOL);
}

$symfonyStyle->success(
$this->symfonyStyle->success(
sprintf(
'%d packages %s opened up to the next nearest version.%s%s "composer update" to push versions up',
$openedPackageCount,
Expand Down
10 changes: 6 additions & 4 deletions src/ValueObject/OutdatedComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,19 @@ public function getDevPackages(): array
);
}

public function count(): int
public function count(bool $onlyDev = false): int
{
return count($this->outdatedPackages);
$packages = $onlyDev ? $this->getDevPackages() : $this->outdatedPackages;

return count($packages);
}

/**
* @return OutdatedPackage[]
*/
public function getPackages(): array
public function getPackages(bool $onlyDev = false): array
{
return $this->outdatedPackages;
return $onlyDev ? $this->getDevPackages() : $this->outdatedPackages;
}

/**
Expand Down