Skip to content

Commit

Permalink
Allow version aliases to be used with execute command
Browse files Browse the repository at this point in the history
  • Loading branch information
Padam87 committed Aug 16, 2021
1 parent 818e317 commit 5b0b076
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 12 deletions.
36 changes: 27 additions & 9 deletions lib/Doctrine/Migrations/Tools/Console/Command/ExecuteCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ protected function configure(): void
->addArgument(
'versions',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'The versions to execute.',
sprintf(
'The versions to execute. Use the FQCN of the migration, or the following reserved aliases: %s',
implode(', ', ['first', 'current', 'prev', 'next', 'latest'])
),
null
)
->addOption(
Expand Down Expand Up @@ -76,6 +79,10 @@ protected function configure(): void
The <info>%command.name%</info> command executes migration versions up or down manually:
<info>%command.full_name% FQCN</info>
You can use version aliases instead of the FQCN:
<info>%command.full_name% current</info>
You can show more information about the process by increasing the verbosity level. To see the
executed queries, set the level to debug with <comment>-vv</comment>:
Expand Down Expand Up @@ -113,20 +120,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
{
$migratorConfigurationFactory = $this->getDependencyFactory()->getConsoleInputMigratorConfigurationFactory();
$migratorConfiguration = $migratorConfigurationFactory->getMigratorConfiguration($input);
$aliasResolver = $this->getDependencyFactory()->getVersionAliasResolver();

$question = sprintf(
'WARNING! You are about to execute a migration in database "%s" that could result in schema changes and data loss. Are you sure you wish to continue?',
$this->getDependencyFactory()->getConnection()->getDatabase() ?? '<unnamed>'
);
if (! $migratorConfiguration->isDryRun() && ! $this->canExecute($question, $input)) {
$this->io->error('Migration cancelled!');
$versions = $input->getArgument('versions');

return 1;
foreach ($versions as &$version) {
$version = (string) $aliasResolver->resolveVersionAlias($version);
}

if (! $migratorConfiguration->isDryRun()) {
$this->io->listing($versions);

$question = sprintf(
'WARNING! You are about to execute the migrations listed above in database "%s" that could result in schema changes and data loss. Are you sure you wish to continue?',
$this->getDependencyFactory()->getConnection()->getDatabase() ?? '<unnamed>'
);

if (! $this->canExecute($question, $input)) {
$this->io->error('Migration cancelled!');

return 1;
}
}

$this->getDependencyFactory()->getMetadataStorage()->ensureInitialized();

$versions = $input->getArgument('versions');
$direction = $input->getOption('down') !== false
? Direction::DOWN
: Direction::UP;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Doctrine\Migrations\Configuration\Connection\ExistingConnection;
use Doctrine\Migrations\Configuration\Migration\ExistingConfiguration;
use Doctrine\Migrations\DependencyFactory;
use Doctrine\Migrations\Exception\UnknownMigrationVersion;
use Doctrine\Migrations\Metadata\MigrationPlan;
use Doctrine\Migrations\Metadata\MigrationPlanList;
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
Expand All @@ -17,6 +18,7 @@
use Doctrine\Migrations\QueryWriter;
use Doctrine\Migrations\Tests\MigrationTestCase;
use Doctrine\Migrations\Tools\Console\Command\ExecuteCommand;
use Doctrine\Migrations\Version\AliasResolver;
use Doctrine\Migrations\Version\Direction;
use Doctrine\Migrations\Version\MigrationPlanCalculator;
use Doctrine\Migrations\Version\Version;
Expand Down Expand Up @@ -47,6 +49,9 @@ class ExecuteCommandTest extends MigrationTestCase
/** @var MigrationPlanCalculator|MockObject */
private $planCalculator;

/** @var AliasResolver|MockObject */
private $versionAliasResolver;

/**
* @param bool|string|null $arg
*
Expand All @@ -63,6 +68,12 @@ public function testWriteSql(bool $dryRun, $arg, ?string $path): void
return ['A'];
});

$this->versionAliasResolver
->expects(self::once())
->method('resolveVersionAlias')
->with('1')
->willReturn(new Version('1'));

if ($arg === false) {
$this->queryWriter
->expects(self::never())
Expand Down Expand Up @@ -116,6 +127,12 @@ public function testExecute(): void
return ['A'];
});

$this->versionAliasResolver
->expects(self::once())
->method('resolveVersionAlias')
->with('1')
->willReturn(new Version('1'));

$this->executeCommandTester->execute([
'versions' => ['1'],
'--down' => true,
Expand All @@ -125,6 +142,63 @@ public function testExecute(): void
self::assertStringContainsString('[notice] Executing 1 up', trim($this->executeCommandTester->getDisplay(true)));
}

public function testExecuteVersionAlias(): void
{
$this->executeCommandTester->setInputs(['yes']);

$this->migrator
->expects(self::once())
->method('migrate')
->willReturnCallback(static function (MigrationPlanList $planList, MigratorConfiguration $configuration): array {
self::assertFalse($configuration->isDryRun());

return ['A'];
});

$this->versionAliasResolver
->expects(self::once())
->method('resolveVersionAlias')
->with('current')
->willReturn(new Version('1'));

$this->executeCommandTester->execute([
'versions' => ['current'],
'--down' => true,
]);

self::assertSame(0, $this->executeCommandTester->getStatusCode());
self::assertStringContainsString('[notice] Executing 1 up', trim($this->executeCommandTester->getDisplay(true)));
}

public function testExecuteVersionAliasException(): void
{
$this->executeCommandTester->setInputs(['yes']);

$this->migrator
->expects(self::never())
->method('migrate')
->willReturnCallback(static function (MigrationPlanList $planList, MigratorConfiguration $configuration): array {
self::assertFalse($configuration->isDryRun());

return ['A'];
});

$exception = new UnknownMigrationVersion('not_a_valid_version_alias');

$this->versionAliasResolver
->expects(self::once())
->method('resolveVersionAlias')
->with('not_a_valid_version_alias')
->willThrowException($exception);

self::expectExceptionObject($exception);

$this->executeCommandTester->execute([
'versions' => ['not_a_valid_version_alias'],
'--down' => true,
]);
}

public function testExecuteMultiple(): void
{
$migration = $this->createMock(AbstractMigration::class);
Expand All @@ -148,6 +222,12 @@ public function testExecuteMultiple(): void
return ['A'];
});

$this->versionAliasResolver
->expects(self::exactly(2))
->method('resolveVersionAlias')
->withConsecutive(['1'], ['2'])
->willReturnOnConsecutiveCalls(new Version('1'), new Version('2'));

$this->executeCommandTester->execute([
'versions' => ['1', '2'],
'--down' => true,
Expand All @@ -174,6 +254,12 @@ public function testExecuteCancel(): void
return ['A'];
});

$this->versionAliasResolver
->expects(self::once())
->method('resolveVersionAlias')
->with('1')
->willReturn(new Version('1'));

$this->executeCommandTester->execute([
'versions' => ['1'],
'--down' => true,
Expand All @@ -186,9 +272,10 @@ protected function setUp(): void
{
$connection = $this->getSqliteConnection();

$this->migrator = $this->createMock(Migrator::class);
$this->queryWriter = $this->createMock(QueryWriter::class);
$migration = $this->createMock(AbstractMigration::class);
$this->migrator = $this->createMock(Migrator::class);
$this->queryWriter = $this->createMock(QueryWriter::class);
$this->versionAliasResolver = $this->createMock(AliasResolver::class);
$migration = $this->createMock(AbstractMigration::class);

$p1 = new MigrationPlan(new Version('1'), $migration, Direction::UP);
$pl = new MigrationPlanList([$p1], Direction::UP);
Expand All @@ -207,6 +294,7 @@ protected function setUp(): void
$this->dependencyFactory->setService(Migrator::class, $this->migrator);
$this->dependencyFactory->setService(MigrationPlanCalculator::class, $this->planCalculator);
$this->dependencyFactory->setService(QueryWriter::class, $this->queryWriter);
$this->dependencyFactory->setService(AliasResolver::class, $this->versionAliasResolver);

$this->executeCommand = new ExecuteCommand($this->dependencyFactory);

Expand Down

0 comments on commit 5b0b076

Please sign in to comment.