Skip to content

Commit

Permalink
add migration step migration_definition/include
Browse files Browse the repository at this point in the history
  • Loading branch information
gggeek committed Nov 18, 2022
1 parent 2840e25 commit f5469f2
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 64 deletions.
26 changes: 23 additions & 3 deletions Command/MassMigrateCommand.php
Expand Up @@ -116,7 +116,7 @@ protected function executeAsParent($input, $output, $toExecute, $start)
$concurrency = $input->getOption('concurrency');
$this->writeln("Executing migrations using " . count($paths) . " processes with a concurrency of $concurrency");

// allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
// Allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
if ($input->getOption('force-sigchild-enabled')) {
Process::forceSigchildEnabled(true);
}
Expand Down Expand Up @@ -231,9 +231,27 @@ protected function executeAsChild($input, $output, $toExecute, $force, $migratio
}

$builderArgs = parent::createChildProcessArgs($input);
} else {
$forcedRefs = array();
if ($input->getOption('set-reference')) {
foreach ($input->getOption('set-reference') as $refSpec) {
$ref = explode(':', $refSpec, 2);
if (count($ref) < 2 || $ref[0] === '') {
throw new \InvalidArgumentException("Invalid reference specification: '$refSpec'");
}
$forcedRefs[$ref[0]] = $ref[1];
}
}
$migrationContext = array(
'useTransactions' => !$input->getOption('no-transactions'),
'defaultLanguageCode' => $input->getOption('default-language'),
'adminUserLogin' => $input->getOption('admin-login'),
'forceExecution' => $force,
'forcedReferences' => $forcedRefs
);
}

// allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
// Allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
if ($input->getOption('force-sigchild-enabled')) {
Process::forceSigchildEnabled(true);
}
Expand Down Expand Up @@ -284,9 +302,11 @@ protected function executeAsChild($input, $output, $toExecute, $force, $migratio
} else {

try {
$this->executeMigrationInProcess($migrationDefinition, $force, $migrationService, $input);
$this->executeMigrationInProcess($migrationDefinition, $migrationService, $migrationContext);

$executed++;
// in case the 1st mig changes values to the refs, we avoid injecting them in the 2nd mig and later
$migrationContext['forcedReferences'] = array();
} catch (\Exception $e) {
$failed++;

Expand Down
46 changes: 26 additions & 20 deletions Command/MigrateCommand.php
Expand Up @@ -136,29 +136,36 @@ protected function execute(InputInterface $input, OutputInterface $output)
$builder->setPrefix($prefix);
}
$builderArgs = $this->createChildProcessArgs($input);
} else {
$forcedRefs = array();
if ($input->getOption('set-reference')) {
foreach ($input->getOption('set-reference') as $refSpec) {
$ref = explode(':', $refSpec, 2);
if (count($ref) < 2 || $ref[0] === '') {
throw new \InvalidArgumentException("Invalid reference specification: '$refSpec'");
}
$forcedRefs[$ref[0]] = $ref[1];
}
}
$migrationContext = array(
'useTransaction' => !$input->getOption('no-transactions'),
'defaultLanguageCode' => $input->getOption('default-language'),
'adminUserLogin' => $input->getOption('admin-login'),
'forceExecution' => $force,
'forcedReferences' => $forcedRefs
);
}

// For cli scripts, this means: do not die if anyone yanks out our stdout.
if ($input->getOption('survive-disconnected-tty')) {
ignore_user_abort(true);
}

// allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
// Allow forcing handling of sigchild. Useful on eg. Debian and Ubuntu
if ($input->getOption('force-sigchild-enabled')) {
Process::forceSigchildEnabled(true);
}

if ($input->getOption('set-reference') && !$input->getOption('separate-process')) {
$refResolver = $this->getContainer()->get('ez_migration_bundle.reference_resolver.customreference');
foreach ($input->getOption('set-reference') as $refSpec) {
$ref = explode(':', $refSpec, 2);
if (count($ref) < 2 || $ref[0] === '') {
throw new \InvalidArgumentException("Invalid reference specification: '$refSpec'");
}
$refResolver->addReference($ref[0], $ref[1], true);
}
}

$aborted = false;
$executed = 0;
$failed = 0;
Expand Down Expand Up @@ -212,9 +219,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
} else {

try {
$this->executeMigrationInProcess($migrationDefinition, $force, $migrationService, $input);
$this->executeMigrationInProcess($migrationDefinition, $migrationService, $migrationContext);

$executed++;

// in case the 1st mig changes values to the refs, we avoid injecting them in the 2nd mig and later
$migrationContext['forcedReferences'] = array();
} catch (\Exception $e) {
$failed++;

Expand Down Expand Up @@ -260,18 +270,14 @@ protected function execute(InputInterface $input, OutputInterface $output)

/**
* @param MigrationDefinition $migrationDefinition
* @param bool $force
* @param MigrationService $migrationService
* @param InputInterface $input
* @param array $migrationContext
*/
protected function executeMigrationInProcess($migrationDefinition, $force, $migrationService, $input)
protected function executeMigrationInProcess($migrationDefinition, $migrationService, $migrationContext)
{
$migrationService->executeMigration(
$migrationDefinition,
!$input->getOption('no-transactions'),
$input->getOption('default-language'),
$input->getOption('admin-login'),
$force
$migrationContext
);
}

Expand Down
14 changes: 11 additions & 3 deletions Command/ResumeCommand.php
Expand Up @@ -12,7 +12,7 @@
* Command to resume suspended migrations.
*
* @todo add support for resuming a set based on path
* @todo add support for the separate-process cli switch
* @todo add support for the separate-process cli switch, as well as clear-cache, default-language, force-sigchild-enabled, survive-disconnected-tty
*/
class ResumeCommand extends AbstractCommand
{
Expand Down Expand Up @@ -97,7 +97,6 @@ protected function execute(InputInterface $input, OutputInterface $output)

$forcedRefs = array();
if ($input->getOption('set-reference') /*&& !$input->getOption('separate-process')*/) {
//$refResolver = $this->getContainer()->get('ez_migration_bundle.reference_resolver.customreference');
foreach ($input->getOption('set-reference') as $refSpec) {
$ref = explode(':', $refSpec, 2);
if (count($ref) < 2 || $ref[0] === '') {
Expand All @@ -110,11 +109,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
$executed = 0;
$failed = 0;

$migrationContext = array(
'useTransaction' => !$input->getOption('no-transactions'),
'forcedReferences' => $forcedRefs,
);

foreach ($suspendedMigrations as $suspendedMigration) {
$output->writeln("<info>Resuming {$suspendedMigration->name}</info>");

try {
$migrationService->resumeMigration($suspendedMigration, !$input->getOption('no-transactions'), $forcedRefs);
$migrationService->resumeMigration($suspendedMigration, $migrationContext);

$executed++;
} catch (\Exception $e) {
Expand All @@ -126,6 +130,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->errOutput->writeln("\n<error>Migration aborted! Reason: " . $e->getMessage() . "</error>");
return 1;
}

// in case we are resuming many migrations, and the 1st one changes values to the injected refs, we do not
// inject them any more from the 2nd onwards
$migrationContext['forcedReferences'] = array();
}

$time = microtime(true) - $start;
Expand Down
38 changes: 37 additions & 1 deletion Core/Executor/MigrationDefinitionExecutor.php
Expand Up @@ -20,7 +20,7 @@ class MigrationDefinitionExecutor extends AbstractExecutor
use ReferenceSetterTrait;

protected $supportedStepTypes = array('migration_definition');
protected $supportedActions = array('generate', 'save');
protected $supportedActions = array('generate', 'save', 'include');

/** @var \Kaliop\eZMigrationBundle\Core\MigrationService $migrationService */
protected $migrationService;
Expand Down Expand Up @@ -52,9 +52,45 @@ public function execute(MigrationStep $step)

$this->skipStepIfNeeded($step);

if ($action === 'include') {
// we can not use a keyword as method name
$action = 'run';
}

return $this->$action($step->dsl, $step->context);
}

public function run($dsl, $context)
{
if (!isset($dsl['file'])) {
throw new InvalidStepDefinitionException("Invalid step definition: miss 'file'");
}
$fileName = $this->resolveReference($dsl['file']);

// default format: path is relative to the current mig dir
$realFilePath = dirname($context['path']) . $fileName;
// but we support as well absolute paths
if (!is_file($realFilePath) && is_file($fileName)) {
$realFilePath = $fileName;
}

$migrationDefinitions = $this->migrationService->getMigrationsDefinitions(array($realFilePath));
if (!count($migrationDefinitions)) {
throw new InvalidStepDefinitionException("Invalid step definition: '$fileName' is not a valid migration definition");
}

// avoid overwriting the 'current migration definition file path' for the included definition
unset($context['path']);

/// @todo can we could have the included migration's steps be printed as 1.1, 1.2 etc...
/// @todo we could return the result of the included migration's last step
foreach($migrationDefinitions as $migrationDefinition) {
$this->migrationService->executeMigration($migrationDefinition, $context);
}

return true;
}

/**
* @todo allow to save to disk
* @param array $dsl
Expand Down

0 comments on commit f5469f2

Please sign in to comment.