diff modules/contrib/migrate_tools/migrate_tools.drush.inc @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/migrate_tools/migrate_tools.drush.inc	Wed Nov 29 16:09:58 2017 +0000
@@ -0,0 +1,452 @@
+<?php
+
+/**
+ * @file
+ * Command-line tools to aid performing and developing migrations.
+ */
+
+use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Database\ConnectionNotDefinedException;
+use Drupal\migrate\Exception\RequirementsException;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate_tools\MigrateExecutable;
+use Drupal\migrate_tools\DrushLogMigrateMessage;
+use Drupal\Core\Datetime\DateFormatter;
+
+/**
+ * Implements hook_drush_command().
+ */
+function migrate_tools_drush_command() {
+  $items['migrate-status'] = [
+    'description' => 'List all migrations with current status.',
+    'options' => [
+      'group' => 'Name of the migration group to list',
+      'names-only' => 'Only return names, not all the details (faster)',
+    ],
+    'arguments' => [
+      'migration' => 'Restrict to a comma-separated list of migrations. Optional',
+    ],
+    'examples' => [
+      'migrate-status' => 'Retrieve status for all migrations',
+      'migrate-status --group=beer' => 'Retrieve status for all migrations in a given group',
+      'migrate-status BeerTerm,BeerNode' => 'Retrieve status for specific migrations',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['ms'],
+  ];
+
+  $items['migrate-import'] = [
+    'description' => 'Perform one or more migration processes.',
+    'options' => [
+      'all' => 'Process all migrations.',
+      'group' => 'Name of the migration group to import',
+      'limit' => 'Limit on the number of items to process in each migration',
+      'feedback' => 'Frequency of progress messages, in items processed',
+      'idlist' => 'Comma-separated list of IDs to import',
+      'update' => ' In addition to processing unprocessed items from the source, update previously-imported items with the current data',
+      'force' => 'Force an operation to run, even if all dependencies are not satisfied',
+      'execute-dependencies' => 'Execute all dependent migrations first.',
+    ],
+    'arguments' => [
+      'migration' => 'Name of migration(s) to import. Delimit multiple using commas.',
+    ],
+    'examples' => [
+      'migrate-import --all' => 'Perform all migrations',
+      'migrate-import --group=beer' => 'Import all migrations in the beer group',
+      'migrate-import BeerTerm,BeerNode' => 'Import new terms and nodes',
+      'migrate-import BeerUser --limit=2' => 'Import no more than 2 users',
+      'migrate-import BeerUser --idlist=5' => 'Import the user record with source ID 5',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['mi'],
+  ];
+
+  $items['migrate-rollback'] = array(
+    'description' => 'Rollback one or more migrations.',
+    'options' => array(
+      'all' => 'Process all migrations.',
+      'group' => 'Name of the migration group to rollback',
+      'feedback' => 'Frequency of progress messages, in items processed',
+    ),
+    'arguments' => array(
+      'migration' => 'Name of migration(s) to rollback. Delimit multiple using commas.',
+    ),
+    'examples' => array(
+      'migrate-rollback --all' => 'Perform all migrations',
+      'migrate-rollback --group=beer' => 'Rollback all migrations in the beer group',
+      'migrate-rollback BeerTerm,BeerNode' => 'Rollback imported terms and nodes',
+    ),
+    'drupal dependencies' => array('migrate_tools'),
+    'aliases' => array('mr'),
+  );
+
+  $items['migrate-stop'] = [
+    'description' => 'Stop an active migration operation.',
+    'arguments' => [
+      'migration' => 'Name of migration to stop',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['mst'],
+  ];
+
+  $items['migrate-reset-status'] = [
+    'description' => 'Reset a active migration\'s status to idle.',
+    'arguments' => [
+      'migration' => 'Name of migration to reset',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['mrs'],
+  ];
+
+  $items['migrate-messages'] = [
+    'description' => 'View any messages associated with a migration.',
+    'arguments' => [
+      'migration' => 'Name of the migration',
+    ],
+    'options' => [
+      'csv' => 'Export messages as a CSV'
+    ],
+    'examples' => [
+      'migrate-messages MyNode' => 'Show all messages for the MyNode migration',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['mmsg'],
+  ];
+
+  $items['migrate-fields-source'] = [
+    'description' => 'List the fields available for mapping in a source.',
+    'arguments' => [
+      'migration' => 'Name of the migration',
+    ],
+    'examples' => [
+      'migrate-fields-source my_node' => 'List fields for the source in the my_node migration',
+    ],
+    'drupal dependencies' => ['migrate_tools'],
+    'aliases' => ['mfs'],
+  ];
+
+  return $items;
+}
+
+/**
+ * @param string $migration_names
+ */
+function drush_migrate_tools_migrate_status($migration_names = '') {
+  $group_name = drush_get_option('group');
+  $names_only = drush_get_option('names-only');
+
+  $migrations = drush_migrate_tools_migration_list($group_name, $migration_names);
+
+  $table = [];
+  // Take it one group at a time, listing the migrations within each group.
+  foreach ($migrations as $group_id => $migration_list) {
+    if ($names_only) {
+      $table[] = [
+        dt('Group: @name', array('@name' => $group_id))
+      ];
+    }
+    else {
+      $table[] = [
+        dt('Group: @name', array('@name' => $group_id)),
+        dt('Status'),
+        dt('Total'),
+        dt('Imported'),
+        dt('Unprocessed'),
+        dt('Last imported'),
+      ];
+    }
+    foreach ($migration_list as $migration_id => $migration) {
+      try {
+        $map = $migration->getIdMap();
+        $imported = $map->importedCount();
+        $source_plugin = $migration->getSourcePlugin();
+      }
+      catch (Exception $e) {
+        drush_log(dt('Failure retrieving information on @migration: @message',
+          ['@migration' => $migration_id, '@message' => $e->getMessage()]));
+        continue;
+      }
+      try {
+        $source_rows = $source_plugin->count();
+        // -1 indicates uncountable sources.
+        if ($source_rows == -1) {
+          $source_rows = dt('N/A');
+          $unprocessed = dt('N/A');
+        }
+        else {
+          $unprocessed = $source_rows - $map->processedCount();
+        }
+      }
+      catch (Exception $e) {
+        drush_print($e->getMessage());
+        drush_log(dt('Could not retrieve source count from @migration: @message',
+          ['@migration' => $migration_id, '@message' => $e->getMessage()]));
+        $source_rows = dt('N/A');
+        $unprocessed = dt('N/A');
+      }
+
+      if ($names_only) {
+        $table[] = [$migration_id];
+      }
+      else {
+        $status = $migration->getStatusLabel();
+        $migrate_last_imported_store = \Drupal::keyValue('migrate_last_imported');
+        $last_imported =  $migrate_last_imported_store->get($migration->id(), FALSE);
+        if ($last_imported) {
+          /** @var DateFormatter $date_formatter */
+          $date_formatter = \Drupal::service('date.formatter');
+          $last_imported = $date_formatter->format($last_imported / 1000,
+            'custom', 'Y-m-d H:i:s');
+        }
+        else {
+          $last_imported = '';
+        }
+        $table[] = [$migration_id, $status, $source_rows, $imported, $unprocessed, $last_imported];
+      }
+    }
+  }
+  drush_print_table($table);
+}
+
+/**
+ * @param string $migration_names
+ */
+function drush_migrate_tools_migrate_import($migration_names = '') {
+  $group_name = drush_get_option('group');
+  $all = drush_get_option('all');
+  $options = [];
+  if (!$all && !$group_name && !$migration_names) {
+    drush_set_error('MIGRATE_ERROR', dt('You must specify --all, --group, or one or more migration names separated by commas'));
+    return;
+  }
+
+  foreach (['limit', 'feedback', 'idlist', 'update', 'force'] as $option) {
+    if (drush_get_option($option)) {
+      $options[$option] = drush_get_option($option);
+    }
+  }
+
+  $migrations = drush_migrate_tools_migration_list($group_name, $migration_names);
+
+  // Take it one group at a time, importing the migrations within each group.
+  foreach ($migrations as $group_id => $migration_list) {
+    array_walk($migration_list, '_drush_migrate_tools_execute_migration', $options);
+  }
+}
+
+/**
+ * Executes a single migration. If the --execute-dependencies option was given,
+ * the migration's dependencies will also be executed first.
+ *
+ * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+ *  The migration to execute.
+ * @param string $migration_id
+ *  The migration ID (not used, just an artifact of array_walk()).
+ * @param array $options
+ *  Additional options for the migration.
+ */
+function _drush_migrate_tools_execute_migration(MigrationInterface $migration, $migration_id,  array $options = []) {
+  $log = new DrushLogMigrateMessage();
+
+  if (drush_get_option('execute-dependencies')) {
+    if ($required_IDS = $migration->get('requirements')) {
+      $manager = \Drupal::service('plugin.manager.config_entity_migration');
+      $required_migrations = $manager->createInstances($required_IDS);
+      $dependency_options = array_merge($options, ['is_dependency' => TRUE]);
+      array_walk($required_migrations, __FUNCTION__, $dependency_options);
+    }
+  }
+  if ($options['force']) {
+    $migration->set('requirements', []);
+  }
+  if ($options['update']) {
+    $migration->getIdMap()->prepareUpdate();
+  }
+  $executable = new MigrateExecutable($migration, $log, $options);
+  // drush_op() provides --simulate support
+  drush_op(array($executable, 'import'));
+}
+
+/**
+ * @param string $migration_names
+ */
+function drush_migrate_tools_migrate_rollback($migration_names = '') {
+  $group_name = drush_get_option('group');
+  $all = drush_get_option('all');
+  $options = [];
+  if (!$all && !$group_name && !$migration_names) {
+    drush_set_error('MIGRATE_ERROR', dt('You must specify --all, --group, or one or more migration names separated by commas'));
+    return;
+  }
+
+  if (drush_get_option('feedback')) {
+    $options['feedback'] = drush_get_option('feedback');
+  }
+
+  $log = new DrushLogMigrateMessage();
+
+  $migrations = drush_migrate_tools_migration_list($group_name, $migration_names);
+
+  // Take it one group at a time, rolling back the migrations within each group.
+  foreach ($migrations as $group_id => $migration_list) {
+    // Roll back in reverse order.
+    $migration_list = array_reverse($migration_list);
+    foreach ($migration_list as $migration_id => $migration) {
+      $executable = new MigrateExecutable($migration, $log, $options);
+      // drush_op() provides --simulate support.
+      drush_op(array($executable, 'rollback'));
+    }
+  }
+}
+
+/**
+ * @param string $migration_id
+ */
+function drush_migrate_tools_migrate_stop($migration_id = '') {
+  /** @var MigrationInterface $migration */
+  $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
+  if ($migration) {
+    $status = $migration->getStatus();
+    switch ($status) {
+      case MigrationInterface::STATUS_IDLE:
+        drush_log(dt('Migration @id is idle', ['@id' => $migration_id]), 'warning');
+        break;
+      case MigrationInterface::STATUS_DISABLED:
+        drush_log(dt('Migration @id is disabled', ['@id' => $migration_id]), 'warning');
+        break;
+      case MigrationInterface::STATUS_STOPPING:
+        drush_log(dt('Migration @id is already stopping', ['@id' => $migration_id]), 'warning');
+        break;
+      default:
+        $migration->interruptMigration(MigrationInterface::RESULT_STOPPED);
+        drush_log(dt('Migration @id requested to stop', ['@id' => $migration_id]), 'success');
+        break;
+    }
+  }
+  else {
+    drush_log(dt('Migration @id does not exist', ['@id' => $migration_id]), 'error');
+  }
+}
+
+/**
+ * @param string $migration_id
+ */
+function drush_migrate_tools_migrate_reset_status($migration_id = '') {
+  /** @var MigrationInterface $migration */
+  $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
+  if ($migration) {
+    $status = $migration->getStatus();
+    if ($status == MigrationInterface::STATUS_IDLE) {
+      drush_log(dt('Migration @id is already Idle', ['@id' => $migration_id]), 'warning');
+    }
+    else {
+      $migration->setStatus(MigrationInterface::STATUS_IDLE);
+      drush_log(dt('Migration @id reset to Idle', ['@id' => $migration_id]), 'status');
+    }
+  }
+  else {
+    drush_log(dt('Migration @id does not exist', ['@id' => $migration_id]), 'error');
+  }
+}
+
+/**
+ * @param string $migration_id
+ */
+function drush_migrate_tools_migrate_messages($migration_id) {
+  /** @var MigrationInterface $migration */
+  $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
+  if ($migration) {
+    $map = $migration->getIdMap();
+    $first = TRUE;
+    $table = [];
+    foreach ($map->getMessageIterator() as $row) {
+      unset($row->msgid);
+      if ($first) {
+        // @todo: Ideally, replace sourceid* with source key names. Or, should
+        // getMessageIterator() do that?
+        foreach ($row as $column => $value) {
+          $table[0][] = $column;
+        }
+        $first = FALSE;
+      }
+      $table[] = (array)$row;
+    }
+    if (empty($table)) {
+      drush_log(dt('No messages for this migration'), 'status');
+    }
+    else {
+      if (drush_get_option('csv')) {
+        foreach ($table as $row) {
+          fputcsv(STDOUT, $row);
+        }
+      }
+      else {
+        $widths = [];
+        foreach ($table[0] as $header) {
+          $widths[] = strlen($header) + 1;
+        }
+        drush_print_table($table, TRUE, $widths);
+      }
+    }
+  }
+  else {
+    drush_log(dt('Migration @id does not exist', ['@id' => $migration_id]), 'error');
+  }
+}
+
+/**
+ * @param string $migration_id
+ */
+function drush_migrate_tools_migrate_fields_source($migration_id) {
+  /** @var MigrationInterface $migration */
+  $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
+  if ($migration) {
+    $source = $migration->getSourcePlugin();
+    $table = [];
+    foreach ($source->fields() as $machine_name => $description) {
+      $table[] = [strip_tags($description), $machine_name];
+    }
+    drush_print_table($table);
+  }
+  else {
+    drush_log(dt('Migration @id does not exist', ['@id' => $migration_id]), 'error');
+  }
+}
+
+/**
+ * Retrieve a list of active migrations.
+ *
+ * @param string $group_id
+ *  Group machine name - if present, return only migrations in this group.
+ * @param string $migration_ids
+ *  Comma-separated list of migrations - if present, return only these migrations.
+ *
+ * @return MigrationInterface[][]
+ *   An array keyed by migration group, each value containing an array of migrations.
+ */
+function drush_migrate_tools_migration_list($group_id = '', $migration_ids = '') {
+  if (!empty($migration_ids)) {
+    $migration_ids = explode(',', Unicode::strtolower($migration_ids));
+  }
+  else {
+    $migration_ids = [];
+  }
+
+  $manager = \Drupal::service('plugin.manager.config_entity_migration');
+  $plugins = $manager->createInstances([]);
+  $migrations = [];
+  foreach ($plugins as $id => $migration) {
+    $configured_group_id = $migration->get('migration_group');
+    if (empty($configured_group_id)) {
+      $configured_group_id = 'default';
+    }
+    if (empty($group_id) || $group_id == $configured_group_id) {
+      if (empty($migration_ids) || in_array(Unicode::strtolower($id), $migration_ids)) {
+        $migrations[$configured_group_id][$id] = $migration;
+      }
+    }
+  }
+  return $migrations;
+}