Last active
August 17, 2018 06:35
-
-
Save nenadalm/9102892 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
define('MIGRATIONS_DIR', 'app/DoctrineMigrations'); | |
list(, $previousHead, $currentHead) = $argv; | |
$excessMigrations = getExcessMigrations($previousHead, $currentHead); | |
rsort($excessMigrations); | |
removeExcessMigrations($excessMigrations, $previousHead); | |
addMissingMigrations(); | |
function addMissingMigrations() | |
{ | |
passthru('php app/console --ansi doctrine:migrations:migrate --no-interaction'); | |
} | |
function removeExcessMigrations(array $excessMigrations, $previousHead) | |
{ | |
foreach ($excessMigrations as $missingMigration) { | |
$migrationFilePath = filePathOfMigration($missingMigration); | |
passthru(sprintf('git checkout %s %s', $previousHead, $migrationFilePath)); | |
passthru(sprintf('git reset HEAD %s', $migrationFilePath)); | |
$output = runProccess(sprintf('php app/console --ansi doctrine:migrations:execute %s --down --no-interaction', $missingMigration)); | |
echo $output->getStdout(), $output->getStderr(); | |
unlink($migrationFilePath); | |
if (strlen($output->getStderr())) { | |
exit(1); | |
} | |
} | |
} | |
function getExcessMigrations($previousHead, $currentHead) | |
{ | |
exec(sprintf('git diff --name-status %s %s %s', $previousHead, $currentHead, MIGRATIONS_DIR), $output); | |
$missingMigrationStatusFiles = array_filter($output, function($statusFile) { | |
return strpos($statusFile, 'D') === 0; | |
}); | |
$excessMigrations = array_map(function($statusFile) { | |
$matches = []; | |
preg_match('/Version([0-9]+)\.php$/', $statusFile, $matches); | |
return $matches[1]; | |
}, $missingMigrationStatusFiles); | |
return $excessMigrations; | |
} | |
function filePathOfMigration($version) | |
{ | |
return sprintf('%s/Version%s.php', MIGRATIONS_DIR, $version); | |
} | |
function runProccess($cmd) | |
{ | |
$proc = proc_open($cmd, [ | |
0 => ['pipe', 'r'], | |
1 => ['pipe', 'w'], | |
2 => ['pipe', 'w'], | |
], $pipes); | |
$stdout = stream_get_contents($pipes[1]); | |
$stderr = stream_get_contents($pipes[2]); | |
array_map('fclose', $pipes); | |
proc_close($proc); | |
return new ProcOutput($stdout, $stderr); | |
} | |
class ProcOutput | |
{ | |
private $stdout; | |
private $stderr; | |
public function __construct($stdout = '', $stderr = '') | |
{ | |
$this->stdout = $stdout; | |
$this->stderr = $stderr; | |
} | |
public function getStdout() | |
{ | |
return $this->stdout; | |
} | |
public function getStderr() | |
{ | |
return $this->stderr; | |
} | |
} |
Thanks. I am thinking about removing this gist though - as I didn't use it for several years (the project it was useful on is no longer under development and projects I am currently working on don't require such script).
The script was written because an app I was working on was hard and time consuming to reinstall (old migrations were broken, they took very long time to run...) and I had to switch between several development branches each with different migrations (migrations were often renamed when branch was merged into another branch - so that newly merged migrations were after all previously run migrations of the other branch).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great script!
You also have the possibility to use git show to get migrations to revert line #20:
instead of