devel.drush.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * @file
  4. * Drush integration for the devel module.
  5. */
  6. /**
  7. * Implements hook_drush_command().
  8. */
  9. function devel_drush_command() {
  10. $items['devel-download'] = array(
  11. 'description' => dt('Downloads the FirePHP library from http://firephp.org/.'),
  12. 'arguments' => array(
  13. 'path' => dt('Path to the download folder. This path is relative to the Drupal root. If omitted Drush will use the default location (sites/all/libraries/FirePHPCore).'),
  14. ),
  15. );
  16. $items['devel-reinstall'] = array(
  17. 'description' => dt('Disable, Uninstall, and Install a list of projects.'),
  18. 'drush dependencies' => array('pm'),
  19. 'arguments' => array(
  20. 'projects' => dt('A space-separated list of project names.'),
  21. ),
  22. 'allow-additional-options' => array('pm-disable', 'pm-uninstall', 'pm-enable'),
  23. 'required-arguments' => 1,
  24. 'aliases' => array('dre'),
  25. );
  26. $items['fn-hook'] = array(
  27. 'description' => 'List implementations of a given hook and explore the source of the selected one.',
  28. 'arguments' => array(
  29. 'hook' => 'The name of the hook to explore (e.g. "menu" for hook_menu()).'
  30. ),
  31. 'examples' => array(
  32. 'fn-hook cron' => 'List implementations of hook_cron().',
  33. ),
  34. 'allow-additional-options' => array('fn-view'),
  35. 'required-arguments' => 1,
  36. 'aliases' => array('fnh', 'hook'),
  37. );
  38. $items['fn-view'] = array(
  39. 'description' => 'Show the source of specified function or method.',
  40. 'arguments' => array(
  41. 'function' => 'The name of the function or method to view.',
  42. ),
  43. 'options' => array(
  44. 'pipe' => 'Output just the filename of the function',
  45. 'format' => 'Specify how the filename should be printed. Available placeholders are !startline, !endline and !file',
  46. ),
  47. 'examples' => array(
  48. 'fn-view drupal_set_breadcrumb' => 'View the source code for function "drupal_set_breadcrumb"',
  49. 'vi `drush --pipe fn-view user_access --format=\'+!startline !file\'`' => 'Edit the file that contains the function "user_access"',
  50. 'fn-view NodeController::load' => 'View the source code for method load in the class NodeController'
  51. ),
  52. 'aliases' => array('fnv'),
  53. 'required-arguments' => 1,
  54. );
  55. $items['devel-token'] = array(
  56. 'description' => dt('List available tokens'),
  57. 'aliases' => array('token'),
  58. 'core' => array(7), // Remove once 3.0 is released.
  59. //@todo support --format option for json, csv, etc.
  60. );
  61. return $items;
  62. }
  63. /**
  64. * A command callback for reinstalling one or more projects.
  65. *
  66. * This is faster than 3 separate bootstraps.
  67. */
  68. function drush_devel_reinstall() {
  69. $projects = func_get_args();
  70. $args = array_merge(array('pm-disable'), $projects);
  71. call_user_func_array('drush_invoke', $args);
  72. $args = array_merge(array('pm-uninstall'), $projects);
  73. call_user_func_array('drush_invoke', $args);
  74. $args = array_merge(array('pm-enable'), $projects);
  75. call_user_func_array('drush_invoke', $args);
  76. }
  77. /**
  78. * A command callback for downloading a project.
  79. */
  80. function drush_devel_download($path = NULL) {
  81. // If no path is provided by the user, set our default path.
  82. if (is_null($path)) {
  83. // We use devel folder for legacy reason.
  84. $path = drupal_get_path('module', 'devel') . '/FirePHPCore';
  85. }
  86. // If FirePHP is not installed and libraries module is enabled,
  87. // try to find FirePHP by its own means.
  88. if (!is_dir($path)) {
  89. if (module_exists('libraries')) {
  90. // Libraries 1.x will return a path even if it doesn't exist
  91. // while 2.x will return FALSE.
  92. $path = libraries_get_path('FirePHPCore');
  93. if (!$path) {
  94. $path = 'sites/all/libraries/FirePHPCore';
  95. }
  96. }
  97. }
  98. if (is_dir($path)) {
  99. drush_log(dt('FirePHP already present at @path. No download required.', array('@path' => $path)), 'ok');
  100. }
  101. elseif (drush_shell_exec('svn export http://firephp.googlecode.com/svn/branches/Library-FirePHPCore-0.3 %s', $path)) {
  102. drush_log(dt('FirePHP has been exported via svn to @path.', array('@path' => $path)), 'success');
  103. }
  104. else {
  105. drush_log(dt('Drush was unable to export FirePHP to @path.', array('@path' => $path)), 'warning');
  106. }
  107. }
  108. /**
  109. * A command handler for showing hook implementations.
  110. */
  111. function drush_devel_fn_hook($hook) {
  112. // Get implementations in the .install files as well.
  113. include_once './includes/install.inc';
  114. drupal_load_updates();
  115. if ($hook_implementations = module_implements($hook)) {
  116. if ($choice = drush_choice(array_combine($hook_implementations, $hook_implementations), 'Enter the number of the hook implementation you wish to view.')) {
  117. return drush_devel_fn_view($choice . "_$hook");
  118. }
  119. }
  120. else {
  121. drush_log(dt('No implementations.'), 'ok');
  122. }
  123. }
  124. /**
  125. * A command handler for showing source code of a function or method.
  126. */
  127. function drush_devel_fn_view($function_name) {
  128. // Get implementations in the .install files as well.
  129. include_once './includes/install.inc';
  130. drupal_load_updates();
  131. if (strpos($function_name, '::') === FALSE) {
  132. if (!function_exists($function_name)) {
  133. return drush_set_error(dt('Function not found'));
  134. }
  135. $reflect = new ReflectionFunction($function_name);
  136. }
  137. else {
  138. list($class, $method) = explode('::', $function_name);
  139. if (!method_exists($class, $method)) {
  140. return drush_set_error(dt('Method not found'));
  141. }
  142. $reflect = new ReflectionMethod($class, $method);
  143. }
  144. $func_info = array('!file' => $reflect->getFileName(), '!startline' => $reflect->getStartLine(), '!endline' => $reflect->getEndLine());
  145. $format = drush_get_option('format', '!file');
  146. drush_print_pipe(dt($format, $func_info));
  147. drush_print(dt("// file: !file, lines !startline-!endline", $func_info));
  148. _drush_devel_print_function($reflect->getFileName(), $reflect->getStartLine(), $reflect->getEndLine());
  149. }
  150. /**
  151. * A command callback for listing available tokens.
  152. */
  153. function drush_devel_token() {
  154. $rows[] = array(dt('Group'), dt('Token'), dt('Name'));
  155. $all = token_info();
  156. foreach ($all['tokens'] as $group => $tokens) {
  157. foreach ($tokens as $key => $token) {
  158. $rows[] = array($group, $key, $token['name']);
  159. }
  160. }
  161. drush_print_table($rows, TRUE);
  162. }
  163. /**
  164. * Prints a function including any Doxygen-style comments preceding it.
  165. */
  166. function _drush_devel_print_function($file, $start_line, $end_line) {
  167. $line_num = 0;
  168. $doxygen = NULL;
  169. $fp = fopen( $file, 'r' );
  170. while (!feof($fp) && ($line_num < ($start_line - 1))) {
  171. $line = fgets($fp);
  172. ++$line_num;
  173. if (substr($line,0,3) == '/**') {
  174. $doxygen = $line;
  175. }
  176. elseif (isset($doxygen)) {
  177. $doxygen .= $line;
  178. if ($line_num + 1 == $start_line) {
  179. drush_print(rtrim($doxygen));
  180. }
  181. if (strstr($line, '*/') !== FALSE) {
  182. $doxygen = NULL;
  183. }
  184. }
  185. }
  186. while (!feof($fp) && ($line_num < $end_line)) {
  187. $line = fgets($fp);
  188. ++$line_num;
  189. drush_print(rtrim($line));
  190. }
  191. }