/**
  * Apply the given migration to the package and commit the result.
  *
  * @param string $packageKey
  * @param array $packageData
  * @param AbstractMigration $migration
  * @return void
  * @throws \RuntimeException
  */
 protected function migratePackage($packageKey, array $packageData, AbstractMigration $migration)
 {
     if (Git::isWorkingCopyClean($packageData['path'])) {
         if (Git::hasMigrationApplied($packageData['path'], $migration->getIdentifier())) {
             echo '  Skipping ' . $packageKey . ', the migration is already applied.' . PHP_EOL;
         } else {
             echo '  Migrating ' . $packageKey . PHP_EOL;
             try {
                 $migration->prepare($this->packagesData[$packageKey]);
                 $migration->up();
                 $migration->execute();
                 echo Git::commitMigration($packageData['path'], $migration->getIdentifier());
             } catch (\Exception $exception) {
                 throw new \RuntimeException('Applying migration "' . $migration->getIdentifier() . '" to "' . $packageKey . '" failed.', 0, $exception);
             }
         }
     } else {
         echo '  Skipping ' . $packageKey . ', the working copy is dirty.' . PHP_EOL;
     }
 }