Index: drush.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush.php,v retrieving revision 1.60 diff -u -p -u -p -r1.60 drush.php --- drush.php 16 Apr 2009 02:48:43 -0000 1.60 +++ drush.php 29 Apr 2009 23:36:58 -0000 @@ -15,6 +15,8 @@ if (!drush_verify_cli()) { } define('DRUSH_BASE_PATH', dirname(__FILE__)); +define('DRUSH_COMMAND', $GLOBALS['argv'][0]); + require_once DRUSH_BASE_PATH . '/includes/environment.inc'; require_once DRUSH_BASE_PATH . '/includes/command.inc'; require_once DRUSH_BASE_PATH . '/includes/drush.inc'; @@ -23,6 +25,7 @@ require_once DRUSH_BASE_PATH . '/include drush_set_context('argc', $GLOBALS['argc']); drush_set_context('argv', $GLOBALS['argv']); + exit(drush_main()); /** @@ -57,7 +60,7 @@ function drush_main() { if (drush_bootstrap($phase)) { $command = drush_parse_command(); if (is_array($command)) { - if ($command['bootstrap'] == $phase) { + if ($command['bootstrap'] == $phase && empty($command['bootstrap_errors'])) { drush_log(dt("Found command: !command", array('!command' => $command['command'])), 'bootstrap'); // Dispatch the command(s). // After this point the drush_shutdown function will run, @@ -70,9 +73,18 @@ function drush_main() { break; } } - $args = implode(" ", drush_get_arguments()); - // If we reach this point, we have not found a valid command. - drush_set_error('DRUSH_COMMAND_NOT_FOUND', dt("The command 'drush.php !args' could not be executed.", array('!args' => $args))); + // If we reach this point, we have not found either a valid or matching command. + $args = implode(' ', drush_get_arguments()); + $drush_command = array_pop(explode('/', DRUSH_COMMAND)); + if ($command) { + foreach ($command['bootstrap_errors'] as $key => $error) { + drush_set_error($key, $error); + } + drush_set_error('DRUSH_COMMAND_NOT_EXECUTABLE', dt("The command '!drush_command !args' could not be executed.", array('!drush_command' => $drush_command, '!args' => $args))); + } + else { + drush_set_error('DRUSH_COMMAND_NOT_FOUND', dt("The command '!drush_command !args' could not be found.", array('!drush_command' => $drush_command, '!args' => $args))); + } } /** Index: commands/core/core.drush.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/core/core.drush.inc,v retrieving revision 1.22 diff -u -p -u -p -r1.22 core.drush.inc --- commands/core/core.drush.inc 24 Apr 2009 05:20:37 -0000 1.22 +++ commands/core/core.drush.inc 29 Apr 2009 23:36:58 -0000 @@ -127,7 +127,7 @@ function core_help() { if (empty($commands)) { drush_show_help(array('help')); $phases = _drush_bootstrap_phases(); - drush_print('Commands: '); + drush_print(dt('Commands: ')); $printed_rows = array(); $phase_index = DRUSH_BOOTSTRAP_DRUSH; @@ -150,7 +150,7 @@ function core_help() { $rows = array(); foreach($commands as $key => $command) { - if (!array_key_exists($key, $printed_rows)) { + if (!array_key_exists($key, $printed_rows) && empty($commands[$key]['bootstrap_errors'])) { $rows[$key] = array(sprintf("%-20s", $key), $commands[$key]['description']); } } Index: includes/backend.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/backend.inc,v retrieving revision 1.11 diff -u -p -u -p -r1.11 backend.inc --- includes/backend.inc 21 Apr 2009 16:55:55 -0000 1.11 +++ includes/backend.inc 29 Apr 2009 23:36:58 -0000 @@ -283,8 +283,7 @@ function _drush_backend_invoke($cmd, $da * A text string representing a fully escaped command. */ function _drush_backend_generate_command($command, &$data, $method = 'GET', $drush_path = null, $hostname = null, $username = null) { - - $drush_path = !is_null($drush_path) ? $drush_path : $_SERVER['argv'][0]; // Call own drush.php file. + $drush_path = !is_null($drush_path) ? $drush_path : DRUSH_COMMAND; // Call own drush.php file. $data['root'] = ($data['root']) ? $data['root'] : drush_get_context('DRUSH_DRUPAL_ROOT'); $data['uri'] = array_key_exists('uri', $data) ? $data['uri'] : drush_get_context('DRUSH_URI'); Index: includes/command.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/command.inc,v retrieving revision 1.27 diff -u -p -u -p -r1.27 command.inc --- includes/command.inc 17 Apr 2009 18:18:17 -0000 1.27 +++ includes/command.inc 29 Apr 2009 23:36:58 -0000 @@ -76,9 +76,6 @@ function drush_parse_args() { * Get a list of all implemented commands. * This invokes hook_drush_command(). * - * @param boolean - * If TRUE, the internal commands table will be rebuild. - * * @return * Associative array of currently active command descriptors. * @@ -91,19 +88,30 @@ function drush_get_commands() { $function = $commandfile . '_drush_command'; $result = $function(); foreach ((array)$result as $key => $command) { - // Add some defaults + // Add some defaults and normalize the command descriptor $command += array( + 'command' => $key, 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, 'commandfile' => $commandfile, 'path' => dirname($path), 'engines' => array(), // Helpful for drush_show_help(). + 'callback' => 'drush_command', + 'description' => NULL, + 'arguments' => array(), + 'options' => array(), + 'extras' => array(), + 'core' => array(), + 'scope' => 'site', + 'drupal dependencies' => array(), + 'drush dependencies' => array(), + 'bootstrap_errors' => array(), ); - // Filter out commands which are invalid for this bootstrap phase, core or have missing dependencies. - if (drush_enforce_requirement_bootstrap_phase($command) - && drush_enforce_requirement_core($command) - && drush_enforce_requirement_drupal_dependencies($command)) { - $commands[$key] = $command; - } + // Collect all the commands (without filtering) so we can match non-executable + // commands, and later explain why they are not executable. + drush_enforce_requirement_bootstrap_phase($command); + drush_enforce_requirement_core($command); + drush_enforce_requirement_drupal_dependencies($command); + $commands[$key] = $command; } } } @@ -150,27 +158,13 @@ function drush_parse_command() { $part = implode(" ", $args); if (isset($implemented[$part])) { $command = $implemented[$part]; - // Normalize command descriptor - $command += array( - 'command' => $part, - 'callback' => 'drush_command', - 'description' => NULL, - 'arguments' => array(), - 'options' => array(), - 'extras' => array(), - 'core' => array(), - 'scope' => 'site', - 'bootstrap' => NULL, - 'drupal dependencies' => array(), - 'drush dependencies' => array(), - ); } else { $arguments[] = array_pop($args); } } - // We have found a command that can be executed. Set the appropriate values. + // We have found a command that matches. Set the appropriate values. if ($command) { $arguments = array_reverse($arguments); @@ -528,17 +522,20 @@ function drush_scan_directory($dir, $mas * Check that a command is valid for the current bootstrap phase. * * @param $command - * Command to check + * Command to check. Any errors will be added to the 'bootstrap_errors' element. * * @return * TRUE if command is valid. */ -function drush_enforce_requirement_bootstrap_phase($command) { +function drush_enforce_requirement_bootstrap_phase(&$command) { $valid = array(); $current_phase = drush_get_context('DRUSH_BOOTSTRAP_PHASE'); if ($command['bootstrap'] == $current_phase) { return TRUE; } + // TODO: pprovide description text for each bootstrap level so we can give + // the user something more helpful and specific here. + $command['bootstrap_errors']['DRUSH_COMMAND_INSUFFICIENT_BOOTSTRAP'] = dt('Command !command needs a higher bootstrap level to run - you will need invoke drush from a more functional Drupal environment to run this command.', array('!command' => $command['command'])); } /** @@ -546,12 +543,12 @@ function drush_enforce_requirement_boots * dependencies. * * @param $command - * Command to check + * Command to check. Any errors will be added to the 'bootstrap_errors' element. * * @return * TRUE if command is valid. */ -function drush_enforce_requirement_drupal_dependencies($command) { +function drush_enforce_requirement_drupal_dependencies(&$command) { if (empty($command['drupal dependencies'])) { return TRUE; } @@ -562,19 +559,26 @@ function drush_enforce_requirement_drupa } } } + $command['bootstrap_errors']['DRUSH_COMMAND_DEPENDENCY_ERROR'] = dt('Command !command needs the following modules installed/enabled to run: !dependencies.', array('!command' => $command['command'], '!dependencies' => implode(', ', $command['drupal dependencies']))); } /** * Check that a command is valid for the current major version of core. * * @param $command - * Command to check + * Command to check. Any errors will be added to the 'bootstrap_errors' element. * * @return * TRUE if command is valid. */ -function drush_enforce_requirement_core($command) { - if (empty($command['core']) || in_array(drush_drupal_major_version(), $command['core'])) { +function drush_enforce_requirement_core(&$command) { + $core = $command['core']; + if (empty($core) || in_array(drush_drupal_major_version(), $core)) { return TRUE; } + $versions = array_pop($core); + if (!empty($core)) { + $versions = implode(', ', $core) . dt(' or ') . $versions; + } + $command['bootstrap_errors']['DRUSH_COMMAND_CORE_VERSION_ERROR'] = dt('Command !command requires Drupal core version !versions to run.', array('!command' => $command['command'], '!versions' => $versions)); } Index: includes/drush.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/includes/drush.inc,v retrieving revision 1.29 diff -u -p -u -p -r1.29 drush.inc --- includes/drush.inc 19 Apr 2009 03:56:32 -0000 1.29 +++ includes/drush.inc 29 Apr 2009 23:36:58 -0000 @@ -153,12 +153,12 @@ function drush_include_engine($type, $en $path = $engines[$engine]['path']; } if (!$path) { - return drush_set_error('DRUSH_ENGINE INCLUDE_NO_PATH', "No $path was set for including the $type engine $engine."); + return drush_set_error('DRUSH_ENGINE INCLUDE_NO_PATH', dt('No !path was set for including the !type engine !engine.', array('!path' => $path, '!type' => $type, '!engine' => $engine))); } if (drush_include($path, $engine, $version)) { return TRUE; } - return drush_set_error('DRUSH_ENGINE INCLUDE_FAILED', "Unable to include the $type engine $engine from $path."); + return drush_set_error('DRUSH_ENGINE INCLUDE_FAILED', dt('Unable to include the !type engine !engine from !path.' , array('!path' => $path, '!type' => $type, '!engine' => $engine))); } /**