migrations dev

This commit is contained in:
Yuri Kuznetsov
2024-04-05 12:17:00 +03:00
parent 382ba22cd7
commit 977b9adeff
5 changed files with 79 additions and 37 deletions
@@ -131,7 +131,7 @@ abstract class Base
return $this->getContainer()->getByClass(FileManager::class);
}
private function getConfig(): Config
protected function getConfig(): Config
{
return $this->getContainer()->getByClass(Config::class);
}
@@ -141,6 +141,11 @@ abstract class Base
return $this->getContainer()->getByClass(EntityManager::class);
}
protected function getInjectableFactory(): InjectableFactory
{
return $this->getContainer()->getByClass(InjectableFactory::class);
}
protected function createConfigWriter(): ConfigWriter
{
$injectableFactory = $this->getContainer()->getByClass(InjectableFactory::class);
@@ -30,6 +30,9 @@
namespace Espo\Core\Upgrades\Actions\Upgrade;
use Espo\Core\Exceptions\Error;
use Espo\Core\Upgrades\Migration\Script;
use Espo\Core\Upgrades\Migration\VersionUtil;
use RuntimeException;
class Install extends \Espo\Core\Upgrades\Actions\Base\Install
{
@@ -49,6 +52,7 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
public function stepAfterUpgradeScript(array $data): void
{
$this->stepAfterInstallScript($data);
$this->runMigrationAfterInstallScript();
}
/**
@@ -82,9 +86,54 @@ class Install extends \Espo\Core\Upgrades\Actions\Base\Install
$version = $this->getManifest()['version'];
if (!$version) {
throw new Error("No 'version' in manifest.");
throw new RuntimeException("No 'version' in manifest.");
}
return $version;
}
/**
* @throws Error
*/
private function runMigrationAfterInstallScript(): void
{
$targetVersion = $this->getTargetVersion();
$version = $this->getConfig()->get('version');
if (!$version || !is_string($version)) {
throw new RuntimeException("No or bad 'version' in config.");
}
$script = $this->getMigrationAfterInstallScript($version, $targetVersion);
if (!$script) {
return;
}
$script->run();
}
private function getMigrationAfterInstallScript(string $version, string $targetVersion): ?Script
{
$isPatch = VersionUtil::isPatch($version, $targetVersion);
$a = VersionUtil::split($targetVersion);
$dir = $isPatch ?
'V' . $a[0] . '_' . $a[1] . '_' . $a[2] :
'V' . $a[0] . '_' . $a[1];
$className = "Espo\\Core\\Upgrades\\Migrations\\$dir\\AfterUpgrade";
if (!class_exists($className)) {
return null;
}
$script = $this->getInjectableFactory()->create($className);
if (!$script instanceof Script) {
throw new RuntimeException("$className does not implement Script interface.");
}
return $script;
}
}
@@ -35,7 +35,6 @@ use RuntimeException;
class Runner
{
public function __construct(
private StepsExtractor $stepsExtractor,
private StepsProvider $stepsProvider,
private VersionDataProvider $versionDataProvider,
private StepRunner $stepRunner
@@ -47,7 +46,7 @@ class Runner
$targetVersion = $this->versionDataProvider->getTargetVersion();
$fullList = $this->stepsProvider->getAfterUpgrade();
$steps = $this->stepsExtractor->extract($version, $targetVersion, $fullList);
$steps = VersionUtil::extractSteps($version, $targetVersion, $fullList);
if ($steps === []) {
$io->writeLine(" No migrations to run.");
@@ -32,20 +32,17 @@ namespace Espo\Core\Upgrades\Migration;
use RuntimeException;
use const SORT_STRING;
class StepsExtractor
class VersionUtil
{
/**
* @param string[] $fullList
* @return string[]
*/
public function extract(string $from, string $to, array $fullList): array
public static function extractSteps(string $from, string $to, array $fullList): array
{
sort($fullList, SORT_STRING);
$aFrom = self::split($from);
$aTo = self::split($to);
$isHotfix = $aFrom[0] === $aTo[0] && $aFrom[1] === $aTo[1];
$isPatch = self::isPatch($from, $to);
$list = [];
@@ -62,7 +59,7 @@ class StepsExtractor
continue;
}
if (!$isHotfix && $a[2] !== null) {
if (!$isPatch && $a[2] !== null) {
continue;
}
@@ -75,7 +72,7 @@ class StepsExtractor
/**
* @return array{string, string, ?string}
*/
private static function split(string $version): array
public static function split(string $version): array
{
$array = explode('.', $version, 3);
@@ -90,4 +87,12 @@ class StepsExtractor
/** @var array{string, string, string} */
return $array;
}
public static function isPatch(string $from, string $to): bool
{
$aFrom = self::split($from);
$aTo = self::split($to);
return $aFrom[0] === $aTo[0] && $aFrom[1] === $aTo[1];
}
}
@@ -29,16 +29,14 @@
namespace tests\unit\Espo\Core\Upgrades\Migration;
use Espo\Core\Upgrades\Migration\StepsExtractor;
use Espo\Core\Upgrades\Migration\VersionUtil;
use PHPUnit\Framework\TestCase;
class StepsExtractorTest extends TestCase
{
public function testGet1(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.0.0', '8.3.0', [
$list = VersionUtil::extractSteps('8.0.0', '8.3.0', [
'7.0',
'7.5',
'8.0',
@@ -56,9 +54,7 @@ class StepsExtractorTest extends TestCase
public function testGet2(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.0.0', '8.3.1', [
$list = VersionUtil::extractSteps('8.0.0', '8.3.1', [
'7.0',
'7.5',
'8.0',
@@ -76,9 +72,7 @@ class StepsExtractorTest extends TestCase
public function testGet3(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.0.0', '8.3.5', [
$list = VersionUtil::extractSteps('8.0.0', '8.3.5', [
'7.0',
'7.5',
'8.0',
@@ -96,9 +90,7 @@ class StepsExtractorTest extends TestCase
public function testGet4(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.2.0', '8.3.5', [
$list = VersionUtil::extractSteps('8.2.0', '8.3.5', [
'7.0',
'7.5',
'8.0',
@@ -115,9 +107,7 @@ class StepsExtractorTest extends TestCase
public function testGet5(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.0.4', '8.3.5', [
$list = VersionUtil::extractSteps('8.0.4', '8.3.5', [
'7.0',
'7.5',
'8.0',
@@ -135,9 +125,7 @@ class StepsExtractorTest extends TestCase
public function testGetMajor1(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('7.5.4', '8.3.5', array_reverse([
$list = VersionUtil::extractSteps('7.5.4', '8.3.5', array_reverse([
'7.0',
'7.5',
'7.5.1',
@@ -160,9 +148,7 @@ class StepsExtractorTest extends TestCase
public function testGetPatch1(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.3.0', '8.3.5', [
$list = VersionUtil::extractSteps('8.3.0', '8.3.5', [
'7.0',
'7.5',
'8.0',
@@ -181,9 +167,7 @@ class StepsExtractorTest extends TestCase
public function testGetPatch2(): void
{
$extractor = new StepsExtractor();
$list = $extractor->extract('8.3.0', '8.3.5', [
$list = VersionUtil::extractSteps('8.3.0', '8.3.5', [
'7.0',
'7.5',
'8.0',