Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Last active February 14, 2024 15:55
Show Gist options
  • Save vudaltsov/af27bdc3d0ebc7047d75801493f60c3b to your computer and use it in GitHub Desktop.
Save vudaltsov/af27bdc3d0ebc7047d75801493f60c3b to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace HappyInc\Infrastructure\Migrations;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
final class GroupMigrationsByYearAndMonthCommand extends Command
{
protected static $defaultName = 'migrations:group:by-year-and-month';
protected function configure(): void
{
$this->addArgument('dir', InputArgument::REQUIRED, 'Migrations directory.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title('Group migrations by year and month');
$dir = rtrim($input->getArgument('dir'), '/');
foreach ($this->getMigrationFiles($dir) as $file) {
$relativePathname = $file->getRelativePathname();
$newRelativePathname = $this->getYearAndMonthRelativePathname($file->getBasename());
if ($relativePathname === $newRelativePathname) {
continue;
}
$newPath = \dirname("{$dir}/{$newRelativePathname}");
if (!is_dir($newPath)) {
mkdir($newPath, recursive: true);
}
if (!rename("{$dir}/{$relativePathname}", "{$dir}/{$newRelativePathname}")) {
$io->error("Failed to move {$relativePathname} to {$newRelativePathname}.");
continue;
}
$io->writeln("Moved {$relativePathname} to {$newRelativePathname}.");
}
$io->success('All migrations successfully grouped.');
return self::SUCCESS;
}
/**
* @return iterable<SplFileInfo>
*/
private function getMigrationFiles(string $dir): iterable
{
return
(new Finder())
->files()
->in($dir)
->name('/^Version\d{14}\.php$/')
;
}
private function getYearAndMonthRelativePathname(string $basename): string
{
$year = substr($basename, 7, 4);
$month = substr($basename, 11, 2);
return "{$year}/{$month}/{$basename}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment