diff --git a/composer.json b/composer.json index afcb2e146280082eae871d406f624b45817aefab..d808be07002df7ad05a7d90b7f27f6fc9eacaa21 100644 --- a/composer.json +++ b/composer.json @@ -116,6 +116,7 @@ "drupal/menu_block": "1.4", "drupal/menu_breadcrumb": "^1.7", "drupal/metatag": "^1.7", + "drupal/migrate_devel": "1.x-dev", "drupal/migrate_plus": "4.0", "drupal/migrate_tools": "4.0", "drupal/module_filter": "^3.1", diff --git a/composer.lock b/composer.lock index 3218f444dd0bc41c39a1f27a7aac14aad931ff25..67a83c99d6582282d024de6c5605ade0eaad1409 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "7c8d97cc8cd3a2ebf93eacc429204dd6", + "content-hash": "c290884be59436699c4bc44490b1ab04", "packages": [ { "name": "alchemy/zippy", @@ -4669,6 +4669,48 @@ "issues": "http://drupal.org/project/issues/metatag" } }, + { + "name": "drupal/migrate_devel", + "version": "dev-1.x", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/migrate_devel", + "reference": "d56b84fe79621199305f36c707bbb5d209ee1b6b" + }, + "require": { + "drupal/core": "*" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1498434542", + "security-coverage": { + "status": "not-covered", + "message": "Project has not opted into security advisory coverage!" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Derimagia", + "homepage": "https://www.drupal.org/user/819640" + } + ], + "description": "Migrate Development Tools", + "homepage": "https://www.drupal.org/project/migrate_devel", + "support": { + "source": "http://cgit.drupalcode.org/migrate_devel" + }, + "time": "2017-06-25T23:46:13+00:00" + }, { "name": "drupal/migrate_plus", "version": "4.0.0", @@ -10507,6 +10549,7 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { + "drupal/migrate_devel": 20, "drupal/roleassign": 15, "drupal/view_unpublished": 15 }, diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index efec831bfe34379ba81e61398ac313a046249ff6..cfb96f43e17d275b9c06b93568f62696c84ad15d 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -4812,6 +4812,49 @@ "issues": "http://drupal.org/project/issues/metatag" } }, + { + "name": "drupal/migrate_devel", + "version": "dev-1.x", + "version_normalized": "dev-1.x", + "source": { + "type": "git", + "url": "https://git.drupal.org/project/migrate_devel", + "reference": "d56b84fe79621199305f36c707bbb5d209ee1b6b" + }, + "require": { + "drupal/core": "*" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "drupal": { + "version": "8.x-1.x-dev", + "datestamp": "1498434542", + "security-coverage": { + "status": "not-covered", + "message": "Project has not opted into security advisory coverage!" + } + } + }, + "installation-source": "source", + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Derimagia", + "homepage": "https://www.drupal.org/user/819640" + } + ], + "description": "Migrate Development Tools", + "homepage": "https://www.drupal.org/project/migrate_devel", + "support": { + "source": "http://cgit.drupalcode.org/migrate_devel" + } + }, { "name": "drupal/migrate_plus", "version": "4.0.0", diff --git a/web/modules/migrate_devel/.gitignore b/web/modules/migrate_devel/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9f11b755a17d8192c60f61cb17b8902dffbd9f23 --- /dev/null +++ b/web/modules/migrate_devel/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/web/modules/migrate_devel/README.md b/web/modules/migrate_devel/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8a870567a19ae133d3f4fc4d27fb494788c8ad98 --- /dev/null +++ b/web/modules/migrate_devel/README.md @@ -0,0 +1,23 @@ +# Migrate Devel + +Adds new options to `drush migrate-import` which +allows developers to debug their migrations. + +`drush migrate-import` comes from either the +[migrate_tools](https://www.drupal.org/project/migrate_tools) or the +[migrate_run](https://www.drupal.org/project/migrate_run) modules. + +Currently uses Kint (from devel) directly to print out debug information +instead of devel in order to take advantage of +cli coloring and named variable debugging. + +Options are: + +* `--migrate-debug` - Prints out rows as they run. +Can be used in `migrate-import` or `migrate-status` and will revert +existing migrations to the default and clear the cache for them. +This requires [config_update](https://www.drupal.org/project/config_update) +if you use [migrate_plus](https://www.drupal.org/project/migrate_plus) +because migrations go into config. +* `--migrate-debug-pre` - Same as above before the process is run on the row. +Can be used in `migrate-import`. diff --git a/web/modules/migrate_devel/migrate_devel.drush.inc b/web/modules/migrate_devel/migrate_devel.drush.inc new file mode 100644 index 0000000000000000000000000000000000000000..2d686c3a3a7afa7086c4e8cab88f772c4bf33e8c --- /dev/null +++ b/web/modules/migrate_devel/migrate_devel.drush.inc @@ -0,0 +1,119 @@ +<?php + +/** + * @file + * File for Drush Integration. + */ +use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface; +use Drupal\config_update\ConfigListInterface; +use Drupal\config_update\ConfigRevertInterface; +use Drupal\Core\Config\StorageInterface; +use Drush\Log\LogLevel; + +/** + * Implements hook_drush_help_alter(). + */ +function migrate_devel_drush_help_alter(&$command) { + if ($command['command'] === 'migrate-import') { + $command['options']['migrate-debug'] = 'Enable Debug Mode'; + $command['options']['migrate-debug-pre'] = 'Enable Debug Mode (Before Row Save)'; + } + + if ($command['command'] === 'migrate-status') { + $command['options']['migrate-debug'] = 'Enable Debug Mode'; + } +} + +/** + * Implements hook_drush_command_alter(). + */ +function migrate_devel_drush_command_alter(&$command) { + $cmd = $command['command']; + if ($cmd === 'migrate-import' || $cmd === 'migrate-status') { + // Reset all migrations + if (drush_get_option('migrate-debug')) { + migrate_devel_rebuild_migrations(); + } + } +} + +/** + * Clears cache for migrations and reverts config of migrations if needed. + */ +function migrate_devel_rebuild_migrations() { + // @TODO: Remove this legacy support of migrate_plus. + // After #2752335, it uses the default Migrate Plugin Manager + /* @var $discovery CachedDiscoveryInterface */ + if (\Drupal::hasService('plugin.manager.config_entity_migration')) { + $discovery = \Drupal::service('plugin.manager.config_entity_migration'); + } else { + $discovery = \Drupal::service('plugin.manager.migration'); + } + + // Reset cached migrations + $discovery->clearCachedDefinitions(); + + /* @var $discovery CachedDiscoveryInterface */ + if (\Drupal::moduleHandler()->moduleExists('migrate_plus')) { + migrate_devel_revert_migrate_config($discovery); + } + + drush_log(dt('Reset Cached Migrations'), LogLevel::DEBUG); +} + +/** + * Reverts migrate config for migrate_plus + * + * @param CachedDiscoveryInterface $discovery + */ +function migrate_devel_revert_migrate_config($discovery) { + // If migrate_plus and config_update exists, revert the config. + if (\Drupal::moduleHandler()->moduleExists('config_update')) { + /* @var $config_revert ConfigRevertInterface */ + $config_revert = \Drupal::service('config_update.config_update'); + + foreach ($discovery->getDefinitions() as $definition) { + $config_revert->revert('migration', $definition['id']); + } + + drush_log(dt('Reverted Existing Migration Configs')); + + // Revert missing config + migrate_devel_revert_missing_config('migration'); + } else { + drush_log(dt('Missing config_update for revert.')); + } +} + +/** + * Reverts missing config for a specific config type. + * + * @param string $type + */ +function migrate_devel_revert_missing_config($type) { + /* @var ConfigRevertInterface $config_revert */ + $config_revert = \Drupal::service('config_update.config_update'); + + // Now we need to add any new migrations. + /* @var ConfigListInterface $config_lister */ + $config_lister = \Drupal::service('config_update.config_list'); + + // Add any new migrations we need to. + list($active_list, $install_list, $optional_list) = $config_lister->listConfig('type', $type); + $missing = array_diff($install_list, $active_list); + + /* @var StorageInterface $config_reader */ + $config_reader = \Drupal::service('config_update.extension_storage'); + + foreach ($missing as $name) { + $config = $config_reader->read($name); + $config_type = $config_lister->getTypeNameByConfigName($name); + $definition = $config_lister->getType($config_type); + $id_key = $definition->getKey('id'); + + if ($config_revert->import($config_type, $config[$id_key])) { + drush_log(dt('Imported @config', ['@config' => $name]), LogLevel::ALERT); + } + } +} + diff --git a/web/modules/migrate_devel/migrate_devel.info.yml b/web/modules/migrate_devel/migrate_devel.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..b9a03e3b13dc41fd3b7755af34e28a260fac9905 --- /dev/null +++ b/web/modules/migrate_devel/migrate_devel.info.yml @@ -0,0 +1,9 @@ +name: Migrate Devel +description: Migrate Development Tools +package: Migrate +type: module +core: 8.x +dependencies: + - drupal:devel + - drupal:migrate + - drupal:kint diff --git a/web/modules/migrate_devel/migrate_devel.services.yml b/web/modules/migrate_devel/migrate_devel.services.yml new file mode 100644 index 0000000000000000000000000000000000000000..37ea7393b89a4c0e469b89467217086c2a17064c --- /dev/null +++ b/web/modules/migrate_devel/migrate_devel.services.yml @@ -0,0 +1,5 @@ +services: + migrate_devel.migrate_event_subscriber: + class: Drupal\migrate_devel\EventSubscriber\MigrationEventSubscriber + tags: + - { name: event_subscriber } diff --git a/web/modules/migrate_devel/src/EventSubscriber/MigrationEventSubscriber.php b/web/modules/migrate_devel/src/EventSubscriber/MigrationEventSubscriber.php new file mode 100644 index 0000000000000000000000000000000000000000..588ef44ff2827c984e4a3adf95765fc44efcca30 --- /dev/null +++ b/web/modules/migrate_devel/src/EventSubscriber/MigrationEventSubscriber.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\migrate_devel\EventSubscriber; + +use Drupal\migrate\Event\MigrateEvents; +use Drupal\migrate\Event\MigratePostRowSaveEvent; +use Drupal\migrate\Event\MigratePreRowSaveEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * MigrationEventSubscriber for Debugging Migrations. + * + * @class MigrationEventSubscriber + */ +class MigrationEventSubscriber implements EventSubscriberInterface { + + /** + * Pre Row Save Function for --migrate-debug-pre. + * + * @param \Drupal\migrate\Event\MigratePreRowSaveEvent $event + * Pre-Row-Save Migrate Event. + */ + public function debugRowPreSave(MigratePreRowSaveEvent $event) { + $row = $event->getRow(); + + $using_drush = function_exists('drush_get_option'); + if ($using_drush && drush_get_option('migrate-debug-pre')) { + // Start with capital letter for variables since this is actually a label. + $Source = $row->getSource(); + $Destination = $row->getDestination(); + + // We use kint directly here since we want to support variable naming. + kint_require(); + \Kint::dump($Source, $Destination); + } + } + + /** + * Post Row Save Function for --migrate-debug. + * + * @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event + * Post-Row-Save Migrate Event. + */ + public function debugRowPostSave(MigratePostRowSaveEvent $event) { + $row = $event->getRow(); + + $using_drush = function_exists('drush_get_option'); + if ($using_drush && drush_get_option('migrate-debug')) { + // Start with capital letter for variables since this is actually a label. + $Source = $row->getSource(); + $Destination = $row->getDestination(); + $DestinationIDValues = $event->getDestinationIdValues(); + + // We use kint directly here since we want to support variable naming. + kint_require(); + \Kint::dump($Source, $Destination, $DestinationIDValues); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[MigrateEvents::PRE_ROW_SAVE][] = ['debugRowPreSave']; + $events[MigrateEvents::POST_ROW_SAVE][] = ['debugRowPostSave']; + return $events; + } + +}