help.drush.inc

  1. 8.0.x commands/core/help.drush.inc
  2. 6.x commands/core/help.drush.inc
  3. 7.x commands/core/help.drush.inc
  4. 4.x commands/core/help.drush.inc
  5. 5.x commands/core/help.drush.inc
  6. master commands/core/help.drush.inc

Functions

Namesort descending Description
core_help_complete Command argument complete callback.
drush_core_help Command callback for help command. This is the default command, when none other has been specified.
drush_format_help_section Format one named help section from a command record
drush_global_options_command Build a fake command for the purposes of showing examples and options.
drush_help_html Return an HTML page documenting all available commands and global options.
drush_help_html_command_list
drush_help_html_global_options
drush_help_html_header Return an HTML page header.
drush_help_listing_print Print CLI table or HTML table listing all commands.
drush_help_section_default_formatter The default section formatter. Replaces '[command]' with the command name.
drush_help_section_formatter_options The options section formatter. Adds a "--" in front of each item label. Also handles short-form and example-value components in the help attributes.
drush_help_visible
drush_print_help Print the help for a single command to the screen.
drush_show_help Prints out help for a given command.
help_drush_command Implementation of hook_drush_command().
help_drush_help Implementation of hook_drush_help().
_drush_format_help_subsection Format one named portion of a subsection from a command record. Subsections allow related parts of a help record to be grouped together. For example, in the 'options' section, sub-options that are related to a particular primary option are…
_drush_help_merge_subcommand_information Check to see if the specified command contains an 'allow-additional-options' record. If it does, find the additional options that are allowed, and add in the help text for the options of all of the sub-commands.
_drush_help_sort_command_options Sort command options alphabetically. Engine options at the end.

File

