Further modules included.
[yaffs-website] / web / modules / contrib / drupalmoduleupgrader / drupalmoduleupgrader.drush.inc
1 <?php
2
3 use Drupal\drupalmoduleupgrader\Report;
4 use Drupal\drupalmoduleupgrader\Target;
5 use Symfony\Component\Filesystem\Filesystem;
6
7 /**
8  * Implements hook_drush_command().
9  */
10 function drupalmoduleupgrader_drush_command() {
11   $items = [];
12
13   $items['dmu-list'] = [
14     'description' => 'Lists available plugins.',
15     'arguments' => [
16       'plugin_type' => 'The plugin type to query. Can be one of: indexer, analyzer, converter, cleaner.',
17     ],
18     'required-arguments' => TRUE,
19     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
20   ];
21
22   $items['dmu-index'] = [
23     'description' => 'Indexes a target module.',
24     'arguments' => [
25       'module' => 'The name of a Drupal 7 module.',
26     ],
27     'required-arguments' => TRUE,
28     'examples' => [
29       'drush dmu-index pants' => 'Indexes the pants module.',
30     ],
31     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
32   ];
33
34   $items['dmu-analyze'] = [
35     'description' => "Analyzes a Drupal 7 module and reports the changes needed to port it to Drupal 8.",
36     'arguments' => [
37       'module' => 'The machine name of a Drupal 7 module.',
38     ],
39     'required-arguments' => TRUE,
40     'options' => [
41       'only' => [
42         'description' => 'A comma-separated list of analyzers to run, excluding all others.',
43         'example-value' => 'HookMenu,VariableAPI,BlockInfo',
44       ],
45       'skip' => [
46         'description' => 'A comma-separated list of analyzers to skip.',
47         'example-value' => 'HookInit,HookExit',
48       ],
49       'path' => [
50         'description' => 'Optional path to the target module.',
51         'example-value' => 'drupal/modules/foobaz',
52       ],
53       'output' => [
54         'description' => 'Optional path to output the report.',
55         'example-value' => 'path/to/module/analyze.html',
56       ],
57     ],
58     'examples' => [
59       'drush dmu-analyze pants' => 'Analyze what needs to be changed in order to port the pants module.',
60     ],
61     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
62   ];
63
64   $items['dmu-upgrade'] = [
65     'description' => "Upgrades a Drupal 7 module to Drupal 8.",
66     'arguments' => [
67       'module' => 'The machine name of a Drupal 7 module.',
68     ],
69     'required-arguments' => TRUE,
70     'options' => [
71       'backup' => [
72         'description' => 'If set, creates a backup copy of the module before conversion.',
73       ],
74       'only' => [
75         'description' => 'A comma-separated list of converters to run, excluding all others.',
76         'example-value' => 'HookMenu,VariableAPI,BlockInfo',
77       ],
78       'skip' => [
79         'description' => 'A comma-separated list of converters to skip.',
80         'example-value' => 'HookInit,HookExit',
81       ],
82       'path' => [
83         'description' => 'Optional path to the target module. Will be determined automatically if omitted.',
84         'example-value' => 'drupal/modules/foobaz',
85       ],
86     ],
87     'examples' => [
88       'drush dmu-upgrade pants' => 'Upgrade whatever can be automatically upgraded in the pants module.',
89     ],
90     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
91   ];
92
93   return $items;
94 }
95
96 /**
97  * Returns a list of plugin IDs of a given type, filtered by the --only
98  * and --skip options.
99  *
100  * @param string $plugin_type
101  *  The plugin type. Can be one of indexer, analyzer, converter, cleaner.
102  *
103  * @return string[]
104  */
105 function _dmu_plugin_list($plugin_type) {
106   // Instantiate the plugin manager and get all available plugin IDs.
107   $manager = \Drupal::service('plugin.manager.drupalmoduleupgrader.' . $plugin_type);
108   $plugin_IDs = array_keys($manager->getDefinitions());
109
110   // Filter by the --only and --skip options, if set.
111   if ($only = drush_get_option('only', FALSE)) {
112     $plugin_IDs = array_intersect($plugin_IDs, explode(',', $only));
113   }
114   elseif ($skip = drush_get_option('skip', FALSE)) {
115     $plugin_IDs = array_diff($plugin_IDs, explode(',', $skip));
116   }
117
118   return $plugin_IDs;
119 }
120
121 /**
122  * Checks for autoload.php, and includes it if it exists or sets an error
123  * if it doesn't.
124  */
125 function _dmu_ensure_autoload() {
126   $locations = [
127     __DIR__ . '/vendor/autoload.php',
128     './vendor/autoload.php',
129   ];
130   foreach ($locations as $location) {
131     if (file_exists($location)) {
132       require_once $location;
133       return;
134     }
135   }
136
137   drush_set_error('no_autoload', 'autoload.php not found! Did you remember to run composer install from the drupalmoduleupgrader directory?');
138 }
139
140 /**
141  * Determines the path to a module.
142  *
143  * @param string $module
144  *  The module's machine name.
145  *
146  * @return string|NULL
147  */
148 function _dmu_get_directory($module) {
149   if ($path = drush_get_option('path', NULL)) {
150     return $path;
151   }
152   else {
153     $search_directories = [
154       DRUPAL_ROOT . '/modules/' . $module,
155       __DIR__ . '/'. $module,
156     ];
157
158     $directories = array_filter($search_directories, 'is_dir');
159     if ($directories) {
160       return reset($directories);
161     }
162   }
163 }
164
165 /**
166  * Checks possible locations of a target module, and ensures that at least
167  * one exists. If none do, sets an error.
168  *
169  * @param string $module
170  *  The target module's machine name.
171  */
172 function _dmu_ensure_directory($module) {
173   $directory = _dmu_get_directory($module);
174
175   if (empty($directory)) {
176     if ($path = drush_get_option('path', NULL)) {
177       drush_set_error('invalid_dir', 'Invalid path: ' . $path);
178     }
179     else {
180       drush_set_error('no_directory', "Cannot determine base directory of module $module. Try passing --path=modules/foobar");
181     }
182   }
183 }
184
185 /**
186  * Validates any of the DMU commands.
187  */
188 function _dmu_validate_command($module) {
189   _dmu_ensure_autoload();
190   _dmu_ensure_directory($module);
191 }
192
193 function _dmu_build_target($module) {
194   $target = new Target(_dmu_get_directory($module), \Drupal::getContainer());
195
196   drush_print(\Drupal::translation()->translate('Indexing...'), 0, NULL, FALSE);
197   $target->buildIndex();
198   drush_print(\Drupal::translation()->translate('done.'));
199
200   return $target;
201 }
202
203 /**
204  * ----- dmu-list -----
205  */
206
207 /**
208  * Lists all the available module-wide plugins.
209  */
210 function drush_drupalmoduleupgrader_dmu_list($plugin_type) {
211   $manager = \Drupal::service('plugin.manager.drupalmoduleupgrader.' . $plugin_type);
212
213   $list = [];
214   foreach ($manager->getDefinitions() as $id => $definition) {
215     $list[$id] = $definition['description'];
216   }
217   drush_print_table(drush_key_value_to_array_table($list));
218 }
219
220 /**
221  * ----- dmu-index -----
222  */
223
224 function drush_drupalmoduleupgrader_dmu_index_validate($module) {
225   _dmu_validate_command($module);
226 }
227
228 /**
229  * ----- dmu-analyze -----
230  */
231
232 function drush_drupalmoduleupgrader_dmu_analyze_validate($module) {
233   _dmu_validate_command($module);
234 }
235
236 /**
237  * Analyzes what needs changing in a module to port it to Drupal 8.
238  *
239  * @param string $module
240  *  The machine name of the module to analyze.
241  */
242 function drush_drupalmoduleupgrader_dmu_analyze($module) {
243   $target = _dmu_build_target($module);
244
245   $total_issues = 0;
246   $report = new Report();
247
248   $analyzers = \Drupal::service('plugin.manager.drupalmoduleupgrader.analyzer');
249   foreach (_dmu_plugin_list('analyzer') as $id) {
250     drush_log(\Drupal::translation()->translate('Executing plugin: @plugin_id', ['@plugin_id' => $id]), 'notice');
251     $issues = $analyzers->createInstance($id)->analyze($target);
252
253     if ($issues) {
254       if (! is_array($issues)) {
255         $issues = array($issues);
256       }
257       foreach ($issues as $issue) {
258         $report->addIssue($issue);
259       }
260       $total_issues += sizeof($issues);
261     }
262   }
263
264   if ($total_issues) {
265     $render = [
266       '#theme' => 'dmu_report',
267       '#report' => $report,
268       '#group_by' => 'category',
269     ];
270
271     $destination = drush_get_option('output', $target->getPath('upgrade-info.html'));
272     $output = \Drupal::service('renderer')->renderRoot($render);
273     file_put_contents($destination, $output);
274     drush_log(\Drupal::translation()->translate('Generated a report at @path', ['@path' => $destination]), 'success');
275   }
276   else {
277     drush_log(\Drupal::translation()->translate('Wow...no issues found! You get a cookie :)', 'success'));
278   }
279 }
280
281 /**
282  * ----- dmu-upgrade -----
283  */
284
285 function drush_drupalmoduleupgrader_dmu_upgrade_validate($module) {
286   _dmu_validate_command($module);
287 }
288
289 /**
290  * Tries to automatically convert a Drupal 7 module to Drupal 8.
291  *
292  * @param string $module
293  *  The module to upgrade.
294  */
295 function drush_drupalmoduleupgrader_dmu_upgrade($module) {
296   $target = _dmu_build_target($module);
297
298   if (drush_get_option('backup', FALSE)) {
299     $fs = new Filesystem();
300     $backup_at = $target->getBasePath() . '.bak';
301     $fs->mirror($target->getBasePath(), $backup_at);
302     drush_log(\Drupal::translation()->translate('Created backup at @path', [ '@path' => $backup_at ]), 'success');
303   }
304
305   $converters = \Drupal::service('plugin.manager.drupalmoduleupgrader.converter');
306   foreach (_dmu_plugin_list('converter') as $id) {
307     /** @var \Drupal\drupalmoduleupgrader\ConverterInterface $converter */
308     $converter = $converters->createInstance($id);
309
310     if ($converter->isExecutable($target)) {
311       drush_log(\Drupal::translation()->translate('Executing plugin: @plugin_id', ['@plugin_id' => $id]), 'notice');
312       try {
313         $converter->convert($target);
314       }
315       catch (Exception $e) {
316         drush_log($e->getMessage(), 'error');
317         // Being a notice, the stack trace will only appear in verbose mode.
318         drush_log($e->getTraceAsString(), 'notice');
319       }
320     }
321   }
322 }