-
-
Notifications
You must be signed in to change notification settings - Fork 389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't Prompt the User for Confirmation on the migrations:migrate
Command When There is Nothing to Do
#480
Don't Prompt the User for Confirmation on the migrations:migrate
Command When There is Nothing to Do
#480
Changes from 5 commits
167e75e
e983baf
f0c50ff
0a88035
ee48a6a
b9f207b
750f571
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,12 +118,11 @@ public function setNoMigrationException($noMigrationException = false) | |
* @param string $to The version to migrate to. | ||
* @param boolean $dryRun Whether or not to make this a dry run and not execute anything. | ||
* @param boolean $timeAllQueries Measuring or not the execution time of each SQL query. | ||
* | ||
* @return array $sql The array of migration sql statements | ||
* | ||
* @param callable|null $confirm A callback to confirm whether the migrations should be executed. | ||
* @return array|false An array of migration sql statements or false if the confirm callback denied execution | ||
* @throws MigrationException | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please keep these lines separating params from the return value. It makes things more readable IMO |
||
*/ | ||
public function migrate($to = null, $dryRun = false, $timeAllQueries = false) | ||
public function migrate($to = null, $dryRun = false, $timeAllQueries = false, callable $confirm = null) | ||
{ | ||
/** | ||
* If no version to migrate to is given we default to the last available one. | ||
|
@@ -156,7 +155,11 @@ public function migrate($to = null, $dryRun = false, $timeAllQueries = false) | |
* to signify that there is nothing left to do. | ||
*/ | ||
if ($from === $to && empty($migrationsToExecute) && !empty($migrations)) { | ||
return []; | ||
return $this->noMigrations(); | ||
} | ||
|
||
if (!$dryRun && false === $this->migrationsCanExecute($confirm)) { | ||
return false; | ||
} | ||
|
||
$output = $dryRun ? 'Executing dry run of migration' : 'Migrating'; | ||
|
@@ -168,6 +171,8 @@ public function migrate($to = null, $dryRun = false, $timeAllQueries = false) | |
*/ | ||
if (empty($migrationsToExecute) && !$this->noMigrationException) { | ||
throw MigrationException::noMigrationsToExecute(); | ||
} elseif (empty($migrationsToExecute)) { | ||
return $this->noMigrations(); | ||
} | ||
|
||
$sql = []; | ||
|
@@ -185,4 +190,15 @@ public function migrate($to = null, $dryRun = false, $timeAllQueries = false) | |
|
||
return $sql; | ||
} | ||
|
||
private function noMigrations() | ||
{ | ||
$this->outputWriter->write('<comment>No migrations to execute.</comment>'); | ||
return []; | ||
} | ||
|
||
private function migrationsCanExecute(callable $confirm=null) | ||
{ | ||
return null === $confirm ? true : $confirm(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,7 +83,7 @@ protected function configure() | |
public function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$configuration = $this->getMigrationConfiguration($input, $output); | ||
$migration = new Migration($configuration); | ||
$migration = $this->createMigration($configuration); | ||
|
||
$this->outputHeader($configuration, $output); | ||
|
||
|
@@ -124,30 +124,36 @@ public function execute(InputInterface $input, OutputInterface $output) | |
if ($path = $input->getOption('write-sql')) { | ||
$path = is_bool($path) ? getcwd() : $path; | ||
$migration->writeSqlFile($path, $version); | ||
} else { | ||
$dryRun = (boolean) $input->getOption('dry-run'); | ||
|
||
// warn the user if no dry run and interaction is on | ||
if (! $dryRun) { | ||
$question = 'WARNING! You are about to execute a database migration' | ||
. ' that could result in schema changes and data lost.' | ||
. ' Are you sure you wish to continue? (y/n)'; | ||
if (! $this->canExecute($question, $input, $output)) { | ||
$output->writeln('<error>Migration cancelled!</error>'); | ||
|
||
return 1; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
$migration->setNoMigrationException($input->getOption('allow-no-migration')); | ||
$sql = $migration->migrate($version, $dryRun, $timeAllqueries); | ||
$dryRun = (boolean) $input->getOption('dry-run'); | ||
|
||
if (empty($sql)) { | ||
$output->writeln('<comment>No migrations to execute.</comment>'); | ||
} | ||
$migration->setNoMigrationException($input->getOption('allow-no-migration')); | ||
$result = $migration->migrate($version, $dryRun, $timeAllqueries, function () use ($input, $output) { | ||
$question = 'WARNING! You are about to execute a database migration' | ||
. ' that could result in schema changes and data lost.' | ||
. ' Are you sure you wish to continue? (y/n)'; | ||
return $this->canExecute($question, $input, $output); | ||
}); | ||
|
||
if (false === $result) { | ||
$output->writeln('<error>Migration cancelled!</error>'); | ||
return 1; | ||
} | ||
} | ||
|
||
/** | ||
* Create a new migration instance to execute the migrations. | ||
* | ||
* @param $configuration The configuration with which the migrations will be executed | ||
* @return Migration a new migration instance | ||
*/ | ||
protected function createMigration(Configuration $configuration) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why adding a new method for this ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Purely to make the command easier to unit test using Some of the functional tests cover the happy paths that deal with an actual |
||
{ | ||
return new Migration($configuration); | ||
} | ||
|
||
/** | ||
* @param string $question | ||
* @param InputInterface $input | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace Doctrine\DBAL\Migrations\Tests\Tools\Console\Command; | ||
|
||
use Symfony\Component\Console\Application; | ||
use Symfony\Component\Console\Helper\QuestionHelper; | ||
use Symfony\Component\Console\Helper\DialogHelper; | ||
|
||
trait DialogSupport | ||
{ | ||
protected $questions, $isDialogHelper; | ||
|
||
protected function configureDialogs(Application $app) | ||
{ | ||
if (class_exists(QuestionHelper::class)) { | ||
$this->isDialogHelper = false; | ||
$this->questions = $this->getMock(QuestionHelper::class); | ||
} else { | ||
$this->isDialogHelper = true; | ||
$this->questions = $this->getMock(DialogHelper::class); | ||
} | ||
$app->getHelperSet()->set($this->questions, $this->isDialogHelper ? 'dialog' : 'question'); | ||
} | ||
|
||
protected function willAskConfirmationAndReturn($bool) | ||
{ | ||
$this->questions->expects($this->once()) | ||
->method($this->isDialogHelper ? 'askConfirmation' : 'ask') | ||
->willReturn($bool); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing that bothers me in this PR is the return array or false here. Wouldn't it be better if it returned an empty array in this case ? @chrisguitarguy What do you think.
I can make the change tomorrow if you agree to it ?