Skip to content

Add --dry-run option to doctrine:fixtures:load command #511

Open
@Maxcastel

Description

@Maxcastel

Feature Request

What

A --dry-run option to the doctrine:fixtures:load command to not actually load the fixtures.

Why

There is no --dry-run option that would allow displaying the fixtures without actually loading them.

I have lots of fixtures with groups. For example, if I want to load all fixtures which have the group1 group, but before actually loading them, I want to check which fixtures will be loaded to avoid making a mistake, like loading an unwanted fixture, I have to open each fixture file and check if it contains the group1 group or search through the entire project.

--group=group1 displays all fixtures which have the group1 group, but they are also actually loaded.

--group=group1 --dry-run would display all fixtures which have the group1 group without actually loading them.

This option exists for the doctrine:migrations:migrate and doctrine:migrations:execute commands but not for the doctrine:fixtures:load command.

This option would be useful to me, and I think it would be helpful to many others, like @alexdawn.

How

Either by performing a transaction and then rolling it back :

if ($input->getOption('dry-run')) {
    $ui->text('  <comment>(dry-run)</comment>');
    $em->getConnection()->beginTransaction();
}

$executor->execute($fixtures, $input->getOption('append'));

if ($input->getOption('dry-run')) {
    $em->getConnection()->rollBack();
}

Or by adding a boolean parameter $dryRun to doctrine\data-fixtures\src\Executor\ORMExecutor::execute() and passing it to purge() and load() :

doctrine\doctrine-fixtures-bundle\Command\LoadDataFixturesDoctrineCommand.php :

$executor->execute($fixtures, $input->getOption('append'), 
+ $input->getOption('dry-run')
);

doctrine\data-fixtures\src\Executor\ORMExecutor.php :

     /** @inheritDoc */
-    public function execute(array $fixtures, bool $append = false): void
+    public function execute(array $fixtures, bool $append = false, bool $dryRun = false): void
     {
         $executor = $this;
-        $this->em->wrapInTransaction(static function (EntityManagerInterface $em) use ($executor, $fixtures, $append): void {
+        $this->em->wrapInTransaction(static function (EntityManagerInterface $em) use ($executor, $fixtures, $append, $dryRun): void {
             if ($append === false) {
-                $executor->purge();
+                $executor->purge($dryRun);
             }
 
             foreach ($fixtures as $fixture) {
-                $executor->load($em, $fixture);
+                $executor->load($em, $fixture, $dryRun);
             }
         });
     }

doctrine\data-fixtures\src\Executor\AbstractExecutor.php :

     /**
      * Purges the database before loading.
+     * 
+     * @param bool $dryRun Whether to simulate the purge operation without actually modifying the database.
      *
      * @throws Exception if the purger is not defined.
      */
-    public function purge(): void
+    public function purge(bool $dryRun = false): void
     {
-        if ($this->purger === null) {
-            throw new Exception(
-                PurgerInterface::class .
-                 ' instance is required if you want to purge the database before loading your data fixtures.',
-            );
+        if ($dryRun === false) {
+            if ($this->purger === null) {
+                throw new Exception(
+                    PurgerInterface::class .
+                    ' instance is required if you want to purge the database before loading your data fixtures.',
+                );
+            }
+
+            $this->purger->purge();
         }
 
         $this->logger?->debug('purging database');
-
-        $this->purger->purge();
     }
     /**
      * Load a fixture with the given persistence manager.
+     * 
+     * @param bool $dryRun Whether to simulate the loading operation without actually persisting the data.
      */
-    public function load(ObjectManager $manager, FixtureInterface $fixture): void
+    public function load(ObjectManager $manager, FixtureInterface $fixture, bool $dryRun = false): void
     {
         if ($this->logger) {
             $prefix = '';
             if ($fixture instanceof OrderedFixtureInterface) {
                  $prefix = sprintf('[%d] ', $fixture->getOrder());
              }

             $this->logger->debug('loading ' . $prefix . get_debug_type($fixture));
         }
 
-        // additionally pass the instance of reference repository to shared fixtures
-        if ($fixture instanceof SharedFixtureInterface) {
-            $fixture->setReferenceRepository($this->referenceRepository);
-        }
+        if ($dryRun === false) {
+            // additionally pass the instance of reference repository to shared fixtures
+            if ($fixture instanceof SharedFixtureInterface) {
+                $fixture->setReferenceRepository($this->referenceRepository);
+            }
 
-        $fixture->load($manager);
-        $manager->clear();
+            $fixture->load($manager);
+            $manager->clear();
+        }
     }
     /**
      * Executes the fixtures.
      *
      * @param FixtureInterface[] $fixtures Array of fixtures to execute.
      * @param bool               $append   Whether to append the data fixtures or purge the database before loading.
+     * @param bool               $dryRun   Whether to simulate the execution of the fixtures without making actual changes to the database.
      */
-    abstract public function execute(array $fixtures, bool $append = false): void;
+    abstract public function execute(array $fixtures, bool $append = false, bool $dryRun = false): void;
 }

But this would also require modifying the doctrine/data-fixtures project, or another solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions