--- a/src/Commands/MigrateToolsCommands.php	2023-01-06 09:26:52.000000000 +0000
+++ b/src/Commands/MigrateToolsCommands.php	2023-01-06 09:38:42.000000000 +0000
@@ -86,15 +86,7 @@
     'tag' => self::REQ,
   ]): void {
     $manager = $this->migrationPluginManager;
-    $migrations = $this->migrationsList($migration_names, $options);
-
-    // Turn this into a flat array.
-    $migrations_to_process = [];
-    foreach ($migrations as $group => $group_migrations) {
-      foreach ($group_migrations as $migration) {
-        $migrations_to_process[$migration->id()] = $migration;
-      }
-    }
+    $migrations_to_process = $this->migrationsList($migration_names, $options);
 
     // Create a dependency graph. The migrations in the given list may have
     // dependencies not in the list, so we need to add those to the list as we
@@ -221,7 +213,15 @@
   ]): RowsOfFields {
     $names_only = $options['names-only'];
 
-    $migrations = $this->migrationsList($migration_names, $options);
+    $migrations = [];
+    $matched_migrations = $this->migrationsList($migration_names, $options);
+    // Sort the matched migrations by group.
+    if (!empty($matched_migrations)) {
+      foreach ($matched_migrations as $id => $migration) {
+        $configured_group_id = empty($migration->migration_group) ? 'default' : $migration->migration_group;
+        $migrations[$configured_group_id][$id] = $migration;
+      }
+    }
 
     $table = [];
     $errors = [];
@@ -403,16 +403,20 @@
       $this->logger->error(dt('No migrations found.'));
     }
 
-    // Take it one group at a time, importing the migrations within each group.
-    foreach ($migrations as $group_id => $migration_list) {
-      // Don't execute disabled migrations.
-      foreach ($migration_list as $migration_id => $migration) {
-        if ($migration->getStatus() == MigrationInterface::STATUS_DISABLED) {
-          continue;
-        }
-        $this->executeMigration($migration, $migration_id, $options);
+    // Import in dependency order.
+    if (!empty($options['limit'])) {
+      while ($options['limit']) {
+        $id = key($migrations);
+        $options['limit'] -= $this->executeMigration(array_shift($migrations), $id, $options);
       }
     }
+    else {
+      array_walk(
+        $migrations,
+        [$this, 'executeMigration'],
+        $options
+      );
+    }
   }
 
   /**
@@ -478,32 +482,27 @@
       $this->logger()->error(dt('No migrations found.'));
     }
 
-    // Take it one group at a time,
-    // rolling back the migrations within each group.
-    $has_failure = FALSE;
-    foreach ($migrations as $migration_list) {
-      // Roll back in reverse order.
-      $migration_list = array_reverse($migration_list);
-      foreach ($migration_list as $migration_id => $migration) {
-        if ($options['skip-progress-bar']) {
-          $migration->set('skipProgressBar', TRUE);
-        }
-        // Initialize the Synmfony Console progress bar.
-        \Drupal::service('migrate_tools.migration_drush_command_progress')->initializeProgress(
-          $this->output(),
-          $migration
-        );
-        $executable = new MigrateExecutable(
-          $migration,
-          $this->getMigrateMessage(),
-          $options
-        );
-        // \drush_op() provides --simulate support.
-        $result = \drush_op([$executable, 'rollback']);
-        if ($result == MigrationInterface::RESULT_FAILED) {
-          $has_failure = TRUE;
-          $errored_migration_id = $migration_id;
-        }
+    // Roll back in reverse order.
+    $migration_list = array_reverse($migrations);
+    foreach ($migration_list as $migration_id => $migration) {
+      if ($options['skip-progress-bar']) {
+        $migration->set('skipProgressBar', TRUE);
+      }
+      // Initialize the Synmfony Console progress bar.
+      \Drupal::service('migrate_tools.migration_drush_command_progress')->initializeProgress(
+        $this->output(),
+        $migration
+      );
+      $executable = new MigrateExecutable(
+        $migration,
+        $this->getMigrateMessage(),
+        $options
+      );
+      // \drush_op() provides --simulate support.
+      $result = \drush_op([$executable, 'rollback']);
+      if ($result == MigrationInterface::RESULT_FAILED) {
+        $has_failure = TRUE;
+        $errored_migration_id = $migration_id;
       }
     }
 
@@ -871,14 +870,7 @@
       }
     }
 
-    // Sort the matched migrations by group.
-    if (!empty($matched_migrations)) {
-      foreach ($matched_migrations as $id => $migration) {
-        $configured_group_id = empty($migration->migration_group) ? 'default' : $migration->migration_group;
-        $migrations[$configured_group_id][$id] = $migration;
-      }
-    }
-    return $migrations ?? [];
+    return $matched_migrations ?? [];
   }
 
   /**
@@ -896,10 +888,13 @@
    *
    * @default $options []
    *
+   * @return int
+   *   The number of items processed.
+   *
    * @throws \Exception
    *   If some migrations failed during execution.
    */
-  protected function executeMigration(MigrationInterface $migration, $migration_id, array $options = []): void {
+  protected function executeMigration(MigrationInterface $migration, $migration_id, array $options = []): int {
     // Keep track of all migrations run during this command so the same
     // migration is not run multiple times.
     static $executed_migrations = [];
@@ -973,6 +968,7 @@
         throw new \Exception($error_message);
       }
     }
+    return $executable->getProcessedCount();
   }
 
   /**
