Skip to content

Commit

Permalink
expand capabilities of MigrationDefinitionExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
gggeek committed Jun 30, 2020
1 parent f8e7b1b commit 27dd844
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 27 deletions.
2 changes: 2 additions & 0 deletions Command/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ protected function generateMigrationFile($migrationType, $migrationMode, $fileTy

switch ($fileType) {
case 'yml':
case 'yaml':
/// @todo use Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE option if it is supported
$code = Yaml::dump($data, 5);
break;
case 'json':
Expand Down
104 changes: 81 additions & 23 deletions Core/Executor/MigrationDefinitionExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MigrationDefinitionExecutor extends AbstractExecutor
use IgnorableStepExecutorTrait;

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

/** @var \Kaliop\eZMigrationBundle\Core\MigrationService $migrationService */
protected $migrationService;
Expand Down Expand Up @@ -98,31 +98,64 @@ protected function generate($dsl, $context)

$fileName = $this->referenceResolver->resolveReference($dsl['file']);

$ext = pathinfo(basename($fileName), PATHINFO_EXTENSION);
$this->saveDefinition($result, $fileName);
}

switch ($ext) {
case 'yml':
case 'yaml':
$code = Yaml::dump($result, 5);
break;
case 'json':
$code = json_encode($result, JSON_PRETTY_PRINT);
break;
default:
throw new \Exception("Can not save generated migration to a file of type '$ext'");
}
$this->setReferences($result, $dsl);

$dir = dirname($fileName);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
return $result;
}

file_put_contents($fileName, $code);
public function save($dsl, $context)
{
if (!isset($dsl['migration_steps'])) {
throw new \Exception("Invalid step definition: miss 'migration_steps'");
}
if (!isset($dsl['file'])) {
throw new \Exception("Invalid step definition: miss 'file'");
}

$this->setReferences($result, $dsl);
if (is_string($dsl['migration_steps'])) {
$definition = $this->referenceResolver->resolveReference($dsl['migration_steps']);
} else {
$definition = $dsl['migration_steps'];
}
$definition = $this->resolveReferencesRecursively($definition);

return $result;
$fileName = $this->referenceResolver->resolveReference($dsl['file']);

$this->saveDefinition($definition, $fileName);

/// @todo what to allow setting refs to ?
/// @todo what to return ?
}

protected function saveDefinition($definition, $fileName)
{
$ext = pathinfo(basename($fileName), PATHINFO_EXTENSION);

switch ($ext) {
case 'yml':
case 'yaml':
/// @todo use Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE option if it is supported
$code = Yaml::dump($definition, 5);
break;
case 'json':
$code = json_encode($definition, JSON_PRETTY_PRINT);
break;
default:
throw new \Exception("Can not save migration definition to a file of type '$ext'");
}

$dir = dirname($fileName);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}

if (!file_put_contents($fileName, $code)) {
throw new \Exception("Failed saving migration definition to file '$fileName'");
}
}

protected function setReferences($result, $dsl)
Expand All @@ -132,15 +165,24 @@ protected function setReferences($result, $dsl)
}

foreach ($dsl['references'] as $reference) {
if (!isset($reference['json_path'])) {
throw new \InvalidArgumentException('MigrationDefinition Executor does not support setting references if not using a json_path expression');
// BC
if (isset($reference['json_path'])) {
$reference['attribute'] = $reference['json_path'];
}

switch ($reference['attribute']) {
case 'definition':
$value = $result;
break;
default:
$value = JmesPath::search($reference['json_path'], $result);
}

$overwrite = false;
if (isset($reference['overwrite'])) {
$overwrite = $reference['overwrite'];
}
$value = JmesPath::search($reference['json_path'], $result);

$this->referenceResolver->addReference($reference['identifier'], $value, $overwrite);
}
}
Expand All @@ -161,4 +203,20 @@ protected function getGeneratingExecutors()
}
return $executors;
}

/**
* @todo should be moved into the reference resolver classes
* @todo allow resolving references within texts, not only as full value
*/
protected function resolveReferencesRecursively($match)
{
if (is_array($match)) {
foreach ($match as $condition => $values) {
$match[$condition] = $this->resolveReferencesRecursively($values);
}
return $match;
} else {
return $this->referenceResolver->resolveReference($match);
}
}
}
1 change: 1 addition & 0 deletions Core/Executor/ReferenceExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ protected function save($dsl, $context)
break;
case 'yml':
case 'yaml':
/// @todo use Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE option if it is supported
$data = Yaml::dump($data);
break;
default:
Expand Down
1 change: 0 additions & 1 deletion Resources/doc/DSL/Contents.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
filename: abc # Optional, taken from the actual file if not specified
mime_type: def # Optional. For ezbinaryfile and ezmedia only. If not specified, the actual file is analyzed using the php function mime_content_type()
# NB: this seems to work only with eZPublish < 5.4 / 2014.11; see bug https://github.com/kaliop-uk/ezmigrationbundle/issues/147
has_controller: false # Optional. For ezmedia only
autoplay: false # Optional. For ezmedia only
loop: false # Optional. For ezmedia only
has_controller: false # Optional. For ezmedia only
Expand Down
19 changes: 18 additions & 1 deletion Resources/doc/DSL/MigrationDefinitions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,25 @@
references:
-
identifier: # A string used to identify the reference
json_path: zzz # Since the generated migration is a nested structure, you have to use a selector, eg: '[0].name_pattern'
attribute: zzz # This can be either the keyword 'definition', in which case the whole definition will be saved,
# or a selector identifying a subset, eg: '[0].name_pattern'
# For syntax, see: http://jmespath.org/tutorial.html, http://jmespath.org/specification.html#grammar
if: # Optional. If set, the migration step will be skipped unless the condition is matched
"reference:_ref_name": # name of a reference to be used for the test
_operator_: value # allowed operators: eq, gt, gte, lt, lte, ne, count, length, regexp, satisfies

-
type: migration_definition
mode: save
migration_steps: # an array of steps. References will be resolved recursively. Ex:
-
type: content
mode: update
match: { location_id: 2 }
attributes: { }
- etc...
file: string # path to the file to be generated. Mandatory.
# The filename must end with an extension of either .yml or .json
if: # Optional. If set, the migration step will be skipped unless the condition is matched
"reference:_ref_name": # name of a reference to be used for the test
_operator_: value # allowed operators: eq, gt, gte, lt, lte, ne, count, length, regexp, satisfies
13 changes: 11 additions & 2 deletions WHATSNEW.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
Version 5.11.0
==============

* New: new constraints 'isnull' and 'notnull' are now supported in 'if' clauses to match references
* New: new constraints `isnull` and `notnull` are now supported in 'if' clauses to match references values

* New: the `migration_definition/generate` step now supports 'if' clauses
* New: the `migration_definition/generate` step now supports an 'if' clause

* New: the `migration_definition/generate` step now supports setting a reference to the whole definition

* New migration step: `migration_definition/save`. Useful in content migrations / syndication scenarios

* BC changes:

- the `migration_definition/generate` step now uses a different syntax for setting references. The old one is
still accepted but deprecated (key `json_path` has been replaced by `attribute`)


Version 5.10.2
Expand Down

0 comments on commit 27dd844

Please sign in to comment.