Skip to content

Commit

Permalink
Merge pull request #294 from goetas/forward-compat-v3
Browse files Browse the repository at this point in the history
Forward compatibility layer for v3.x
  • Loading branch information
goetas committed Mar 28, 2020
2 parents 856437e + 54598cd commit ddcc1c5
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 26 deletions.
63 changes: 47 additions & 16 deletions .doctrine-project.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,49 @@
{
"name": "Doctrine Migrations Bundle",
"shortName": "DoctrineMigrationsBundle",
"slug": "doctrine-migrations-bundle",
"versions": [
{
"name": "2.0",
"branchName": "2.0",
"slug": "2.0",
"current": true
},
{
"name": "1.3",
"branchName": "1.3",
"slug": "1.3"
}
]
"name": "Doctrine Migrations Bundle",
"shortName": "DoctrineMigrationsBundle",
"slug": "doctrine-migrations-bundle",
"versions": [
{
"name": "2.2",
"branchName": "master",
"slug": "2.2",
"upcoming": true
},
{
"name": "2.1",
"branchName": "2.1.x",
"slug": "2.1",
"current": true
},
{
"name": "2.0",
"branchName": "2.0.x",
"slug": "2.0",
"maintained": false
},
{
"name": "1.3",
"branchName": "1.3",
"slug": "1.3",
"maintained": false
},
{
"name": "1.2",
"branchName": "1.2",
"slug": "1.2",
"maintained": false
},
{
"name": "1.1",
"branchName": "1.1",
"slug": "1.1",
"maintained": false
},
{
"name": "1.0",
"branchName": "1.0",
"slug": "1.0",
"maintained": false
}
]
}
79 changes: 72 additions & 7 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use function constant;
use function count;
use function in_array;
use function is_string;
use function method_exists;
Expand Down Expand Up @@ -41,14 +42,78 @@ public function getConfigTreeBuilder() : TreeBuilder

$rootNode
->children()
->scalarNode('dir_name')->defaultValue('%kernel.root_dir%/DoctrineMigrations')->cannotBeEmpty()->end()
->scalarNode('namespace')->defaultValue('Application\Migrations')->cannotBeEmpty()->end()
->scalarNode('table_name')->defaultValue('migration_versions')->cannotBeEmpty()->end()
->scalarNode('column_name')->defaultValue('version')->end()
->scalarNode('column_length')->defaultValue(14)->end()
->scalarNode('executed_at_column_name')->defaultValue('executed_at')->end()
->scalarNode('name')
->setDeprecated('The "%node%" option is deprecated.')
->defaultValue('Application Migrations')
->end()

// 3.x forward compatibility layer
->arrayNode('migrations_paths')
->info('A list of pairs namespace/path where to look for migrations.')
->useAttributeAsKey('name')
->defaultValue([])
->prototype('scalar')->end()
->validate()
->ifTrue(static function ($v) : bool {
return count($v) === 0;
})
->thenInvalid('At least one migration path must be specified.')

->ifTrue(static function ($v) : bool {
return count($v) > 1;
})
->thenInvalid('Maximum one migration path can be specified with the 2.x version.')
->end()
->end()

->arrayNode('storage')
->info('Storage to use for migration status metadata.')
->children()
->arrayNode('table_storage')
->info('The default metadata storage, implemented as database table.')
->children()
->scalarNode('table_name')->defaultValue(null)->cannotBeEmpty()->end()
->scalarNode('version_column_name')->defaultValue(null)->end()
->scalarNode('version_column_length')
->defaultValue(null)
->validate()
->ifTrue(static function ($v) : bool {
return $v < 1024;
})
->thenInvalid('The minimum length for the version column is 1024.')
->end()
->end()
->scalarNode('executed_at_column_name')->defaultValue(null)->end()
->end()
->end()
->end()
->end()

->scalarNode('dir_name')
->defaultValue('%kernel.root_dir%/DoctrineMigrations')->cannotBeEmpty()
->setDeprecated('The "%node%" option is deprecated. Use "migrations_paths" instead.')
->end()
->scalarNode('namespace')
->defaultValue('Application\Migrations')->cannotBeEmpty()
->setDeprecated('The "%node%" option is deprecated. Use "migrations_paths" instead.')
->end()
->scalarNode('table_name')
->defaultValue('migration_versions')->cannotBeEmpty()
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.table_name" instead.')
->end()
->scalarNode('column_name')
->defaultValue('version')
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.version_column_name" instead.')
->end()
->scalarNode('column_length')
->defaultValue(14)
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.version_column_length" instead.')
->end()
->scalarNode('executed_at_column_name')
->defaultValue('executed_at')
->setDeprecated('The "%node%" option is deprecated. Use "storage.table_storage.executed_at_column_name" instead.')
->end()
->scalarNode('all_or_nothing')->defaultValue(false)->end()
->scalarNode('name')->defaultValue('Application Migrations')->end()
->scalarNode('custom_template')->defaultValue(null)->end()
->scalarNode('organize_migrations')->defaultValue(false)
->info('Organize migrations mode. Possible values are: "BY_YEAR", "BY_YEAR_AND_MONTH", false')
Expand Down
29 changes: 28 additions & 1 deletion DependencyInjection/DoctrineMigrationsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use function count;
use function current;
use function key;

