Index: includes/drush.inc =================================================================== RCS file: includes/drush.inc diff -N includes/drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/drush.inc 13 Jun 2007 13:35:41 -0000 @@ -0,0 +1,337 @@ + 'drush_callback_help', + 'description' => 'View help. Run "drush help command" to view command-specific help.' + ); + + $commands = $commands + module_invoke_all('drush_command', TRUE); + + return $commands; +} + +function drush_is_command($command) { + $commands = drush_get_commands(); + return (isset($commands[$command])) ? TRUE : FALSE; +} + +/** + * Calls a given function, passing through all arguments unchanged. + * + * This should be used when calling possibly mutative or destructive functions + * (e.g. unlink() and other file system functions) so that can be suppressed + * if the simulation mode is enabled. + * + * @param $function + * The name of the function. + * @return + * The return value of the function, or TRUE if simulation mode is enabled. + */ +function drush_op($function) { + $args = func_get_args(); + array_shift($args); // Skip function name + + if (DRUSH_VERBOSE || DRUSH_SIMULATE) { + drush_print("Calling $function(". implode(", ", $args) .')'); + } + + if (DRUSH_SIMULATE) { + return true; + } + + return call_user_func_array($function, $args); +} + +/** + * Executes a shell command. + * Output is only printed if in verbose mode. + * If in simulation mode, no action is taken. + * + * @param $cmd + * The command to execute. + * @param $indent + * Indentation for the output (only for verbose mode). + */ +function drush_shell_exec($cmd, $indent = 0) { + if (DRUSH_VERBOSE || DRUSH_SIMULATE) { + drush_print('Executing: ' . $cmd, $indent); + } + + if (DRUSH_SIMULATE) { + return true; + } + + exec($cmd . ' 2>&1', $output, $result); + + if (DRUSH_VERBOSE) { + foreach ($output as $line) { + drush_print($line, $indent + 2); + } + } + + // Exit code 0 means success. + return ($result == 0); +} + +/** + * Exits with a message. + * TODO: Exit with a correct status code. + */ +function drush_die($msg = NULL, $status = NULL) { + die($msg ? "drush: $msg\n" : ''); +} + +/** + * Prints an error message. + * Always returns FALSE. This allows to do e.g. + * if ($error) { return drush_error('A error occured); } + * to make your function return FALSE in case of an error. + */ +function drush_error($msg = '') { + // TODO: print to stderr if running in CLI mode. + drush_print("E: ". $msg); + return FALSE; +} + +/** + * Prints a message. + * @param $message + * The message to print. + * @param $indent + * The indentation (space chars) + */ +function drush_print($message = '', $indent = 0) { + print str_repeat(' ', $indent) . (string)$message . "\n"; +} + +/** + * Prints a message, but only if verbose mode is activated. + * Returns TRUE if in verbose mode, otherwise FALSE. + */ +function drush_verbose($msg = FALSE, $indent = 0) { + if (!DRUSH_VERBOSE) { + return FALSE; + } + if (DRUSH_VERBOSE && $msg === FALSE) { + return TRUE; + } + + print str_repeat(' ', $indent) . (string)$msg . "\n"; + return TRUE; +} + +/** + * Ask the user a basic yes/no question. + * + * @param $msg The question to ask + * @return TRUE if the user entered 'y', FALSE if he entered 'n' + */ +function drush_confirm($msg, $indent = 0) { + print str_repeat(' ', $indent) . (string)$msg . " (y/n): "; + + if (DRUSH_AFFIRMATIVE) { + print "y\n"; + return TRUE; + } + while ($line = trim(fgets(STDIN))) { + if ($line == 'y') { + return TRUE; + } + if ($line == 'n') { + return FALSE; + } + print str_repeat(' ', $indent) . (string)$msg . " (y/n): "; + } + +} + +/** + * Print a formatted table. + * @param $rows + * The rows to print + * @param $indent + * Indentation for the whole table + * @param $header + * If TRUE, the first line will be treated as table + * header and therefore be underlined. + */ +function drush_print_table($rows, $indent = 0, $header = FALSE) { + if (count($rows) == 0) { + // Nothing to output. + return; + } + + $indent = str_repeat(' ', $indent); + $format = _drush_get_table_row_format($rows); + + $header_printed = FALSE; + foreach ($rows as $cols) { + // Print the current line. + print $indent . vsprintf($format, $cols) . "\n"; + // Underline the first row if $header is set to true. + if (!$header_printed && $header) { + $headers = array(); + foreach ($cols as $col) { + $headers[] = str_repeat('-', strlen($col)); + } + print $indent . trim(vsprintf($format, $headers)) . "\n"; + $header_printed = TRUE; + } + } +} + +/** + * @} End of "defgroup drush". + */ + +/** + * Create the table row format string to be used in vsprintf(). + */ +function _drush_get_table_row_format($table) { + $widths = _drush_get_table_column_widths($table); + foreach ($widths as $col_width) { + $col_formats[] = "%-{$col_width}s"; + } + $format = implode("\t", $col_formats); + return $format; +} + +/** + * Calculate table column widths. + */ +function _drush_get_table_column_widths($table) { + $widths = array(); + foreach ($table as $row => $cols) { + foreach ($cols as $col => $value) { + $old_width = isset($widths[$col]) ? $widths[$col] : 0; + $widths[$col] = max($old_width, strlen((string)$value)); + } + } + return $widths; +} + +/** + * Command callback. Display help. + */ +function drush_callback_help() { + $commands = func_get_args(); + + // Display general help text if no command is specified. + if (empty($commands)) { + drush_print('drush ' . VERSION); + drush_print(t('Usage: drush [options] ...')); + drush_print(); + drush_print(t('Options: ')); + + // TODO: (?) Add a hook for this, to allow other modules to add their options + $rows[] = array('-r , --root=', t('Drupal root directory to use (default: current directory)')); + $rows[] = array('-l , --uri=', t('URI of the drupal site to use (only needed in multisite environments)')); + $rows[] = array('-u , --user=', t('Drupal user name (or numeric ID) to execute actions under.')); + $rows[] = array('-v, --verbose', t('Display all available output')); + $rows[] = array('-y, --yes', t("Assume 'yes' as answer to all prompts")); + $rows[] = array('-s, --simulate', t("Simulate all relevant actions (don't actually change the system)")); + + drush_print_table($rows, 2); + drush_print(); + drush_print('Commands: '); + + $commands = drush_get_commands(); + $rows = array(); + foreach ($commands as $key => $command) { + $rows[] = array($key, $commands[$key]['description']); + } + drush_print_table($rows, 2); + } + // Print command specific help. + else { + $commandstring = implode(" ", $commands); + + if (!drush_is_command($commandstring)) { + return drush_error(t('Invalid command !command.', array('!command' => implode(" ", $commands)))); + } + + $help = module_invoke_all('help', 'drush:'. $commandstring); + if (!empty($help)) { + drush_print(implode("\n", $help)); + } + else { + drush_print(t("No help available for command 'drush $commandstring'.")); + } + } +} + +/** + * This is called if no command or an unknown command is entered. + */ +function drush_usage() { + $commands = func_get_args(); + if (drush_get_option('version')) { + return drush_print('drush ' . VERSION); + } + + if (drush_get_option('help') || empty($commands)) { + return drush_callback_help(); + } + + return drush_error(t('Invalid command !command.', array('!command' => implode(" ", $commands)))); +} \ No newline at end of file Index: scripts/drush.bat =================================================================== RCS file: scripts/drush.bat diff -N scripts/drush.bat --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ scripts/drush.bat 13 Jun 2007 13:35:42 -0000 @@ -0,0 +1 @@ +@php.exe drush.php %1 %2 %3 %4 %5 %6 %7 %8 %9 Index: scripts/drush.php =================================================================== RCS file: scripts/drush.php diff -N scripts/drush.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ scripts/drush.php 13 Jun 2007 13:35:42 -0000 @@ -0,0 +1,252 @@ +#!/usr/bin/php + $drush_user) : array('name' => $drush_user)); + + if (empty($user)) { + if (is_numeric($drush_user)) { + drush_die(t('Could not login with user ID #%user.', array('%user' => $drush_user))); + } + else { + drush_die(t('Could not login with user account `%user\'.', array('%user' => $drush_user))); + } + return FALSE; + } + + return TRUE; +} + +/** + * Parse console arguments. + * + * @param $args + * The console argument array (usually $argv) + * @param $arg_opts + * An array of options that are followed by an argument. + * e.g. shell.php -u admin -v --> $arg_opts = array('u') + * @param $default_options + * @return + * A associative array: + * $return['commands'] ia a numeric array of all commands, + * $return['options'] contains the options. The option keys + * are always noted without - or -- and are set to TRUE if they were + * invoked, to the argument if followed by an argument, and if not present + * to their default value or FALSE if no default value was specified. + */ +function drush_parse_args($args = array(), $arg_opts = array(), $default_options = array()) { + $options = $default_options; + $commands = array(); + + for ($i = 1; $i < count($args); $i++) { + $opt = $args[$i]; + // Is the arg an option (starting with '-')? + if ($opt{0} == "-" && strlen($opt) != 1) { + // Do we have multiple options behind one '-'? + if (strlen($opt) > 2 && $opt{1} != "-") { + // Each char becomes a key of its own. + for ($j = 1; $j < strlen($opt); $j++) { + $options[substr($opt, $j, 1)] = true; + } + } + // Do we have a longopt (starting with '--')? + elseif ($opt{1} == "-") { + if ($pos = strpos($opt, '=')) { + $options[substr($opt, 2, $pos - 2)] = substr($opt, $pos + 1); + } + else { + $options[substr($opt, 2)] = true; + } + } + else { + $opt = substr($opt, 1); + // Check if the current opt is in $arg_opts (= has to be followed by an argument). + if ((in_array($opt, $arg_opts))) { + if (($args[$i+1] == NULL) || ($args[$i+1] == "") || ($args[$i + 1]{0} == "-")) { + exit("Invalid input: -$opt needs to be followed by an argument."); + } + $options[$opt] = $args[$i + 1]; + $i++; + } + else { + $options[$opt] = true; + } + } + } + // If it's not an option, it's a command. + else { + $commands[] = $opt; + } + } + return array('options' => $options, 'commands' => $commands); +} + +/** + * Get the value for an option. + * + * If the first argument is an array, then it checks wether one of the options + * exists and return the value of the first one found. Useful for allowing both + * -h and --host-name + * + */ +function drush_get_option($option, $default = NULL) { + $options = $GLOBALS['args']['options']; + if (is_array($option)) { + foreach ($option as $current) { + if (array_key_exists($current, $options)) { + return $options[$current]; + } + } + return $default; + } + + if (!array_key_exists($option, $options)) { + return $default; + } + else { + return $options[$option]; + } +} + +/** + * Converts a Windows path (dir1\dir2\dir3) into a Unix path (dir1/dir2/dir3). + */ +function drush_convert_path($path) { + return str_replace('\\','/', $path); +} + +?>