Skip to content

Commit

Permalink
[feat] use config to replace environment variables
Browse files Browse the repository at this point in the history
WIP
  • Loading branch information
nikophil committed Nov 7, 2022
1 parent cada0cf commit 29b6934
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 26 deletions.
32 changes: 32 additions & 0 deletions src/Bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,38 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
->end()
->arrayNode('database_resetter')
->canBeDisabled()
->addDefaultsIfNotSet()
->info('Configure database reset mechanism.')
->children()
->arrayNode('orm')
->children()
->arrayNode('connections')
->scalarPrototype()->end()
->info('Connections to reset. If empty, the default connection is used.')
->end()
->arrayNode('object_managers')
->scalarPrototype()->end()
->info('Object managers to reset. If empty, the default manager is used.')
->end()
->enumNode('reset_mode')
->info('Whether to use doctrine:schema:update or migrations when resetting schema.')
->values(['schema', 'migrate'])
->defaultValue('schema')
->end()
->end()
->end()
->arrayNode('odm')
->children()
->arrayNode('object_managers')
->scalarPrototype()->end()
->info('Object managers to reset. If empty, the default manager is used.')
->end()
->end()
->end()
->end()
->end()
->end()
;

Expand Down
37 changes: 37 additions & 0 deletions src/Bundle/DependencyInjection/ZenstruckFoundryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Zenstruck\Foundry\Bundle\DependencyInjection;

use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle;
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -34,6 +36,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container

$this->configureFaker($mergedConfig['faker'], $container);
$this->configureDefaultInstantiator($mergedConfig['instantiator'], $container);
$this->configureDatabaseResetter($mergedConfig['database_resetter'], $container);

if (true === $mergedConfig['auto_refresh_proxies']) {
$container->getDefinition(Configuration::class)->addMethodCall('enableDefaultProxyAutoRefresh');
Expand Down Expand Up @@ -88,4 +91,38 @@ private function configureDefaultInstantiator(array $config, ContainerBuilder $c
$definition->addMethodCall('alwaysForceProperties');
}
}

private function configureDatabaseResetter(array $config, ContainerBuilder $container): void
{
$configurationDefinition = $container->getDefinition(Configuration::class);

if (false === $config['enabled']) {
$configurationDefinition->addMethodCall('disableDatabaseReset');
}

if (isset($config['orm']) && !self::isBundleLoaded($container, DoctrineBundle::class)) {
throw new \InvalidArgumentException('doctrine/doctrine-bundle should be enabled to use config under "database_resetter.orm".');
}

if (isset($config['odm']) && !self::isBundleLoaded($container, DoctrineMongoDBBundle::class)) {
throw new \InvalidArgumentException('doctrine/mongodb-odm-bundle should be enabled to use config under "database_resetter.odm".');
}

$configurationDefinition->setArgument('$ormConnectionsToReset', $config['orm']['connections'] ?? []);
$configurationDefinition->setArgument('$ormObjectManagersToReset', $config['orm']['object_managers'] ?? []);
$configurationDefinition->setArgument('$ormResetMode', $config['orm']['reset_mode'] ?? 'schema');
$configurationDefinition->setArgument('$odmObjectManagersToReset', $config['odm']['object_managers'] ?? []);
}

/**
* @psalm-suppress UndefinedDocblockClass
*/
private static function isBundleLoaded(ContainerBuilder $container, string $bundleName): bool
{
return \in_array(
$bundleName,
\is_array($bundles = $container->getParameter('kernel.bundles')) ? $bundles : [],
true
);
}
}
4 changes: 4 additions & 0 deletions src/Bundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
</service>

<service id="Zenstruck\Foundry\Configuration" public="true">
<argument></argument> <!-- $ormConnectionsToReset -->
<argument></argument> <!-- $ormObjectManagersToReset -->
<argument></argument> <!-- $ormResetMode -->
<argument></argument> <!-- $odmObjectManagersToReset -->
<call method="setManagerRegistry">
<argument type="service" id="Zenstruck\Foundry\ChainManagerRegistry" />
</call>
Expand Down
54 changes: 53 additions & 1 deletion src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,32 @@ final class Configuration
/** @var bool */
private $flushEnabled = true;

public function __construct()
/** @var bool */
private $databaseResetEnabled = true;

/** @var list<string> */
private $ormConnectionsToReset;

/** @var list<string> */
private $ormObjectManagersToReset;

/** @var string */
private $ormResetMode;

/** @var list<string> */
private $odmObjectManagersToReset;

public function __construct(array $ormConnectionsToReset, array $ormObjectManagersToReset, string $ormResetMode, array $odmObjectManagersToReset)
{
$this->stories = new StoryManager([]);
$this->factories = new ModelFactoryManager([]);
$this->faker = Faker\Factory::create();
$this->instantiator = new Instantiator();

$this->ormConnectionsToReset = $ormConnectionsToReset;
$this->ormObjectManagersToReset = $ormObjectManagersToReset;
$this->ormResetMode = $ormResetMode;
$this->odmObjectManagersToReset = $odmObjectManagersToReset;
}