/**
* DoctrineMigrationsExtension.
Expand All @@ -17,14 +20,38 @@ class DoctrineMigrationsExtension extends Extension
/**
* Responds to the migrations configuration parameter.
*
* @param string[][] $configs
* @param string[][]|array<string, array<string, array<string, string>|string>>> $configs
*/
public function load(array $configs, ContainerBuilder $container) : void
{
$configuration = new Configuration();

$config = $this->processConfiguration($configuration, $configs);

// 3.x forward compatibility layer
if (isset($config['migrations_paths']) && count($config['migrations_paths'])>0) {
$config['namespace'] = key($config['migrations_paths']);
$config['dir_name'] = current($config['migrations_paths']);
unset($config['migrations_paths']);
}

if (isset($config['storage']['table_storage'])) {
$storageConfig = $config['storage']['table_storage'];
if (isset($storageConfig['table_name'])) {
$config['table_name'] = $storageConfig['table_name'];
}
if (isset($storageConfig['version_column_name'])) {
$config['column_name'] = $storageConfig['version_column_name'];
}
if (isset($storageConfig['version_column_length'])) {
$config['column_length'] = $storageConfig['version_column_length'];
}
if (isset($storageConfig['executed_at_column_name'])) {
$config['executed_at_column_name'] = $storageConfig['executed_at_column_name'];
}
unset($config['storage']);
}

foreach ($config as $key => $value) {
$container->setParameter($this->getAlias() . '.' . $key, $value);
}
Expand Down
27 changes: 25 additions & 2 deletions Resources/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,36 @@ application:
# config/packages/doctrine_migrations.yaml
doctrine_migrations:
name: 'Application Migrations'
# Namespace/path to search for migrations
migrations_paths:
'DoctrineMigrations': '%kernel.project_dir%/src/Migrations'
# Deprecated since v2.2, use "migrations_paths" instead (array value)
dir_name: '%kernel.project_dir%/src/Migrations'
# Deprecated since v2.2, use "migrations_paths" instead (array key)
namespace: DoctrineMigrations
storage:
# Default (SQL table) metadata storage configuration
table_storage:
table_name: 'migration_versions'
version_column_name: 'version'
version_column_length: 1024
executed_at_column_name: 'executed_at'
execution_time_column_name: 'execution_time'
# Deprecated since v2.2, use "storage.table_storage.table_name" instead
table_name: 'migration_versions'
# Deprecated since v2.2, use "storage.table_storage.version_column_name" instead
column_name: 'version'
# Deprecated since v2.2, use "storage.table_storage.version_column_length" instead (minimum value has to be at least 1024)
column_length: 14
# Deprecated since v2.2, use "storage.table_storage.execution_time_column_name" instead
executed_at_column_name: 'executed_at'
name: 'Application Migrations'
# available in version >= 1.2. Possible values: "BY_YEAR", "BY_YEAR_AND_MONTH", false
organize_migrations: false
# available in version >= 1.3. Path to your custom migrations template
Expand Down Expand Up @@ -192,7 +215,7 @@ fill in the ``up()`` and ``down()`` methods), see the official Doctrine Migratio

.. tip::

If you need to use another database connection to execute migrations you may use option ``--db="doctrine-connection-name"``
If you need to use another database connection to execute migrations you may use option ``--db="doctrine-connection-name"``
where ``doctrine-connection-name`` is valid Doctrine connection defined in doctrine.yaml

Running Migrations during Deployment
Expand Down
30 changes: 30 additions & 0 deletions Tests/DependencyInjection/DoctrineMigrationsExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@ public function testOrganizeMigrations() : void
);
}

public function testForwardCompatibilityLayer() : void
{
$container = $this->getContainer();
$extension = new DoctrineMigrationsExtension();

$config = [
'storage' => [
'table_storage' => [
'table_name' => 'doctrine_migration_versions_test',
'version_column_name' => 'doctrine_migration_column_test',
'version_column_length' => '2000',
'executed_at_column_name' => 'doctrine_migration_executed_at_column_test',
],
],

'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],

];

$extension->load(['doctrine_migrations' => $config], $container);

$this->assertEquals('a', $container->getParameter('doctrine_migrations.dir_name'));
$this->assertEquals('DoctrineMigrationsTest', $container->getParameter('doctrine_migrations.namespace'));
$this->assertEquals('doctrine_migration_versions_test', $container->getParameter('doctrine_migrations.table_name'));
$this->assertEquals('doctrine_migration_column_test', $container->getParameter('doctrine_migrations.column_name'));
$this->assertEquals(2000, $container->getParameter('doctrine_migrations.column_length'));
$this->assertEquals(2000, $container->getParameter('doctrine_migrations.column_length'));
$this->assertEquals('doctrine_migration_executed_at_column_test', $container->getParameter('doctrine_migrations.executed_at_column_name'));
}

private function getContainer() : ContainerBuilder
{
return new ContainerBuilder(new ParameterBag([
Expand Down

0 comments on commit ddcc1c5

Please sign in to comment.