commands/core/help.drush.inc
View source
  1. <?php
  2. use Drush\Log\LogLevel;
  3. /**
  4. * Implementation of hook_drush_help().
  5. *
  6. * This function is called whenever a drush user calls
  7. * 'drush help <name-of-your-command>'
  8. *
  9. * @param
  10. * A string with the help section (prepend with 'drush:')
  11. *
  12. * @return
  13. * A string with the help text for your command.
  14. */
  15. function help_drush_help($section) {
  16. switch ($section) {
  17. case 'drush:help':
  18. return dt("Drush provides an extensive help system that describes both drush commands and topics of general interest. Use `drush help --filter` to present a list of command categories to view, and `drush topic` for a list of topics that go more in-depth on how to use and extend drush.");
  19. }
  20. }
  21. /**
  22. * Implementation of hook_drush_command().
  23. *
  24. * In this hook, you specify which commands your
  25. * drush module makes available, what it does and
  26. * description.
  27. *
  28. * Notice how this structure closely resembles how
  29. * you define menu hooks.
  30. *
  31. * @return
  32. * An associative array describing your command(s).
  33. */
  34. function help_drush_command() {
  35. $items = array();
  36. $items['help'] = array(
  37. 'description' => 'Print this help message. See `drush help help` for more options.',
  38. 'bootstrap' => DRUSH_BOOTSTRAP_NONE,
  39. 'allow-additional-options' => TRUE,
  40. 'options' => array(
  41. 'sort' => 'Sort commands in alphabetical order. Drush waits for full bootstrap before printing any commands when this option is used.',
  42. 'filter' => array(
  43. 'description' => 'Restrict command list to those commands defined in the specified file. Omit value to choose from a list of names.',
  44. 'example-value' => 'category',
  45. 'value' => 'optional',
  46. ),
  47. 'format' => 'Format to output . Allowed values are: json, var_export, html.',
  48. 'pipe' => 'A list of available commands, one per line.',
  49. ),
  50. 'arguments' => array(
  51. 'command' => 'A command name, or command alias.',
  52. ),
  53. 'examples' => array(
  54. 'drush' => 'List all commands.',
  55. 'drush --filter=devel_generate' => 'Show only commands defined in devel_generate.drush.inc',
  56. 'drush help pm-download' => 'Show help for one command.',
  57. 'drush help dl' => 'Show help for one command using an alias.',
  58. ),
  59. 'topics' => array('docs-readme'),
  60. );
  61. return $items;
  62. }
  63. /**
  64. * Command argument complete callback.
  65. *
  66. * @return
  67. * Array of available command names.
  68. */
  69. function core_help_complete() {
  70. return array('values' => array_keys(drush_get_commands()));
  71. }
  72. /**
  73. * Prints out help for a given command.
  74. */
  75. function drush_show_help($commandstring) {
  76. // First check and see if the command can already be found.
  77. $commands = drush_get_commands();
  78. if (!array_key_exists($commandstring, $commands)) {
  79. // If the command cannot be found, then bootstrap so that
  80. // additional commands will be brought in.
  81. // For speed, only bootstrap up to DRUSH_BOOTSTRAP_DRUPAL_SITE.
  82. drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE);
  83. $commands = drush_get_commands();
  84. }
  85. if (array_key_exists($commandstring, $commands)) {
  86. $command = $commands[$commandstring];
  87. drush_print_help($command);
  88. return TRUE;
  89. }
  90. $shell_aliases = drush_get_context('shell-aliases', array());
  91. if (array_key_exists($commandstring, $shell_aliases)) {
  92. $msg = dt("'@alias-name' is a shell alias. Its value is: !name. See `drush topic docs-shell-aliases` and `drush shell-alias` for more information.", array('@alias-name' => $commandstring, '!name' => $shell_aliases[$commandstring]));
  93. drush_log($msg, LogLevel::OK);
  94. return TRUE;
  95. }
  96. return drush_set_error('DRUSH_COMMAND_NOT_FOUND', dt('Invalid command !command.', array('!command' => $commandstring)));
  97. }
  98. /**
  99. * Print the help for a single command to the screen.
  100. *
  101. * @param array $command
  102. * A fully loaded $command array.
  103. */
  104. function drush_print_help($command) {
  105. _drush_help_merge_subcommand_information($command);
  106. if (!$help = drush_command_invoke_all('drush_help', 'drush:'. $command['command'])) {
  107. $help = array($command['description']);
  108. }
  109. if ($command['strict-option-handling']) {
  110. $command['topics'][] = 'docs-strict-options';
  111. }
  112. // Give commandfiles an opportunity to add examples and options to the command.
  113. drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE);
  114. drush_engine_add_help_topics($command);
  115. drush_command_invoke_all_ref('drush_help_alter', $command);
  116. drush_print(wordwrap(implode("\n", $help), drush_get_context('DRUSH_COLUMNS', 80)));
  117. drush_print();
  118. $global_options = drush_get_global_options();
  119. foreach ($command['global-options'] as $global_option) {
  120. $command['options'][$global_option] = $global_options[$global_option];
  121. }
  122. // Sort command options.
  123. uksort($command['options'], '_drush_help_sort_command_options');
  124. // Print command sections help.
  125. foreach ($command['sections'] as $key => $value) {
  126. if (!empty($command[$key])) {
  127. $rows = drush_format_help_section($command, $key);
  128. if ($rows) {
  129. drush_print(dt($value) . ':');
  130. drush_print_table($rows, FALSE, array('label' => 40));
  131. unset($rows);
  132. drush_print();
  133. }
  134. }
  135. }
  136. // Append aliases if any.
  137. if ($command['aliases']) {
  138. drush_print(dt("Aliases: ") . implode(', ', $command['aliases']));
  139. }
  140. }
  141. /**
  142. * Sort command options alphabetically. Engine options at the end.
  143. */
  144. function _drush_help_sort_command_options($a, $b) {
  145. $engine_a = strpos($a, '=');
  146. $engine_b = strpos($b, '=');
  147. if ($engine_a && !$engine_b) {
  148. return 1;
  149. }
  150. else if (!$engine_a && $engine_b) {
  151. return -1;
  152. }
  153. elseif ($engine_a && $engine_b) {
  154. if (substr($a, 0, $engine_a) == substr($b, 0, $engine_b)) {
  155. return 0;
  156. }
  157. }
  158. return ($a < $b) ? -1 : 1;
  159. }
  160. /**
  161. * Check to see if the specified command contains an 'allow-additional-options'
  162. * record. If it does, find the additional options that are allowed, and
  163. * add in the help text for the options of all of the sub-commands.
  164. */
  165. function _drush_help_merge_subcommand_information(&$command) {
  166. // 'allow-additional-options' will either be FALSE (default),
  167. // TRUE ("allow anything"), or an array that lists subcommands
  168. // that are or may be called via drush_invoke by this command.
  169. if (is_array($command['allow-additional-options'])) {
  170. $implemented = drush_get_commands();
  171. foreach ($command['allow-additional-options'] as $subcommand_name) {
  172. if (array_key_exists($subcommand_name, $implemented)) {
  173. $command['options'] += $implemented[$subcommand_name]['options'];
  174. $command['sub-options'] = array_merge_recursive($command['sub-options'], $implemented[$subcommand_name]['sub-options']);
  175. if (empty($command['arguments'])) {
  176. $command['arguments'] = $implemented[$subcommand_name]['arguments'];
  177. }
  178. $command['topics'] = array_merge($command['topics'], $implemented[$subcommand_name]['topics']);
  179. }
  180. }
  181. }
  182. }
  183. /**
  184. * Format one named help section from a command record
  185. *
  186. * @param $command
  187. * A command record with help information
  188. * @param $section
  189. * The name of the section to format ('options', 'topic', etc.)
  190. * @returns array
  191. * Formatted rows, suitable for printing via drush_print_table. The returned
  192. * array can be empty.
  193. */
  194. function drush_format_help_section($command, $section) {
  195. $rows = array();
  196. $formatter = (function_exists('drush_help_section_formatter_' . $section)) ? 'drush_help_section_formatter_' . $section : 'drush_help_section_default_formatter';
  197. foreach ($command[$section] as $name => $help_attributes) {
  198. if (!is_array($help_attributes)) {
  199. $help_attributes = array('description' => $help_attributes);
  200. }
  201. $help_attributes['label'] = $name;
  202. call_user_func_array($formatter, array($command, &$help_attributes));
  203. if (empty($help_attributes['hidden'])) {
  204. $rows[] = array('label' => $help_attributes['label'], 'description' => $help_attributes['description']);
  205. // Process the subsections too, if any
  206. if (!empty($command['sub-' . $section]) && array_key_exists($name, $command['sub-' . $section])) {
  207. $rows = array_merge($rows, _drush_format_help_subsection($command, $section, $name, $formatter));
  208. }
  209. }
  210. }
  211. return $rows;
  212. }
  213. /**
  214. * Format one named portion of a subsection from a command record.
  215. * Subsections allow related parts of a help record to be grouped
  216. * together. For example, in the 'options' section, sub-options that
  217. * are related to a particular primary option are stored in a 'sub-options'
  218. * section whose name == the name of the primary option.
  219. *
  220. * @param $command
  221. * A command record with help information
  222. * @param $section
  223. * The name of the section to format ('options', 'topic', etc.)
  224. * @param $subsection
  225. * The name of the subsection (e.g. the name of the primary option)
  226. * @param $formatter
  227. * The name of a function to use to format the rows of the subsection
  228. * @param $prefix
  229. * Characters to prefix to the front of the label (for indentation)
  230. * @returns array
  231. * Formatted rows, suitable for printing via drush_print_table.
  232. */
  233. function _drush_format_help_subsection($command, $section, $subsection, $formatter, $prefix = ' ') {
  234. $rows = array();
  235. foreach ($command['sub-' . $section][$subsection] as $name => $help_attributes) {
  236. if (!is_array($help_attributes)) {
  237. $help_attributes = array('description' => $help_attributes);
  238. }
  239. $help_attributes['label'] = $name;
  240. call_user_func_array($formatter, array($command, &$help_attributes));
  241. if (!array_key_exists('hidden', $help_attributes)) {
  242. $rows[] = array('label' => $prefix . $help_attributes['label'], 'description' => $help_attributes['description']);
  243. // Process the subsections too, if any
  244. if (!empty($command['sub-' . $section]) && array_key_exists($name, $command['sub-' . $section])) {
  245. $rows = array_merge($rows, _drush_format_help_subsection($command, $section, $name, $formatter, $prefix . ' '));
  246. }
  247. }
  248. }
  249. return $rows;
  250. }
  251. /**
  252. * The options section formatter. Adds a "--" in front of each
  253. * item label. Also handles short-form and example-value
  254. * components in the help attributes.
  255. */
  256. function drush_help_section_formatter_options($command, &$help_attributes) {
  257. if ($help_attributes['label'][0] == '-') {
  258. drush_log(dt("Option '!option' of command !command should instead be declared as '!fixed'", array('!option' => $help_attributes['label'], '!command' => $command['command'], '!fixed' => preg_replace('/^--*/', '', $help_attributes['label']))), LogLevel::DEBUG);
  259. }
  260. else {
  261. $help_attributes['label'] = '--' . $help_attributes['label'];
  262. }
  263. if (!empty($help_attributes['required'])) {
  264. $help_attributes['description'] .= " " . dt("Required.");
  265. }
  266. $prefix = '<';
  267. $suffix = '>';
  268. if (array_key_exists('example-value', $help_attributes)) {
  269. if (isset($help_attributes['value']) && $help_attributes['value'] == 'optional') {
  270. $prefix = '[';
  271. $suffix = ']';
  272. }
  273. $help_attributes['label'] .= '=' . $prefix . $help_attributes['example-value'] . $suffix;
  274. if (array_key_exists('short-form', $help_attributes)) {
  275. $help_attributes['short-form'] .= " $prefix" . $help_attributes['example-value'] . $suffix;
  276. }
  277. }
  278. if (array_key_exists('short-form', $help_attributes)) {
  279. $help_attributes['label'] = '-' . $help_attributes['short-form'] . ', ' . $help_attributes['label'];
  280. }
  281. drush_help_section_default_formatter($command, $help_attributes);
  282. }
  283. /**
  284. * The default section formatter. Replaces '[command]' with the
  285. * command name.
  286. */
  287. function drush_help_section_default_formatter($command, &$help_attributes) {
  288. // '[command]' is a token representing the current command. @see pm_drush_engine_version_control().
  289. $help_attributes['label'] = str_replace('[command]', $command['command'], $help_attributes['label']);
  290. }
  291. /**
  292. * Build a fake command for the purposes of showing examples and options.
  293. */
  294. function drush_global_options_command($brief = FALSE) {
  295. $global_options_help = array(
  296. 'description' => 'Execute a drush command. Run `drush help [command]` to view command-specific help. Run `drush topic` to read even more documentation.',
  297. 'sections' => array(
  298. 'options' => 'Global options (see `drush topic core-global-options` for the full list)',
  299. ),
  300. 'options' => drush_get_global_options($brief),
  301. 'examples' => array(
  302. 'drush dl cck zen' => 'Download CCK module and Zen theme.',
  303. 'drush --uri=http://example.com status' => 'Show status command for the example.com multi-site.',
  304. ),
  305. '#brief' => TRUE,
  306. );
  307. $global_options_help += drush_command_defaults('global-options', 'global_options', __FILE__);
  308. drush_command_invoke_all_ref('drush_help_alter', $global_options_help);
  309. ksort($global_options_help['options']);
  310. return $global_options_help;
  311. }
  312. /**
  313. * Command callback for help command. This is the default command, when none
  314. * other has been specified.
  315. */
  316. function drush_core_help() {
  317. $commands = func_get_args();
  318. $format = drush_get_option('format');
  319. if (empty($commands)) {
  320. // For speed, only bootstrap up to DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION.
  321. drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION);
  322. $implemented = drush_get_commands();
  323. ksort($implemented);
  324. $command_categories = drush_commands_categorize($implemented);
  325. $visible = drush_help_visible($command_categories);
  326. // If the user specified --filter w/out a value, then
  327. // present a choice list of help categories.
  328. if (drush_get_option('filter', FALSE) === TRUE) {
  329. $help_categories = array();
  330. foreach ($command_categories as $key => $info) {
  331. $description = $info['title'];
  332. if (array_key_exists('summary', $info)) {
  333. $description .= ": " . $info['summary'];
  334. }
  335. $help_categories[$key] = $description;
  336. }
  337. $result = drush_choice($help_categories, 'Select a help category:');
  338. if (!$result) {
  339. return drush_user_abort();
  340. }
  341. drush_set_option('filter', $result);
  342. }
  343. // Filter out categories that the user does not want to see
  344. $filter_category = drush_get_option('filter');
  345. if (!empty($filter_category) && ($filter_category !== TRUE)) {
  346. if (!array_key_exists($filter_category, $command_categories)) {
  347. return drush_set_error('DRUSH_NO_CATEGORY', dt("The specified command category !filter does not exist.", array('!filter' => $filter_category)));
  348. }
  349. $command_categories = array($filter_category => $command_categories[$filter_category]);
  350. }
  351. if ($format == 'html') {
  352. drush_print(drush_help_html_header());
  353. }
  354. // Make a fake command section to hold the global options, then print it.
  355. $global_options_help = drush_global_options_command(TRUE);
  356. if (!in_array($format, array('html', 'var_export', 'json')) && !drush_get_option('filter')) {
  357. drush_print_help($global_options_help);
  358. }
  359. if ($format == 'json' || $format == 'var_export') {
  360. // Print giant array, and set backend_result. We do it this way because this command
  361. // isn't yet fully compliant with outputformat system. To do so, we need to deal with
  362. // the fact that this command varies output significantly when showing help for one
  363. // command versus a listing. We also have oddball HTML format.
  364. drush_print(drush_format($command_categories, 'commands'));
  365. drush_backend_set_result($command_categories);
  366. return NULL;
  367. }
  368. else {
  369. // HTML and CLI command listing (in a table).
  370. drush_help_listing_print($command_categories, $format);
  371. if ($format == 'html') {
  372. // Print global options and long-form help for all commands.
  373. drush_print(drush_help_html_global_options($global_options_help));
  374. drush_print(drush_help_html($visible));
  375. }
  376. }
  377. // Newline-delimited list for use by other scripts. Set the --pipe option.
  378. if (drush_get_option('pipe')) {
  379. drush_print_pipe(implode("\n", array_keys($visible)));
  380. }
  381. return;
  382. }
  383. else {
  384. $result = TRUE;
  385. while ((count($commands) > 0) && !drush_get_error()) {
  386. $result = drush_show_help(array_shift($commands));
  387. }
  388. return $result;
  389. }
  390. return drush_set_error('DRUSH_COMMAND_NOT_FOUND', dt('Invalid command !command.', array('!command' => implode(" ", $commands))));
  391. }
  392. // Uncategorize the list of commands. Hiddens have been removed and
  393. // filtering performed.
  394. function drush_help_visible($command_categories) {
  395. $all = array();
  396. foreach ($command_categories as $category => $info) {
  397. $all = array_merge($all, $info['commands']);
  398. }
  399. return $all;
  400. }
  401. /**
  402. * Print CLI table or HTML table listing all commands.
  403. */
  404. function drush_help_listing_print($command_categories, $format) {
  405. $all_commands = array();
  406. foreach ($command_categories as $key => $info) {
  407. // Get the commands in this category.
  408. $commands = $info['commands'];
  409. // Build rows for drush_print_table().
  410. $rows = array();
  411. foreach($commands as $cmd => $command) {
  412. $name = $command['aliases'] ? $cmd . ' (' . implode(', ', $command['aliases']) . ')': $cmd;
  413. $rows[$cmd] = array('name' => $name, 'description' => $command['description']);
  414. }
  415. // Vary the output by mode: CLI or HTML
  416. if ($format == 'html') {
  417. drush_print("<h3>" . $info['title'] . "</h3>");
  418. drush_print(drush_help_html_command_list($commands));
  419. }
  420. else {
  421. drush_print($info['title'] . ": (" . $key . ")");
  422. drush_print_table($rows, FALSE, array('name' => 20));
  423. }
  424. }
  425. }
  426. /**
  427. * Return an HTML page header.
  428. */
  429. function drush_help_html_header() {
  430. return "<html><head><title>Drush help</title><style>dt {font-size: 110%; font-weight: bold}</style></head><body>\n";
  431. }
  432. function drush_help_html_global_options($global_options_help) {
  433. // Global options
  434. $global_option_rows = drush_format_help_section($global_options_help, 'options');
  435. $output = '<h3>Global Options (see `drush topic core-global-options` for the full list)</h3><table>';
  436. foreach ($global_option_rows as $row) {
  437. $output .= "<tr>";
  438. foreach ($row as $value) {
  439. $output .= "<td>" . htmlspecialchars($value) . "</td>\n";
  440. }
  441. $output .= "</tr>";
  442. }
  443. $output .= "</table>\n";
  444. return $output;
  445. }
  446. function drush_help_html_command_list($commands) {
  447. // Command table
  448. $output = "<table>\n";
  449. foreach ($commands as $key => $command) {
  450. $output .= " <tr><td><a href=\"#$key\">$key</a></td><td>" . $command['description'] . "</td></tr>\n";
  451. }
  452. $output .= "</table>\n";
  453. return $output;
  454. }
  455. /**
  456. * Return an HTML page documenting all available commands and global options.
  457. */
  458. function drush_help_html($commands) {
  459. // Command details
  460. $output = '<h3>Command detail</h3><dl>';
  461. foreach ($commands as $key => $command) {
  462. $output .= "\n<a name=\"$key\"></a><dt>$key</dt><dd><pre>\n";
  463. ob_start();
  464. drush_show_help($key);
  465. $output .= ob_get_clean();
  466. $output .= "</pre></dd>\n";
  467. }
  468. $output .= "</body></html>\n";
  469. return $output;
  470. }