public function stories(): StoryManager
Expand Down Expand Up @@ -132,6 +152,18 @@ public function isFlushingEnabled(): bool
return $this->flushEnabled;
}

public function disableDatabaseReset(): self
{
$this->databaseResetEnabled = false;

return $this;
}

public function isDatabaseResetEnabled(): bool
{
return $this->databaseResetEnabled;
}

public function delayFlush(callable $callback): void
{
$this->flushEnabled = false;
Expand Down Expand Up @@ -187,6 +219,26 @@ public function hasManagerRegistry(): bool
return null !== $this->managerRegistry;
}

public function getOrmConnectionsToReset(): array
{
return $this->ormConnectionsToReset;
}

public function getOrmObjectManagersToReset(): array
{
return $this->ormObjectManagersToReset;
}

public function getOrmResetMode(): string
{
return $this->ormResetMode;
}

public function getOdmObjectManagersToReset(): array
{
return $this->odmObjectManagersToReset;
}

private function managerRegistry(): ManagerRegistry
{
if (!$this->hasManagerRegistry()) {
Expand Down
11 changes: 11 additions & 0 deletions src/Test/AbstractSchemaResetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,15 @@ protected function runCommand(Application $application, string $command, array $
throw new \RuntimeException(\sprintf('Error running "%s": %s', $command, $output->fetch()));
}
}

/**
* @param list<string> $availableObjectsToReset
* @param list<string> $candidateObjectsToReset
*/
protected static function validateObjectsToReset(string $objectsType, array $availableObjectsToReset, array $candidateObjectsToReset): void
{
if ($invalidObjectsToReset = \array_diff($candidateObjectsToReset, $availableObjectsToReset)) {
throw new \InvalidArgumentException(\sprintf('Cannot reset %s schema: invalid value "%s" given as %s. Available values are "%s"', ORMDatabaseResetter::class === static::class ? 'ORM' : 'ODM', \json_encode($invalidObjectsToReset), $objectsType, \json_encode($availableObjectsToReset)));
}
}
}
40 changes: 31 additions & 9 deletions src/Test/DatabaseResetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\HttpKernel\KernelInterface;
use Zenstruck\Foundry\Configuration;
use Zenstruck\Foundry\Factory;

/**
Expand All @@ -19,10 +20,6 @@ final class DatabaseResetter

public static function hasBeenReset(): bool
{
if (isset($_SERVER['FOUNDRY_DISABLE_DATABASE_RESET'])) {
return true;
}

return self::$hasBeenReset;
}

Expand All @@ -37,8 +34,7 @@ public static function resetDatabase(KernelInterface $kernel): void
return;
}

$application = self::createApplication($kernel);
$databaseResetter = new ORMDatabaseResetter($application, $kernel->getContainer()->get('doctrine'));
$databaseResetter = self::createORMDatabaseResetter(self::createApplication($kernel), $kernel);

$databaseResetter->resetDatabase();

Expand All @@ -60,18 +56,18 @@ public static function resetSchema(KernelInterface $kernel): void
self::bootFoundry($kernel);
}

/** @retrun array<SchemaResetterInterface> */
/** @return array<AbstractSchemaResetter> */
private static function schemaResetters(KernelInterface $kernel): array
{
$application = self::createApplication($kernel);
$databaseResetters = [];

if ($kernel->getContainer()->has('doctrine')) {
$databaseResetters[] = new ORMDatabaseResetter($application, $kernel->getContainer()->get('doctrine'));
$databaseResetters[] = self::createORMDatabaseResetter($application, $kernel);
}

if ($kernel->getContainer()->has('doctrine_mongodb')) {
$databaseResetters[] = new ODMSchemaResetter($application, $kernel->getContainer()->get('doctrine_mongodb'));
$databaseResetters[] = self::createODMSchemaResetter($application, $kernel);
}

return $databaseResetters;
Expand All @@ -93,4 +89,30 @@ private static function createApplication(KernelInterface $kernel): Application

return $application;
}

private static function createORMDatabaseResetter(Application $application, KernelInterface $kernel): ORMDatabaseResetter
{
$container = $kernel->getContainer();
$configuration = $container->get(Configuration::class);

return new ORMDatabaseResetter(
$application,
$container->get('doctrine'),
$configuration->getOrmConnectionsToReset(),
$configuration->getOrmObjectManagersToReset(),
$configuration->getOrmResetMode()
);
}

