Skip to content
Closed
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
7 changes: 7 additions & 0 deletions packages/console/src/Testing/ConsoleTester.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,11 @@ public function dd(): self

return $this;
}

public function dump(): self
{
lw($this->output->asUnformattedString());

return $this;
}
}
6 changes: 4 additions & 2 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
use Rector\Arguments\Rector\ClassMethod\ArgumentAdderRector;
use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\PropertyProperty\RemoveNullPropertyInitializationRector;
use Rector\Php70\Rector\StaticCall\StaticCallOnNonStaticToInstanceCallRector;
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector;
use Rector\Php74\Rector\Ternary\ParenthesizeNestedTernaryRector;
use Rector\Php81\Rector\Array_\FirstClassCallableRector;
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
use Rector\Php82\Rector\Param\AddSensitiveParameterAttributeRector;
use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector;
use Rector\Php84\Rector\Param\ExplicitNullableParamTypeRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector;
use Rector\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector;
Expand All @@ -36,6 +35,9 @@
'secret',
],
])
->withConfiguredRule(RenameClassRector::class, [
'Tempest\\Database\\Id' => 'Tempest\\Database\\PrimaryKey',
])
->withRules([
ExplicitNullableParamTypeRector::class,
])
Expand Down
77 changes: 77 additions & 0 deletions src/Tempest/Framework/Commands/UpgradeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace Tempest\Framework\Commands;

use Composer\Semver\Semver;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use Tempest\Console\Console;
use Tempest\Console\ConsoleArgument;
use Tempest\Console\ConsoleCommand;
use Tempest\Console\ExitCode;
use Tempest\Container\Singleton;
use Tempest\Core\Kernel;

#[Singleton]
final readonly class UpgradeCommand
{
public function __construct(
private Console $console,
) {}

#[ConsoleCommand(
name: 'upgrade:tempest',
description: 'Upgrades the application to the latest version',
)]
public function __invoke(
#[ConsoleArgument(description: 'Upgrade to a specific version', help: 'If not specified, the latest version is used')]
string $version = Kernel::VERSION,
#[ConsoleArgument(description: 'Dry run the upgrade')]
bool $dryRun = false,
#[ConsoleArgument(description: 'Verbose output')]
bool $_verbose = false,
): ExitCode {
$command = 'vendor/bin/rector --no-ansi --no-progress-bar --no-diffs';
if ($dryRun) {
$this->console->info('Dry run enabled');
$command .= ' --dry-run';
}

$rectors = $this->getRectorsForVersion($version);
if (! $rectors->valid()) {
$this->console->info('No rectors found for this version');

return ExitCode::SUCCESS;
}

foreach ($rectors as $rule) {
$command .= " --only=\"{$rule}\"";
}

$this->console->info("Running <code>{$command}</code>");
try {
$processed = Process::fromShellCommandline($command)->mustRun();
} catch (ProcessFailedException $e) {
$this->console->error($e->getProcess()->getErrorOutput());

return ExitCode::ERROR;
}

$this->console->info(trim($processed->getOutput()));

return ExitCode::SUCCESS;
}

private function getRectorsForVersion(string $version): \Generator
{
return match (true) {
Semver::satisfies($version, '^1.0.0') => [],

Check failure on line 70 in src/Tempest/Framework/Commands/UpgradeCommand.php

View workflow job for this annotation

GitHub Actions / Run style check

analysis/undefined-function-or-method

Attempt to call static method on undefined class `Composer\Semver\Semver`. Help: Define or import `Composer\Semver\Semver` before using it.
Semver::satisfies($version, '^2.0.0') => [

Check failure on line 71 in src/Tempest/Framework/Commands/UpgradeCommand.php

View workflow job for this annotation

GitHub Actions / Run style check

analysis/undefined-function-or-method

Attempt to call static method on undefined class `Composer\Semver\Semver`. Help: Define or import `Composer\Semver\Semver` before using it.
yield 'Rector\Renaming\Rector\Name\RenameClassRector',
],
default => [],
};
}
}
32 changes: 32 additions & 0 deletions tests/Integration/Console/Commands/UpgradeCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Integration\Console\Commands;

use PHPUnit\Framework\Attributes\Test;
use Tempest\Console\ExitCode;
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;

class UpgradeCommandTest extends FrameworkIntegrationTestCase
{
#[Test]
public function no_upgrades_for_v1(): void
{
$this->console
->call('upgrade:tempest', ['version' => 'v1.0.0', 'dry-run' => true])
->assertContains(' No rectors found for this version')
->assertExitCode(ExitCode::SUCCESS);
}

#[Test]
public function upgrade_to_v2(): void
{
$this->console
->call('upgrade:tempest', ['version' => 'v2.0.0', 'dry-run' => true])
->assertContains('vendor/bin/rector --no-ansi --no-progress-bar --no-diffs --dry-run --only="Rector\Renaming\Rector\Name\RenameClassRector"')
->assertContains('[OK] Rector is done!')
->dump()
->assertExitCode(ExitCode::SUCCESS);
}
}
Loading