forked from drush-ops/drush
-
Notifications
You must be signed in to change notification settings - Fork 0
/
drush.api.php
425 lines (391 loc) · 13.7 KB
/
drush.api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
<?php
/**
* @file
* Documentation of the Drush API.
*/
/**
* Declare a new command.
*/
function hook_drush_command() {
// To learn more, run `drush topic docs-commands` and
// `drush topic docs-examplecommand`.
}
/**
* All drush commands are invoked in a specific order, using
* drush-made hooks, very similar to the Drupal hook system. See drush_invoke()
* for the actual implementation.
*
* For any commandfile named "hook", the following hooks are called, in
* order, for the command "COMMAND":
*
* 0. drush_COMMAND_init()
* 1. drush_hook_COMMAND_pre_validate()
* 2. drush_hook_COMMAND_validate()
* 3. drush_hook_pre_COMMAND()
* 4. drush_hook_COMMAND()
* 5. drush_hook_post_COMMAND()
*
* For example, here are the hook opportunities for a mysite.drush.inc file
* that wants to hook into the `pm-download` command.
*
* 1. drush_mysite_pm_download_pre_validate()
* 2. drush_mysite_pm_download_validate()
* 3. drush_mysite_pre_pm_download()
* 4. drush_mysite_pm_download()
* 5. drush_mysite_post_pm_download()
*
* Note that the drush_COMMAND_init() hook is only for use by the
* commandfile that defines the command.
*
* If any of hook function fails, either by calling drush_set_error
* or by returning FALSE as its function result, then the rollback
* mechanism is called. To fail with an error, call drush_set_error:
*
* return drush_set_error('MY_ERROR_CODE', dt('Error message.'));
*
* To allow the user to confirm or cancel a command, use drush_confirm
* and drush_user_abort:
*
* if (!drush_confirm(dt('Are you sure?'))) {
* return drush_user_abort();
* }
*
* The rollback mechanism will call, in reverse, all _rollback hooks.
* The mysite command file can implement the following rollback hooks:
*
* 1. drush_mysite_post_pm_download_rollback()
* 2. drush_mysite_pm_download_rollback()
* 3. drush_mysite_pre_pm_download_rollback()
* 4. drush_mysite_pm_download_validate_rollback()
* 5. drush_mysite_pm_download_pre_validate_rollback()
*
* Before any command is called, hook_drush_init() is also called.
* hook_drush_exit() is called at the very end of command invocation.
*
* @see includes/command.inc
*
* @see hook_drush_init()
* @see drush_COMMAND_init()
* @see drush_hook_COMMAND_pre_validate()
* @see drush_hook_COMMAND_validate()
* @see drush_hook_pre_COMMAND()
* @see drush_hook_COMMAND()
* @see drush_hook_post_COMMAND()
* @see drush_hook_post_COMMAND_rollback()
* @see drush_hook_COMMAND_rollback()
* @see drush_hook_pre_COMMAND_rollback()
* @see drush_hook_COMMAND_validate_rollback()
* @see drush_hook_COMMAND_pre_validate_rollback()
* @see hook_drush_exit()
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Take action before any command is run.
*
* Logging an error stops command execution.
*/
function hook_drush_init() {
}
/**
* Initialize a command prior to validation.
*
* If a command needs to bootstrap to a higher level, this is best done in the
* command init hook. It is permisible to bootstrap in any hook, but note that
* if bootstrapping adds more commandfiles (*.drush.inc) to the commandfile
* list, the newly-added commandfiles will not have any hooks called until the
* next phase. For example, a command that calls drush_bootstrap_max() in
* drush_hook_COMMAND() would only permit commandfiles from modules enabled in
* the site to participate in drush_hook_post_COMMAND() hooks.
*/
function drush_COMMAND_init() {
drush_bootstrap_max();
}
/**
* Run before a specific command validates.
*
* Logging an error stops command execution, and the rollback function (if any)
* for each hook implementation is invoked.
*
* @see drush_hook_COMMAND_pre_validate_rollback()
*/
function drush_hook_COMMAND_pre_validate() {
}
/**
* Run before a specific command executes.
*
* Logging an error stops command execution, and the rollback function (if any)
* for each hook implementation is invoked.
*
* @see drush_hook_COMMAND_validate_rollback()
*/
function drush_hook_COMMAND_validate() {
}
/**
* Run before a specific command executes.
*
* Logging an error stops command execution, and the rollback function (if any)
* for each hook implementation is invoked, in addition to the validate
* rollback.
*
* @see drush_hook_pre_COMMAND_rollback()
* @see drush_hook_COMMAND_validate_rollback()
*/
function drush_hook_pre_COMMAND() {
}
/**
* Implementation of the actual drush command.
*
* This is where most of the stuff should happen.
*
* Logging an error stops command execution, and the rollback function (if any)
* for each hook implementation is invoked, in addition to pre and
* validate rollbacks.
*
* @return mixed|false
* The return value will be passed along to the caller if --backend option is
* present. A boolean FALSE indicates failure and rollback will be inititated.
*
* @see drush_hook_COMMAND_rollback()
* @see drush_hook_pre_COMMAND_rollback()
* @see drush_hook_COMMAND_validate_rollback()
*/
function drush_hook_COMMAND() {
}
/**
* Run after a specific command executes.
*
* Logging an error stops command execution, and the rollback function (if any)
* for each hook implementation is invoked, in addition to pre, normal
* and validate rollbacks.
*
* @see drush_hook_post_COMMAND_rollback()
* @see drush_hook_COMMAND_rollback()
* @see drush_hook_pre_COMMAND_rollback()
* @see drush_hook_COMMAND_validate_rollback()
*/
function drush_hook_post_COMMAND() {
}
/**
* Take action after any command is run.
*/
function hook_drush_exit() {
}
/**
* Adjust the contents of any command structure prior to dispatch.
*
* @see core_drush_command_alter()
*/
function hook_drush_command_alter(&$command) {
}
/**
* Adjust the contents of a site alias.
*/
function hook_drush_sitealias_alter(&$alias_record) {
// If the alias is "remote", but the remote site is
// the system this command is running on, convert the
// alias record to a local alias.
if (isset($alias_record['remote-host'])) {
$uname = php_uname('n');
if ($alias_record['remote-host'] == $uname) {
unset($alias_record['remote-host']);
unset($alias_record['remote-user']);
}
}
}
/**
* Take action after a project has been downloaded.
*/
function hook_drush_pm_post_download($project, $release) {
}
/**
* Take action after a project has been updated.
*/
function hook_pm_post_update($project_name, $installed_release, $project) {
}
/**
* Adjust the location a project should be copied to after being downloaded.
*
* See @pm_drush_pm_download_destination_alter().
*/
function hook_drush_pm_download_destination_alter(&$project, $release) {
if ($some_condition) {
$project['project_install_location'] = '/path/to/install/to/' . $project['project_dir'];
}
}
/**
* Automatically download project dependencies at pm-enable time.
*
* Use a pre-pm_enable hook to download before your module is enabled,
* or a post-pm_enable hook (drush_hook_post_pm_enable) to run after
* your module is enabled.
*
* Your hook will be called every time pm-enable is executed; you should
* only download dependencies when your module is being enabled. Respect
* the --skip flag, and take no action if it is present.
*/
function drush_hook_pre_pm_enable() {
// Get the list of modules being enabled; only download dependencies if our
// module name appears in the list.
$modules = drush_get_context('PM_ENABLE_MODULES');
if (in_array('hook', $modules) && !drush_get_option('skip')) {
$url = 'http://server.com/path/MyLibraryName.tgz';
$path = drush_get_context('DRUSH_DRUPAL_ROOT');
drush_include_engine('drupal', 'environment');
if (drush_module_exists('libraries')) {
$path .= '/' . libraries_get_path('MyLibraryName') . '/MyLibraryName.tgz';
}
else {
$path .= '/' . drupal_get_path('module', 'hook') . '/MyLibraryName.tgz';
}
drush_download_file($url, $path) && drush_tarball_extract($path);
}
}
/**
* Sql-sync sanitization example.
*
* This is equivalent to the built-in --sanitize option of sql-sync, but
* simplified to only work with default values on Drupal 6 + mysql.
*
* @see sql_drush_sql_sync_sanitize()
*/
function hook_drush_sql_sync_sanitize($source) {
$table = drush_get_option('db-prefix') ? '{users}' : 'users';
drush_sql_register_post_sync_op('my-sanitize-id',
dt('Reset passwords and email addresses in user table.'),
"UPDATE $table SET pass = MD5('password'), mail = concat('user+', uid, '@localhost') WHERE uid > 0;");
}
/**
* Add help components to a command.
*/
function hook_drush_help_alter(&$command) {
if ($command['command'] == 'sql-sync') {
$command['options']['myoption'] = "Description of modification of sql-sync done by hook";
$command['sub-options']['sanitize']['my-sanitize-option'] = "Description of sanitization option added by hook (grouped with --sanitize option)";
}
if ($command['command'] == 'global-options') {
// Recommended: don't show global hook options in brief global options help.
if ($command['#brief'] === FALSE) {
$command['options']['myglobaloption'] = 'Description of option used globally in all commands (e.g. in a commandfile init hook)';
}
}
}
/**
* Add/edit options to cache-clear command.
*
* @param array $types
* Adjust types as needed. Is passed by reference.
*
* @param bool $include_bootstrapped_types
* If FALSE, omit types which require a FULL bootstrap.
*/
function hook_drush_cache_clear(&$types, $include_bootstrapped_types) {
$types['views'] = 'views_invalidate_cache';
}
/**
* Inform drush about one or more engine types.
*
* This hook allow to declare available engine types, the cli option to select
* between engine implementatins, which one to use by default, global options
* and other parameters. Commands may override this info when declaring the
* engines they use.
*
* @return array
* An array whose keys are engine type names and whose values describe
* the characteristics of the engine type in relation to command definitions:
*
* - description: The engine type description.
* - topic: If specified, the name of the topic command that will
* display the automatically generated topic for this engine.
* - topic-file: If specified, the path to the file that will be
* displayed at the head of the automatically generated topic for
* this engine. This path is relative to the Drush root directory;
* non-core commandfiles should therefore use:
* 'topic-file' => dirname(__FILE__) . '/mytopic.html';
* - topics: If set, contains a list of topics that should be added to
* the "Topics" section of any command that uses this engine. Note
* that if 'topic' is set, it will automatically be added to the topics
* list, and therefore does not need to also be listed here.
* - option: The command line option to choose an implementation for
* this engine type.
* FALSE means there's no option. That is, the engine type is for internal
* usage of the command and thus an implementation is not selectable.
* - default: The default implementation to use by the engine type.
* - options: Engine options common to all implementations.
* - add-options-to-command: If there's a single implementation for this
* engine type, add its options as command level options.
* - combine-help: If there are multiple implementations for this engine
* type, then instead of adding multiple help items in the form of
* --engine-option=engine-type [description], instead combine all help
* options into a single --engine-option that lists the different possible
* values that can be used.
*
* @see drush_get_engine_types_info()
* @see pm_drush_engine_type_info()
*/
function hook_drush_engine_type_info() {
return array(
'dessert' => array(
'description' => 'Choose a dessert while the sandwich is baked.',
'option' => 'dessert',
'default' => 'ice-cream',
'options' => 'sweetness',
'add-options-to-command' => FALSE,
),
);
}
/**
* Inform drush about one or more engines implementing a given engine type.
*
* - description: The engine implementation's description.
* - implemented-by: The engine that actually implements this engine.
* This is useful to allow the implementation of similar engines
* in the reference one.
* Defaults to the engine type key (e.g. 'ice-cream').
* - verbose-only: The engine implementation will only appear in help
* output in --verbose mode.
*
* This hook allow to declare implementations for an engine type.
*
* @see pm_drush_engine_package_handler()
* @see pm_drush_engine_version_control()
*/
function hook_drush_engine_ENGINE_TYPE() {
return array(
'ice-cream' => array(
'description' => 'Feature rich ice-cream with all kind of additives.',
'options' => array(
'flavour' => 'Choose your favorite flavour',
),
),
'frozen-yogurt' => array(
'description' => 'Frozen dairy dessert made with yogurt instead of milk and cream.',
'implemented-by' => 'ice-cream',
),
);
}
/**
* Alter the order that hooks are invoked.
*
* When implementing a given hook we may need to ensure it is invoked before
* or after another implementation of the same hook. For example, let's say
* you want to implement a hook that would be called after drush_make. You'd
* write a drush_MY_MODULE_post_make() function. But if you need your hook to
* be called before drush_make_post_make(), you can ensure this by implemen-
* ting MY_MODULE_drush_invoke_alter().
*
* @see drush_command_invoke_all_ref()
*/
function hook_drush_invoke_alter($modules, $hook) {
if ($hook == 'some_hook') {
// Take the module who's hooks would normally be called last.
$module = array_pop($modules);
// Ensure it'll be called first for 'some_hook'.
array_unshift($modules, $module);
}
}
/**
* @} End of "addtogroup hooks".
*/