private static function createODMSchemaResetter(Application $application, KernelInterface $kernel): ODMSchemaResetter
{
$container = $kernel->getContainer();
$configuration = $container->get(Configuration::class);

return new ODMSchemaResetter(
$application,
$container->get('doctrine_mongodb'),
$configuration->getOdmObjectManagersToReset()
);
}
}
9 changes: 7 additions & 2 deletions src/Test/ODMSchemaResetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ final class ODMSchemaResetter extends AbstractSchemaResetter
private $application;
/** @var ManagerRegistry */
private $registry;
/** @var list<string> */
private $objectManagersToReset;

public function __construct(Application $application, ManagerRegistry $registry)
public function __construct(Application $application, ManagerRegistry $registry, array $objectManagersToReset)
{
$this->application = $application;
$this->registry = $registry;

self::validateObjectsToReset('object manager', \array_keys($registry->getManagerNames()), $objectManagersToReset);
$this->objectManagersToReset = $objectManagersToReset;
}

public function resetSchema(): void
Expand Down Expand Up @@ -48,6 +53,6 @@ public function resetSchema(): void
/** @return list<string> */
private function objectManagersToReset(): array
{
return [$this->registry->getDefaultManagerName()];
return $this->objectManagersToReset ?: [$this->registry->getDefaultManagerName()];
}
}
44 changes: 36 additions & 8 deletions src/Test/ORMDatabaseResetter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,29 @@ final class ORMDatabaseResetter extends AbstractSchemaResetter
private $application;
/** @var ManagerRegistry */
private $registry;

public function __construct(Application $application, ManagerRegistry $registry)
/** @var list<string> */
private $connectionsToReset;
/** @var list<string> */
private $objectManagersToReset;
/** @var string */
private $resetMode;

/**
* @param list<string> $connectionsToReset
* @param list<string> $objectManagersToReset
*/
public function __construct(Application $application, ManagerRegistry $registry, array $connectionsToReset, array $objectManagersToReset, string $resetMode)
{
$this->application = $application;
$this->registry = $registry;

self::validateObjectsToReset('connection', \array_keys($registry->getConnectionNames()), $connectionsToReset);
$this->connectionsToReset = $connectionsToReset;

self::validateObjectsToReset('object manager', \array_keys($registry->getManagerNames()), $objectManagersToReset);
$this->objectManagersToReset = $objectManagersToReset;

$this->resetMode = $resetMode;
}

public function resetDatabase(): void
Expand All @@ -40,7 +58,7 @@ public function resetSchema(): void

private function createSchema(): void
{
if (self::isResetUsingMigrations()) {
if ($this->isResetUsingMigrations()) {
$this->runCommand($this->application, 'doctrine:migrations:migrate', ['-n' => true]);

return;
Expand All @@ -59,7 +77,7 @@ private function createSchema(): void

private function dropSchema(): void
{
if (self::isResetUsingMigrations()) {
if ($this->isResetUsingMigrations()) {
$this->dropAndResetDatabase();

return;
Expand Down Expand Up @@ -103,24 +121,34 @@ private function dropAndResetDatabase(): void
private function connectionsToReset(): array
{
if (isset($_SERVER['FOUNDRY_RESET_CONNECTIONS'])) {
trigger_deprecation('zenstruck\foundry', '1.23', 'Usage of environment variable "FOUNDRY_RESET_CONNECTIONS" is deprecated. Please use bundle configuration: "database_resetter.orm.connections: true".');

return \explode(',', $_SERVER['FOUNDRY_RESET_CONNECTIONS']);
}

return [$this->registry->getDefaultConnectionName()];
return $this->connectionsToReset ?: [$this->registry->getDefaultConnectionName()];
}

/** @return list<string> */
private function objectManagersToReset(): array
{
if (isset($_SERVER['FOUNDRY_RESET_OBJECT_MANAGERS'])) {
trigger_deprecation('zenstruck\foundry', '1.23', 'Usage of environment variable "FOUNDRY_RESET_OBJECT_MANAGERS" is deprecated. Please use bundle configuration: "database_resetter.orm.object_managers: true".');

return \explode(',', $_SERVER['FOUNDRY_RESET_OBJECT_MANAGERS']);
}

return [$this->registry->getDefaultManagerName()];
return $this->objectManagersToReset ?: [$this->registry->getDefaultManagerName()];
}

private static function isResetUsingMigrations(): bool
private function isResetUsingMigrations(): bool
{
return 'migrate' === ($_SERVER['FOUNDRY_RESET_MODE'] ?? 'schema');
if (isset($_SERVER['FOUNDRY_RESET_MODE'])) {
trigger_deprecation('zenstruck\foundry', '1.23', 'Usage of environment variable "FOUNDRY_RESET_MODE" is deprecated. Please use bundle configuration: "database_resetter.reset_mode: true".');

return 'migrate' === $_SERVER['FOUNDRY_RESET_MODE'];
}

return 'migrate' === $this->resetMode;
}
}

0 comments on commit 29b6934

Please sign in to comment.