Skip to content

Commit 25e0b28

Browse files
authored
Merge pull request #318 from goetas/bundle-relative-paths
Allow bundle-relative paths in the migration path resolution
2 parents f9b4c06 + 9a18e93 commit 25e0b28

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

DependencyInjection/DoctrineMigrationsExtension.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@
77
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
88
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
99
use InvalidArgumentException;
10+
use RuntimeException;
1011
use Symfony\Component\Config\FileLocator;
1112
use Symfony\Component\DependencyInjection\ContainerBuilder;
1213
use Symfony\Component\DependencyInjection\Definition;
1314
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1415
use Symfony\Component\DependencyInjection\Reference;
1516
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
17+
use function array_keys;
18+
use function explode;
19+
use function implode;
20+
use function sprintf;
21+
use function strlen;
22+
use function substr;
1623

1724
/**
1825
* DoctrineMigrationsExtension.
@@ -38,6 +45,7 @@ public function load(array $configs, ContainerBuilder $container) : void
3845
$configurationDefinition = $container->getDefinition('doctrine.migrations.configuration');
3946

4047
foreach ($config['migrations_paths'] as $ns => $path) {
48+
$path = $this->checkIfBundleRelativePath($path, $container);
4149
$configurationDefinition->addMethodCall('addMigrationsDirectory', [$ns, $path]);
4250
}
4351

@@ -98,6 +106,34 @@ public function load(array $configs, ContainerBuilder $container) : void
98106
$container->setParameter('doctrine.migrations.preferred_connection', $config['connection']);
99107
}
100108

109+
private function checkIfBundleRelativePath(string $path, ContainerBuilder $container) : string
110+
{
111+
if (isset($path[0]) && $path[0] === '@') {
112+
$pathParts = explode('/', $path);
113+
$bundleName = substr($pathParts[0], 1);
114+
115+
$bundlePath = $this->getBundlePath($bundleName, $container);
116+
return $bundlePath . substr($path, strlen('@' . $bundleName));
117+
}
118+
119+
return $path;
120+
}
121+
122+
private function getBundlePath(string $bundleName, ContainerBuilder $container) : string
123+
{
124+
$bundleMetadata = $container->getParameter('kernel.bundles_metadata');
125+
126+
if (! isset($bundleMetadata[$bundleName])) {
127+
throw new RuntimeException(sprintf(
128+
'The bundle "%s" has not been registered, available bundles: %s',
129+
$bundleName,
130+
implode(', ', array_keys($bundleMetadata))
131+
));
132+
}
133+
134+
return $bundleMetadata[$bundleName]['path'];
135+
}
136+
101137
/**
102138
* Returns the base path for the XSD files.
103139
*

Resources/doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ application:
4747
migrations_paths:
4848
'App\Migrations': 'src/App'
4949
'AnotherApp\Migrations': '/path/to/other/migrations'
50+
'SomeBundle\Migrations': '@SomeBundle/Migrations'
5051
5152
# List of additional migration classes to be loaded, optional
5253
migrations:

Tests/DependencyInjection/DoctrineMigrationsExtensionTest.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\DoctrineMigrationsExtension;
88
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
99
use Doctrine\Bundle\MigrationsBundle\Tests\Fixtures\CustomEntityManager;
10+
use Doctrine\Bundle\MigrationsBundle\Tests\Fixtures\TestBundle\TestBundle;
1011
use Doctrine\DBAL\Connection;
1112
use Doctrine\Migrations\Configuration\Configuration;
1213
use Doctrine\Migrations\DependencyFactory;
@@ -101,6 +102,30 @@ public function testNoConfigsAreNeeded() : void
101102
self::assertSame([], $config->getMigrationDirectories());
102103
}
103104

105+
public function testBundleRelativePathResolution() : void
106+
{
107+
$container = $this->getContainer([
108+
'migrations_paths' => [
109+
'DoctrineMigrationsTest' => '@TestBundle',
110+
'DoctrineMigrationsTestAnother' => '@TestBundle/another-path',
111+
],
112+
]);
113+
114+
$conn = $this->createMock(Connection::class);
115+
$container->set('doctrine.dbal.default_connection', $conn);
116+
$container->compile();
117+
118+
$config = $container->get('doctrine.migrations.configuration');
119+
$bundle = new TestBundle();
120+
121+
self::assertInstanceOf(Configuration::class, $config);
122+
self::assertSame([
123+
'DoctrineMigrationsTest' => $bundle->getPath(),
124+
'DoctrineMigrationsTestAnother' => $bundle->getPath() . '/another-path',
125+
126+
], $config->getMigrationDirectories());
127+
}
128+
104129
private function assertConfigs(?object $config) : void
105130
{
106131
self::assertInstanceOf(Configuration::class, $config);
@@ -288,9 +313,16 @@ private function getContainer(array $config) : ContainerBuilder
288313

289314
private function getContainerBuilder() : ContainerBuilder
290315
{
316+
$bundle = new TestBundle();
291317
return new ContainerBuilder(new ParameterBag([
292318
'kernel.debug' => false,
293-
'kernel.bundles' => [],
319+
'kernel.bundles' => [$bundle->getName() => TestBundle::class],
320+
'kernel.bundles_metadata' => [
321+
$bundle->getName() => [
322+
'path' => $bundle->getPath(),
323+
'namespace' => $bundle->getNamespace(),
324+
],
325+
],
294326
'kernel.cache_dir' => sys_get_temp_dir(),
295327
'kernel.environment' => 'test',
296328
'kernel.project_dir' => __DIR__ . '/../',
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle\Tests\Fixtures\TestBundle;
6+
7+
use Symfony\Component\HttpKernel\Bundle\Bundle;
8+
9+
class TestBundle extends Bundle
10+
{
11+
}

0 commit comments

Comments
 (0)