? drush.decoupled.v3.DRUPAL-6--1.patch Index: README.txt =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/README.txt,v retrieving revision 1.15 diff -u -5 -p -u -p -r1.15 README.txt --- README.txt 26 Mar 2008 03:03:56 -0000 1.15 +++ README.txt 20 Nov 2008 02:55:10 -0000 @@ -14,30 +14,28 @@ for those. There are several modules tha this download. See Package Manager, SQL Tools, and Toolbox. INSTALLATION ------------ For Linux/Unix/Mac: - 1. Untar the tarball into your module directory (sites/all/modules) - 2. Enable drush.module and any submodules you want to use. You must enable the CVS or wget modules - if you want to install modules (you do). - 3. (optional, but recommended:) To ease the use of drush, + 1. Untar the tarball into a convenient folder (/path/to/drush) + 2. (optional, but recommended:) To ease the use of drush, - create a link to drush.php in a directory that is in your $PATH, e.g.: - $ ln /path/to/drush.php /usr/bin/drush + $ ln /path/to/drush/drush.php /usr/bin/drush OR - create an alias to drush.php: - $ alias drush='php modules/drush/drush.php' + $ alias drush='php /path/to/drush/drush.php' (this goes into .profile or .bash_aliases in your home folder) - 4. Start using drush by running "drush" from your Drupal root directory. + 3. Start using drush by running "drush" from your Drupal root directory. - (or, if you did not follow step 3, by running "./sites/all/modules/drush.php" - or navigating to sites/all/modules/drush and running "./drush.php" ) + (or, if you did not follow step 3, by running "/path/to/drush/drush.php" + or navigating to /path/to/drush and running "./drush.php" ) If you have troubles, try using the -l and -r flags when invoking drush.php. See below. For Windows (experimental!): - - Follow steps 1 and 2. Use drush by navigating to sites/all/modules/drush + - Follow step 1. Use drush by navigating to /path/to/drush and running 'drush.bat'. - Whenever the documentation or the help text refers to 'drush [option] ' or something similar, 'drush' has to be replaced by 'drush.bat'. - If drush.bat is not working for you, either add the directory in which your @@ -52,22 +50,23 @@ any Drupal directory: Use the 'help' command to get a list of available options and commands: $ drush help -Please note that drush requires a working drupal setup in order to function -correctly. So for multisite installations, you might need to use the -l or other command line -options just to get the help command to work: +For multisite installations, you might need to use the -l or other command line +options just to get drush to work: $ drush -l http://association.drupal.org/drupal help Related Options: -r , --root= Drupal root directory to use (default: current directory) -l , --uri= URI of the drupal site to use (only needed in multisite environments) -v, --verbose Display all available output -If you get tired of typing options all the time, you can add them to your drush.php alias or create a drushrc.php file. These provide additional options for your drush call. They provide great flexibility for a multi-site installation, for example. See example.drushrc.php. +If you get tired of typing options all the time, you can add them to your drush.php alias or +create a drushrc.php file. These provide additional options for your drush call. They provide +great flexibility for a multi-site installation, for example. See example.drushrc.php. REQUIREMENTS ------------ This version of drush is designed for Drupal 6.x running on a Unix/Linux platform. Index: drush.drush.inc =================================================================== RCS file: drush.drush.inc diff -N drush.drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drush.drush.inc 20 Nov 2008 02:55:10 -0000 @@ -0,0 +1,95 @@ + 'drush_callback_help', + 'description' => 'View help. Run "drush help [command]" to view command-specific help.' + ); + return $items; +} + +/** + * Get the available options for Drush. + * + * @return + * An associative array containing the option definition as the key, and the description as the value, + * for each of the available options. + */ +function drush_get_options() { + // TODO: Add a hook for this, to allow other modules to add their options + $options['-r , --root='] = t("Drupal root directory to use (default: current directory)"); + $options['-l , --uri='] = t('URI of the drupal site to use (only needed in multisite environments)'); + $options['-v, --verbose'] = t('Display all available output'); + $options['-y, --yes'] = t("Assume 'yes' as answer to all prompts"); + $options['-s, --simulate'] = t("Simulate all relevant actions (don't actually change the system)"); + $options['-i, --include'] = t("A list of paths to search for drush commands"); + $options['-c, --config'] = t("Specify a config file to use. See example.drushrc.php"); + return $options; +} + +/** + * 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(t('Usage: drush.php [options] ...')); + drush_print(); + drush_print(t('Options: ')); + foreach (drush_get_options() as $option => $description) { + $rows[] = array($option, $description); + } + + 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('help') || empty($commands)) { + return drush_callback_help(); + } + + return drush_error(t('Invalid command !command.', array('!command' => implode(" ", $commands)))); + +} Index: drush.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush.inc,v retrieving revision 1.16 diff -u -5 -p -u -p -r1.16 drush.inc --- drush.inc 19 May 2008 01:31:57 -0000 1.16 +++ drush.inc 20 Nov 2008 02:55:10 -0000 @@ -4,10 +4,13 @@ /** * @file * The drush API implementation and helpers. */ +// Load the drush module engine. +require_once(dirname(__FILE__) . '/module.inc'); + /** * Dispatch a given set of commands. * Modules can add commands by implementing hook_drush_command(). */ function drush_dispatch($commands) { @@ -48,11 +51,11 @@ function drush_get_commands($refresh = F if (!$refresh && !empty($commands)) { return $commands; } - $commands = module_invoke_all('drush_command', TRUE); + $commands = drush_module_invoke_all('drush_command', TRUE); return $commands; } function drush_is_command($command) { Index: drush.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush.module,v retrieving revision 1.7 diff -u -5 -p -u -p -r1.7 drush.module --- drush.module 1 Feb 2008 21:56:08 -0000 1.7 +++ drush.module 20 Nov 2008 02:55:10 -0000 @@ -4,10 +4,11 @@ /** * @file * drush (the drupal shell) provides a command line interface for Drupal. */ +include_once('drush.drush.inc'); /** * Implementation of hook_help() */ function drush_help($section) { @@ -47,91 +48,5 @@ function drush_help($section) { } } -/** - * Implementation of hook_drush_command(). - */ -function drush_drush_command() { - $items['help'] = array( - 'callback' => 'drush_callback_help', - 'description' => 'View help. Run "drush help [command]" to view command-specific help.' - ); - return $items; -} - -/** - * Get the available options for Drush. - * - * @return - * An associative array containing the option definition as the key, and the description as the value, - * for each of the available options. - */ -function drush_get_options() { - // TODO: Add a hook for this, to allow other modules to add their options - $options['-r , --root='] = t("Drupal root directory to use (default: current directory)"); - $options['-l , --uri='] = t('URI of the drupal site to use (only needed in multisite environments)'); - $options['-v, --verbose'] = t('Display all available output'); - $options['-y, --yes'] = t("Assume 'yes' as answer to all prompts"); - $options['-s, --simulate'] = t("Simulate all relevant actions (don't actually change the system)"); - $options['-c, --config'] = t("Specify a config file to use. See example.drushrc.php"); - return $options; -} - -/** - * 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(t('Usage: drush.php [options] ...')); - drush_print(); - drush_print(t('Options: ')); - foreach (drush_get_options() as $option => $description) { - $rows[] = array($option, $description); - } - - 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('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: drush.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush.php,v retrieving revision 1.24.2.3 diff -u -5 -p -u -p -r1.24.2.3 drush.php --- drush.php 18 Nov 2008 01:07:49 -0000 1.24.2.3 +++ drush.php 20 Nov 2008 02:55:10 -0000 @@ -241,20 +241,11 @@ function _drush_bootstrap_drupal() { } // The bootstrap can fail silently, so we catch that in a shutdown function. register_shutdown_function('drush_shutdown'); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); - if (module_exists('drush')) { - require_once drupal_get_path('module', 'drush') . '/drush.inc'; - } - else { - $message = "E: You must enable the Drush module for the site you want to use.\n"; - $message .= "Hint: Drush was looking in the site '$conf_path'. You can select another site\n"; - $message .= "with Drush enabled by specifying the Drupal URI to use with the --uri\n"; - $message .= "parameter on the command line or \$options['uri'] in your drushrc.php file.\n"; - die($message); - } + require_once dirname(__FILE__) . '/drush.inc'; } function drush_shutdown() { if (!function_exists('drupal_set_content')) { $message = "E: Drush was not able to start (bootstrap) Drupal.\n"; Index: example.drushrc.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/example.drushrc.php,v retrieving revision 1.5.2.1 diff -u -5 -p -u -p -r1.5.2.1 example.drushrc.php --- example.drushrc.php 14 Nov 2008 22:08:56 -0000 1.5.2.1 +++ example.drushrc.php 20 Nov 2008 02:55:10 -0000 @@ -16,10 +16,13 @@ // $options['l'] = 'http://example.com/subir'; // specify your Drupal core base directory (useful if you use symlinks) // $options['r'] = '/home/USER/workspace/drupal-6'; +// specify additional directories to search for *.drush.inc files +// $options['i'] = 'sites/default:profiles/myprofile'; + // enable verbose mode // $options['v'] = 1; /* * Customize this associative array with your own tables. This is the Index: module.inc =================================================================== RCS file: module.inc diff -N module.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ module.inc 20 Nov 2008 02:55:10 -0000 @@ -0,0 +1,180 @@ + $info) { + require_once($filename); + $list[] = basename($filename, '.drush.inc'); + } + } + } + return $list; +} + +/** + * Determine whether a module implements a hook. + * + * @param $module + * The name of the module (without the .module extension). + * @param $hook + * The name of the hook (e.g. "help" or "menu"). + * @return + * TRUE if the the hook is implemented. + */ +function drush_module_hook($module, $hook) { + return function_exists($module .'_'. $hook); +} + + +/** + * Finds all files that match a given mask in a given directory. + * Directories and files beginning with a period are excluded; this + * prevents hidden files and directories (such as SVN working directories) + * from being scanned. + * + * @param $dir + * The base directory for the scan, without trailing slash. + * @param $mask + * The regular expression of the files to find. + * @param $nomask + * An array of files/directories to ignore. + * @param $callback + * The callback function to call for each match. + * @param $recurse + * When TRUE, the directory scan will recurse the entire tree + * starting at the provided directory. + * @param $key + * The key to be used for the returned array of files. Possible + * values are "filename", for the path starting with $dir, + * "basename", for the basename of the file, and "name" for the name + * of the file without an extension. + * @param $min_depth + * Minimum depth of directories to return files from. + * @param $depth + * Current depth of recursion. This parameter is only used internally and should not be passed. + * + * @return + * An associative array (keyed on the provided key) of objects with + * "path", "basename", and "name" members corresponding to the + * matching files. + */ +function drush_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0) { + $key = (in_array($key, array('filename', 'basename', 'name')) ? $key : 'filename'); + $files = array(); + + if (is_dir($dir) && $handle = opendir($dir)) { + while (FALSE !== ($file = readdir($handle))) { + if (!in_array($file, $nomask) && $file[0] != '.') { + if (is_dir("$dir/$file") && $recurse) { + // Give priority to files in this folder by merging them in after any subdirectory files. + $files = array_merge(drush_scan_directory("$dir/$file", $mask, $nomask, $callback, $recurse, $key, $min_depth, $depth + 1), $files); + } + elseif ($depth >= $min_depth && ereg($mask, $file)) { + // Always use this match over anything already set in $files with the same $$key. + $filename = "$dir/$file"; + $basename = basename($file); + $name = substr($basename, 0, strrpos($basename, '.')); + $files[$$key] = new stdClass(); + $files[$$key]->filename = $filename; + $files[$$key]->basename = $basename; + $files[$$key]->name = $name; + if ($callback) { + $callback($filename); + } + } + } + } + + closedir($handle); + } + + return $files; +} Index: drush_pm/drush_pm.drush.inc =================================================================== RCS file: drush_pm/drush_pm.drush.inc diff -N drush_pm/drush_pm.drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drush_pm/drush_pm.drush.inc 20 Nov 2008 02:55:10 -0000 @@ -0,0 +1,547 @@ + 'drush_pm_install', + 'description' => 'Install one or more modules' + ); + $items['pm refresh'] = array( + 'callback' => 'drush_pm_refresh', + 'description' => 'Refresh update status information' + ); + $items['pm update'] = array( + 'callback' => 'drush_pm_update', + 'description' => 'Update your modules' + ); + $items['pm info'] = array( + 'callback' => 'drush_pm_info', + 'description' => 'Release information for a module' + ); + return $items; +} + + +/** + * Parse out the project name and version and return as a structured array + * + * @param $requests an array of project names + */ +function drush_pm_parse_project_version($requests) { + $requestdata = array(); + foreach($requests as $request) { + // project-HEAD or project-5.x-1.0-beta + // '5.x-' is optional, as is '-beta' + preg_match('/-(HEAD|(\d+)\.([\dx]+)(-.+)?)$/', $request, $matches); + if ($matches[0]) { + // Specific version requested + $version = $matches[0]; + $project = substr($request, 0, strlen($request) - strlen($version)); + } + else { + // Recommended stable version requested + $project = $request; + } + if (empty($project)) { + drush_die(t("Project name not found.\n\nRun drush help pm install for more information.")); + } + $requestdata[$project] = array( + 'name' => $project, + 'version' => trim($version, ' -'), + ); + } + return $requestdata; +} + +/** + * Command callback. Installs one or more packages (so far only modules). + */ +function drush_pm_install() { + $requests = func_get_args(); + if (empty($requests)) { + drush_die(t("No project specified.\n\nRun drush help pm install for more information.")); + } + + // Parse out project name and version + $requests = drush_pm_parse_project_version($requests); + + // If a URI is provided then we install to that specific site, otherwise we install to sites/all/modules + if (DRUSH_URI) { + $path = conf_path(); + $modulepath = DRUSH_DRUPAL_ROOT .'/'. $path .'/modules/'; + } + + if (!isset($modulepath) || !file_exists($modulepath)) { + $modulepath = DRUSH_DRUPAL_ROOT .'/sites/all/modules/'; + } + + // Get the module info from drupal.org via xml-rpc + $releases = drush_pm_get_project_info($requests); + if (!$releases) { + drush_die(t("None of the given projects exists or has releases that are compatible with your Drupal version.")); + } + + $startdir = getcwd(); + + $package_handler = drush_pm_get_package_handler() .'_install_project'; + if (!function_exists($package_handler)) { + drush_die(t("The $package_handler package handler does not handle installs.")); + } + + // Download and install each module + foreach($requests as $project => $request) { + if (isset($releases[$project]) && $release = drush_pm_get_release($request, $releases[$project])) { + if (is_dir($modulepath . $project)) { + drush_error(t('Project !project is already installed. Skipping.', array('!project' => $project))); + } + elseif ($package_handler($project, $release, $modulepath)) { + drush_print(t("Project !project successfully installed (version !version).", + array('!project' => $project, '!version' => $release['version']))); + module_invoke_all('drush_pm_post_install', $project, $release, $modulepath); + } + } + else { + drush_error(t('Project !project doesn\' exist or has no releases that are compatible with your Drupal version. Skipping.', array('!project' => $project))); + } + } + + drush_op('chdir', $startdir); +} + +/** + * Command callback. Displays update status info and allows to update installed modules. + * Pass specific projects as arguments, otherwise we update all that have candidate releases. + * + * This command prompts for confirmation before updating, so it is safe to run just to check on + * In this case, say at the confirmation prompt. + */ +function drush_pm_update() { + // Get update status information. + $releases = _drush_pm_get_update_info(); + + // Get specific requests + $requests = func_get_args(); + + // Parse out project name and version + $requests = drush_pm_parse_project_version($requests); + + // Preprocess releases + if (!empty($requests)) { + // Force update projects where a specific version is reqested + foreach ($requests as $project => $request) { + if (!empty($request['version'])) { + // Match the requested release + $release = drush_pm_get_release($request, $releases[$project]); + if ($release['version'] == $releases[$project]['existing_version']) { + $releases[$project]['status'] = DRUSH_PM_REQUESTED_CURRENT; + } + else { + $releases[$project]['status'] = DRUSH_PM_REQUESTED_UPDATE; + } + // Set the candidate version to the requested release + $releases[$project]['candidate_version'] = $release['version']; + } + } + } + + // Table headers. + $rows[] = array(t('Name'), t('Installed version'), t('Recommended version'), t('Status')); + + // Process releases, notifying user of status and building a list of proposed updates + $updateable = array(); + foreach ($releases as $release) { + if (!$release['title']) { + continue; + } + + switch($release['status']) { + case UPDATE_CURRENT: + $status = t('Up to date'); + $release['candidate_version'] = $release['recommended']; + break; + case UPDATE_NOT_CURRENT: + $status = t('Update available'); + $release['candidate_version'] = $release['recommended']; + $updateable[$release['name']] = $release; + break; + case UPDATE_NOT_SECURE: + $status = t('SECURITY UPDATE available'); + $release['candidate_version'] = $release['recommended']; + $updateable[$release['name']] = $release; + break; + case UPDATE_REVOKED: + $status = t('Intalled version REVOKED'); + $release['candidate_version'] = $release['recommended']; + $updateable[$project['name']] = $release; + break; + case DRUSH_PM_REQUESTED_UPDATE: + $status = t('Specified version available'); + $updateable[$release['name']] = $release; + break; + case DRUSH_PM_REQUESTED_CURRENT: + $status = t('Specified version already installed'); + break; + case UPDATE_NOT_SUPPORTED: + $status = t('Installed version not supported'); + $release['candidate_version'] = $release['recommended']; + $updateable[$project['name']] = $release; + break; + case UPDATE_NOT_CHECKED: + $status = t('Unable to check status'); + break; + case UPDATE_UNKNOWN: + default: + $status = t('Unknown'); + break; + } + + $rows[] = array($release['title'], $release['existing_version'], $release['candidate_version'], $status); + } + + $last = variable_get('update_last_check', 0); + drush_print(t('Update information last refreshed: ') . ($last ? format_date($last) : t('Never'))); + drush_print(); + drush_print(t("Update status information on all installed and enabled Drupal modules:")); + drush_print_table($rows, 2, TRUE); + drush_print(); + + // If specific project updates were requested then remove releases for all others + if (!empty($requests)) { + foreach ($updateable as $project => $release) { + if (!isset($requests[$project])) { + unset($updateable[$project]); + } + } + } + + if (empty($updateable)) { + drush_die(t('No updates available.')); + } + + // Offer to update to the identified releases + drush_pm_update_packages($updateable); +} + +/** + * Update packages according to an array of releases, following interactive + * confirmation from the user. + * + * @param $releases + * An array of releases from the drupal.org update service, with an additional + * array key candidate_version that specifies the version to be installed. + */ +function drush_pm_update_packages($releases) { + if (isset($releases['drupal'])) { + drush_print("NOTE: An update for the Drupal core is available. \nDrupal itself can't yet be updated by this tool. Please update Drupal manually.\n"); + unset($releases['drupal']); + } + + drush_print(t('Updates will be made to the following projects:')); + foreach($releases as $release) { + $print .= $release['title'] . " [" . $release['name'] . '-' . $release['candidate_version'] . "], "; + } + drush_print(substr($print, 0, strlen($print)-2)); + drush_print(); + drush_print(t("Note: Updated modules can potentially break your site. It's not recommended to update production sites without prior testing.")); + if (module_exists('drush_pm_svn')) { + drush_print(t("Note: A backup of your package will be stored to backups directory if no .svn directory is found.")); + } + drush_print(t('Note: If you have made any modifications to any file that belongs to one of these projects, you will have to migrate those modifications after updating.')); + if(!drush_confirm(t('Do you really want to continue?'))) { + drush_die('Aborting.'); + } + + $package_handler = drush_pm_get_package_handler() .'_update_project'; + if (!function_exists($package_handler)) { + drush_die(t("The $package_handler package handler does not handle updates.")); + } + + // Save the date to be used in the backup directory's path name. + $date = date('YmdHis'); + + // Now we start the actual updating. + foreach($releases as $release) { + drush_verbose(t('Starting to update !project ...', array('!project' => $release['title']))); + + $source = DRUSH_DRUPAL_ROOT .'/' . $release['path']; + + $skip_backup = module_invoke_all('drush_pm_skip_backup', $source); + if (!count($skip_backup)) { + $backup_dir = DRUSH_DRUPAL_ROOT. '/backup'; + drush_op('mkdir', $backup_dir, 0777); + $backup_dir .= '/modules'; + drush_op('mkdir', $backup_dir, 0777); + $backup_dir .= "/$date"; + drush_op('mkdir', $backup_dir, 0777); + $backup_target = $backup_dir . '/'. $release['name']; + if (!drush_op('rename', $source, $backup_target)) { + drush_die(t('Failed to backup project directory !source to !backup_target', array('!source' => $source, '!backup_target' => $backup_target))); + } + } + + // Install the new version. + // $basepath is the dir where the current module is installed. It's one dir up from the + // place of the project's info files. + $basepath = explode('/', $release['path']); + // move a directory up, so we can copy updated dir to parent + array_pop($basepath); + $project_parent_path = DRUSH_DRUPAL_ROOT. '/'. implode('/', $basepath). '/'; + if (!$package_handler($release['name'], $release['releases'][$release['candidate_version']], $project_parent_path)) { + if (!count($skip_backup)) { + drush_error(t('Updating project !project failed. Restoring previously installed version.', array('!project' => $release['name']))); + drush_op('rename', $backup_target, $source); + } + else { + drush_error(t('Updating project !project failed. Please revert to the previously installed version.', array('!project' => $release['name']))); + } + } + else { + drush_print(t('Project !project was updated successfully. Installed version is now !version.', array('!project' => $release['name'], '!version' => $release['candidate_version']))); + module_invoke_all('drush_pm_post_update', $release['name'], $release['releases'][$release['candidate_version']], $project_parent_path); + } + } + if ($backup_dir) { + drush_print(t("Backups were saved into the directory !backup_dir.", array('!backup_dir' => $backup_dir))); + } + drush_print(t("You should now run update.php through your browser.")); +} + +/** + * Find a module handler + */ +function drush_pm_get_package_handler() { + $package_handlers = module_invoke_all('drush_pm_package_handler'); + + if (empty($package_handlers)) { + drush_die(t("No package handlers found.")); + } + + $handler = drush_get_option('handler'); + // See if we have the full handler provided + if (array_search($handler, $package_handlers)) { + return $handler; + } + // Allow a shortcut for any functions named drush_pm_* + if (array_search('drush_pm_'. $handler, $package_handlers)) { + return 'drush_pm_'. $handler; + } + + // Fallback on the first provided handler (from the lightest module) + return $package_handlers[0]; +} + +/** + * Get update information for all installed projects. + * + * @return An array containing remote and local versions for all installed projects + */ +function _drush_pm_get_update_info($projects = NULL) { + $info = update_get_available(); + $data = update_calculate_project_data($info); + $data = drush_pm_get_project_path($data); + return $data; +} + +/** + * Command callback. Refresh update status information. + */ +function drush_pm_refresh() { + drush_print(t("Refreshing update status information ...")); + update_refresh(); + drush_print(t("Done.")); +} + +/** + * Get project information from drupal.org. + * + * @param $projects An array of project names + */ +function drush_pm_get_project_info($projects) { + $info = array(); + $data = array(); + foreach ($projects as $project_name => $project) { + $url = UPDATE_DEFAULT_URL. "/$project_name/". DRUPAL_CORE_COMPATIBILITY; + $xml = drupal_http_request($url); + $data[] = $xml->data; + } + if ($data) { + include_once drupal_get_path('module', 'update') .'/update.fetch.inc'; + $parser = new update_xml_parser; + $info = $parser->parse($data); + } + return $info; +} + +/** + * Get the recommended release for a certain so far uninstalled project. + * + * @param $project A project information array for the requested project + * @param $info A project information array for this project, as returned by an update service from drush_pm_get_project_info() + */ +function drush_pm_get_release($project, $info) { + $minor = ''; + $version_patch_changed = ''; + + if ($project['version']) { + // The user specified a specific version - try to find that exact version + foreach($info['releases'] as $version => $release) { + // Ignore unpublished releases. + if ($release['status'] != 'published') { + continue; + } + + // Straight match + if (!isset($recommended_version) && $release['version'] == $project['version']) { + $recommended_version = $version; + } + // Shortcut match with ommitted Drupal version + if (!isset($recommended_version) && $release['version'] == DRUPAL_CORE_COMPATIBILITY .'-'. $project['version']) { + $recommended_version = $version; + } + } + } + else { + // No version specified - try to find the best version we can + foreach($info['releases'] as $version => $release) { + // Ignore unpublished releases. + if ($release['status'] != 'published') { + continue; + } + + // If we haven't found a recommended version yet, put the dev + // version as recommended and hope it gets overwritten later. + // Look for the 'latest version' if we haven't found it yet. + // Latest version is defined as the most recent version for the + // default major version. + if (!isset($latest_version) && $release['version_major'] == $info['default_major']) { + $latest_version = $version; + } + + if (!isset($recommended_version) && $release['version_major'] == $info['default_major']) { + if ($minor != $release['version_patch']) { + $minor = $release['version_patch']; + $version_patch_changed = $version; + } + if (empty($release['version_extra']) && $minor == $release['version_patch']) { + $recommended_version = $version_patch_changed; + } + continue; + } + } + } + + if (isset($recommended_version)) { + return $info['releases'][$recommended_version]; + } + else if (isset($latest_version)) { + return $info['releases'][$latest_version]; + } + else { + return false; + } +} + +/** + * We need to set the project path by looking at the module location. Ideally, update.module would do this for us. + */ +function drush_pm_get_project_path($projects) { + foreach ($projects as $project => $info) { + if (!isset($info['path']) && $project != 'drupal') { + // looks for an enabled module. + foreach ($info['includes'] as $module => $name) { + if ($path = drupal_get_path('module', $module)) { + continue; + } + } + // As some modules are not located in their project's root directory + // but in a subdirectory (e.g. all the ecommerce modules), we take the module's + // info file's path, and then move up until we are at a directory with the + // project's name. + $parts = explode('/', $path); + $i = count($parts) - 1; + $stop = array_search($project, $parts); + while ($i > $stop) { + unset($parts[$i]); + $i--; + } + $projects[$project]['path'] = implode('/', $parts); + } + } + return $projects; +} + +/** + * A drush command callback. Show release info for given project(s). + * + **/ +function drush_pm_info() { + $projects = func_get_args(); + $projects = drupal_map_assoc($projects); + $info = drush_pm_get_project_info($projects); + + $rows[] = array(t('Project'), t('Release'), t('Date')); + foreach ($info as $key => $project) { + foreach ($project['releases'] as $release) { + + $rows[] = array( + $key, + $release['version'], + format_date($release['date'], 'custom', 'Y-M-d'), + ); + } + } + return drush_print_table($rows, FALSE, TRUE); +} + +/** + * Deletes a directory, all files in it and all subdirectories in it (recursively). + * Use with care! + * Written by Andreas Kalsch + */ +function delete_dir($dir) { + if (substr($dir, strlen($dir)-1, 1) != '/') + $dir .= '/'; + + if ($handle = opendir($dir)) { + while ($obj = readdir($handle)) { + if ($obj != '.' && $obj != '..') { + if (is_dir($dir.$obj)) { + if (!delete_dir($dir.$obj)) { + return false; + } + } + elseif (is_file($dir.$obj)) { + if (!unlink($dir.$obj)) { + return false; + } + } + } + } + + closedir($handle); + + if (!@rmdir($dir)) { + return false; + } + return true; + } + return false; +} + + Index: drush_pm/drush_pm.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush_pm/drush_pm.module,v retrieving revision 1.25.2.4 diff -u -5 -p -u -p -r1.25.2.4 drush_pm.module --- drush_pm/drush_pm.module 15 Nov 2008 03:37:32 -0000 1.25.2.4 +++ drush_pm/drush_pm.module 20 Nov 2008 02:55:10 -0000 @@ -11,19 +11,11 @@ * - Version: a requested version, such as 1.0 or 1.x-dev. * - Release: a specific release of a project, with associated metadata (from the drupal.org update service). * - Package: the collection of files that make up a release. */ -/** - * Project is a user requested version update. - */ -define('DRUSH_PM_REQUESTED_UPDATE', 101); - -/** - * User requested version already installed. - */ -define('DRUSH_PM_REQUESTED_CURRENT', 102); +include_once('drush_pm.drush.inc'); /** * Implementation of hook_help(). */ function drush_pm_help($section) { @@ -64,33 +56,10 @@ Use the -y option to answer all question View all releases for a given project. Useful for deciding which version to install/update. "); } } -/** - * Implementation of hook_drush_command(). - */ -function drush_pm_drush_command() { - $items['pm install'] = array( - 'callback' => 'drush_pm_install', - 'description' => 'Install one or more modules' - ); - $items['pm refresh'] = array( - 'callback' => 'drush_pm_refresh', - 'description' => 'Refresh update status information' - ); - $items['pm update'] = array( - 'callback' => 'drush_pm_update', - 'description' => 'Update your modules' - ); - $items['pm info'] = array( - 'callback' => 'drush_pm_info', - 'description' => 'Release information for a module' - ); - return $items; -} - function drush_pm_requirements($phase) { switch ($phase) { case 'runtime': $package_handlers = module_invoke_all('drush_pm_package_handler'); $requirements['handlers'] = array( @@ -100,513 +69,6 @@ function drush_pm_requirements($phase) { ); break; } return is_array($requirements) ? $requirements : array(); } - -/** - * Parse out the project name and version and return as a structured array - * - * @param $requests an array of project names - */ -function drush_pm_parse_project_version($requests) { - $requestdata = array(); - foreach($requests as $request) { - // project-HEAD or project-5.x-1.0-beta - // '5.x-' is optional, as is '-beta' - preg_match('/-(HEAD|(\d+)\.([\dx]+)(-.+)?)$/', $request, $matches); - if ($matches[0]) { - // Specific version requested - $version = $matches[0]; - $project = substr($request, 0, strlen($request) - strlen($version)); - } - else { - // Recommended stable version requested - $project = $request; - } - if (empty($project)) { - drush_die(t("Project name not found.\n\nRun drush help pm install for more information.")); - } - $requestdata[$project] = array( - 'name' => $project, - 'version' => trim($version, ' -'), - ); - } - return $requestdata; -} - -/** - * Command callback. Installs one or more packages (so far only modules). - */ -function drush_pm_install() { - $requests = func_get_args(); - if (empty($requests)) { - drush_die(t("No project specified.\n\nRun drush help pm install for more information.")); - } - - // Parse out project name and version - $requests = drush_pm_parse_project_version($requests); - - // If a URI is provided then we install to that specific site, otherwise we install to sites/all/modules - if (DRUSH_URI) { - $path = conf_path(); - $modulepath = DRUSH_DRUPAL_ROOT .'/'. $path .'/modules/'; - } - - if (!isset($modulepath) || !file_exists($modulepath)) { - $modulepath = DRUSH_DRUPAL_ROOT .'/sites/all/modules/'; - } - - // Get the module info from drupal.org via xml-rpc - $releases = drush_pm_get_project_info($requests); - if (!$releases) { - drush_die(t("None of the given projects exists or has releases that are compatible with your Drupal version.")); - } - - $startdir = getcwd(); - - $package_handler = drush_pm_get_package_handler() .'_install_project'; - if (!function_exists($package_handler)) { - drush_die(t("The $package_handler package handler does not handle installs.")); - } - - // Download and install each module - foreach($requests as $project => $request) { - if (isset($releases[$project]) && $release = drush_pm_get_release($request, $releases[$project])) { - if (is_dir($modulepath . $project)) { - drush_error(t('Project !project is already installed. Skipping.', array('!project' => $project))); - } - elseif ($package_handler($project, $release, $modulepath)) { - drush_print(t("Project !project successfully installed (version !version).", - array('!project' => $project, '!version' => $release['version']))); - module_invoke_all('drush_pm_post_install', $project, $release, $modulepath); - } - } - else { - drush_error(t('Project !project doesn\' exist or has no releases that are compatible with your Drupal version. Skipping.', array('!project' => $project))); - } - } - - drush_op('chdir', $startdir); -} - -/** - * Command callback. Displays update status info and allows to update installed modules. - * Pass specific projects as arguments, otherwise we update all that have candidate releases. - * - * This command prompts for confirmation before updating, so it is safe to run just to check on - * In this case, say at the confirmation prompt. - */ -function drush_pm_update() { - // Get update status information. - $releases = _drush_pm_get_update_info(); - - // Get specific requests - $requests = func_get_args(); - - // Parse out project name and version - $requests = drush_pm_parse_project_version($requests); - - // Preprocess releases - if (!empty($requests)) { - // Force update projects where a specific version is reqested - foreach ($requests as $project => $request) { - if (!empty($request['version'])) { - // Match the requested release - $release = drush_pm_get_release($request, $releases[$project]); - if ($release['version'] == $releases[$project]['existing_version']) { - $releases[$project]['status'] = DRUSH_PM_REQUESTED_CURRENT; - } - else { - $releases[$project]['status'] = DRUSH_PM_REQUESTED_UPDATE; - } - // Set the candidate version to the requested release - $releases[$project]['candidate_version'] = $release['version']; - } - } - } - - // Table headers. - $rows[] = array(t('Name'), t('Installed version'), t('Recommended version'), t('Status')); - - // Process releases, notifying user of status and building a list of proposed updates - $updateable = array(); - foreach ($releases as $release) { - if (!$release['title']) { - continue; - } - - switch($release['status']) { - case UPDATE_CURRENT: - $status = t('Up to date'); - $release['candidate_version'] = $release['recommended']; - break; - case UPDATE_NOT_CURRENT: - $status = t('Update available'); - $release['candidate_version'] = $release['recommended']; - $updateable[$release['name']] = $release; - break; - case UPDATE_NOT_SECURE: - $status = t('SECURITY UPDATE available'); - $release['candidate_version'] = $release['recommended']; - $updateable[$release['name']] = $release; - break; - case UPDATE_REVOKED: - $status = t('Intalled version REVOKED'); - $release['candidate_version'] = $release['recommended']; - $updateable[$project['name']] = $release; - break; - case DRUSH_PM_REQUESTED_UPDATE: - $status = t('Specified version available'); - $updateable[$release['name']] = $release; - break; - case DRUSH_PM_REQUESTED_CURRENT: - $status = t('Specified version already installed'); - break; - case UPDATE_NOT_SUPPORTED: - $status = t('Installed version not supported'); - $release['candidate_version'] = $release['recommended']; - $updateable[$project['name']] = $release; - break; - case UPDATE_NOT_CHECKED: - $status = t('Unable to check status'); - break; - case UPDATE_UNKNOWN: - default: - $status = t('Unknown'); - break; - } - - $rows[] = array($release['title'], $release['existing_version'], $release['candidate_version'], $status); - } - - $last = variable_get('update_last_check', 0); - drush_print(t('Update information last refreshed: ') . ($last ? format_date($last) : t('Never'))); - drush_print(); - drush_print(t("Update status information on all installed and enabled Drupal modules:")); - drush_print_table($rows, 2, TRUE); - drush_print(); - - // If specific project updates were requested then remove releases for all others - if (!empty($requests)) { - foreach ($updateable as $project => $release) { - if (!isset($requests[$project])) { - unset($updateable[$project]); - } - } - } - - if (empty($updateable)) { - drush_die(t('No updates available.')); - } - - // Offer to update to the identified releases - drush_pm_update_packages($updateable); -} - -/** - * Update packages according to an array of releases, following interactive - * confirmation from the user. - * - * @param $releases - * An array of releases from the drupal.org update service, with an additional - * array key candidate_version that specifies the version to be installed. - */ -function drush_pm_update_packages($releases) { - if (isset($releases['drupal'])) { - drush_print("NOTE: An update for the Drupal core is available. \nDrupal itself can't yet be updated by this tool. Please update Drupal manually.\n"); - unset($releases['drupal']); - } - - drush_print(t('Updates will be made to the following projects:')); - foreach($releases as $release) { - $print .= $release['title'] . " [" . $release['name'] . '-' . $release['candidate_version'] . "], "; - } - drush_print(substr($print, 0, strlen($print)-2)); - drush_print(); - drush_print(t("Note: Updated modules can potentially break your site. It's not recommended to update production sites without prior testing.")); - if (module_exists('drush_pm_svn')) { - drush_print(t("Note: A backup of your package will be stored to backups directory if no .svn directory is found.")); - } - drush_print(t('Note: If you have made any modifications to any file that belongs to one of these projects, you will have to migrate those modifications after updating.')); - if(!drush_confirm(t('Do you really want to continue?'))) { - drush_die('Aborting.'); - } - - $package_handler = drush_pm_get_package_handler() .'_update_project'; - if (!function_exists($package_handler)) { - drush_die(t("The $package_handler package handler does not handle updates.")); - } - - // Save the date to be used in the backup directory's path name. - $date = date('YmdHis'); - - // Now we start the actual updating. - foreach($releases as $release) { - drush_verbose(t('Starting to update !project ...', array('!project' => $release['title']))); - - $source = DRUSH_DRUPAL_ROOT .'/' . $release['path']; - - $skip_backup = module_invoke_all('drush_pm_skip_backup', $source); - if (!count($skip_backup)) { - $backup_dir = DRUSH_DRUPAL_ROOT. '/backup'; - drush_op('mkdir', $backup_dir, 0777); - $backup_dir .= '/modules'; - drush_op('mkdir', $backup_dir, 0777); - $backup_dir .= "/$date"; - drush_op('mkdir', $backup_dir, 0777); - $backup_target = $backup_dir . '/'. $release['name']; - if (!drush_op('rename', $source, $backup_target)) { - drush_die(t('Failed to backup project directory !source to !backup_target', array('!source' => $source, '!backup_target' => $backup_target))); - } - } - - // Install the new version. - // $basepath is the dir where the current module is installed. It's one dir up from the - // place of the project's info files. - $basepath = explode('/', $release['path']); - // move a directory up, so we can copy updated dir to parent - array_pop($basepath); - $project_parent_path = DRUSH_DRUPAL_ROOT. '/'. implode('/', $basepath). '/'; - if (!$package_handler($release['name'], $release['releases'][$release['candidate_version']], $project_parent_path)) { - if (!count($skip_backup)) { - drush_error(t('Updating project !project failed. Restoring previously installed version.', array('!project' => $release['name']))); - drush_op('rename', $backup_target, $source); - } - else { - drush_error(t('Updating project !project failed. Please revert to the previously installed version.', array('!project' => $release['name']))); - } - } - else { - drush_print(t('Project !project was updated successfully. Installed version is now !version.', array('!project' => $release['name'], '!version' => $release['candidate_version']))); - module_invoke_all('drush_pm_post_update', $release['name'], $release['releases'][$release['candidate_version']], $project_parent_path); - } - } - if ($backup_dir) { - drush_print(t("Backups were saved into the directory !backup_dir.", array('!backup_dir' => $backup_dir))); - } - drush_print(t("You should now run update.php through your browser.")); -} - -/** - * Find a module handler - */ -function drush_pm_get_package_handler() { - $package_handlers = module_invoke_all('drush_pm_package_handler'); - - if (empty($package_handlers)) { - drush_die(t("No package handlers found.")); - } - - $handler = drush_get_option('handler'); - // See if we have the full handler provided - if (array_search($handler, $package_handlers)) { - return $handler; - } - // Allow a shortcut for any functions named drush_pm_* - if (array_search('drush_pm_'. $handler, $package_handlers)) { - return 'drush_pm_'. $handler; - } - - // Fallback on the first provided handler (from the lightest module) - return $package_handlers[0]; -} - -/** - * Get update information for all installed projects. - * - * @return An array containing remote and local versions for all installed projects - */ -function _drush_pm_get_update_info($projects = NULL) { - $info = update_get_available(); - $data = update_calculate_project_data($info); - $data = drush_pm_get_project_path($data); - return $data; -} - -/** - * Command callback. Refresh update status information. - */ -function drush_pm_refresh() { - drush_print(t("Refreshing update status information ...")); - update_refresh(); - drush_print(t("Done.")); -} - -/** - * Get project information from drupal.org. - * - * @param $projects An array of project names - */ -function drush_pm_get_project_info($projects) { - $info = array(); - $data = array(); - foreach ($projects as $project_name => $project) { - $url = UPDATE_DEFAULT_URL. "/$project_name/". DRUPAL_CORE_COMPATIBILITY; - $xml = drupal_http_request($url); - $data[] = $xml->data; - } - if ($data) { - include_once drupal_get_path('module', 'update') .'/update.fetch.inc'; - $parser = new update_xml_parser; - $info = $parser->parse($data); - } - return $info; -} - -/** - * Get the recommended release for a certain so far uninstalled project. - * - * @param $project A project information array for the requested project - * @param $info A project information array for this project, as returned by an update service from drush_pm_get_project_info() - */ -function drush_pm_get_release($project, $info) { - $minor = ''; - $version_patch_changed = ''; - - if ($project['version']) { - // The user specified a specific version - try to find that exact version - foreach($info['releases'] as $version => $release) { - // Ignore unpublished releases. - if ($release['status'] != 'published') { - continue; - } - - // Straight match - if (!isset($recommended_version) && $release['version'] == $project['version']) { - $recommended_version = $version; - } - // Shortcut match with ommitted Drupal version - if (!isset($recommended_version) && $release['version'] == DRUPAL_CORE_COMPATIBILITY .'-'. $project['version']) { - $recommended_version = $version; - } - } - } - else { - // No version specified - try to find the best version we can - foreach($info['releases'] as $version => $release) { - // Ignore unpublished releases. - if ($release['status'] != 'published') { - continue; - } - - // If we haven't found a recommended version yet, put the dev - // version as recommended and hope it gets overwritten later. - // Look for the 'latest version' if we haven't found it yet. - // Latest version is defined as the most recent version for the - // default major version. - if (!isset($latest_version) && $release['version_major'] == $info['default_major']) { - $latest_version = $version; - } - - if (!isset($recommended_version) && $release['version_major'] == $info['default_major']) { - if ($minor != $release['version_patch']) { - $minor = $release['version_patch']; - $version_patch_changed = $version; - } - if (empty($release['version_extra']) && $minor == $release['version_patch']) { - $recommended_version = $version_patch_changed; - } - continue; - } - } - } - - if (isset($recommended_version)) { - return $info['releases'][$recommended_version]; - } - else if (isset($latest_version)) { - return $info['releases'][$latest_version]; - } - else { - return false; - } -} - -/** - * We need to set the project path by looking at the module location. Ideally, update.module would do this for us. - */ -function drush_pm_get_project_path($projects) { - foreach ($projects as $project => $info) { - if (!isset($info['path']) && $project != 'drupal') { - // looks for an enabled module. - foreach ($info['includes'] as $module => $name) { - if ($path = drupal_get_path('module', $module)) { - continue; - } - } - // As some modules are not located in their project's root directory - // but in a subdirectory (e.g. all the ecommerce modules), we take the module's - // info file's path, and then move up until we are at a directory with the - // project's name. - $parts = explode('/', $path); - $i = count($parts) - 1; - $stop = array_search($project, $parts); - while ($i > $stop) { - unset($parts[$i]); - $i--; - } - $projects[$project]['path'] = implode('/', $parts); - } - } - return $projects; -} - -/** - * A drush command callback. Show release info for given project(s). - * - **/ -function drush_pm_info() { - $projects = func_get_args(); - $projects = drupal_map_assoc($projects); - $info = drush_pm_get_project_info($projects); - - $rows[] = array(t('Project'), t('Release'), t('Date')); - foreach ($info as $key => $project) { - foreach ($project['releases'] as $release) { - - $rows[] = array( - $key, - $release['version'], - format_date($release['date'], 'custom', 'Y-M-d'), - ); - } - } - return drush_print_table($rows, FALSE, TRUE); -} - -/** - * Deletes a directory, all files in it and all subdirectories in it (recursively). - * Use with care! - * Written by Andreas Kalsch - */ -function delete_dir($dir) { - if (substr($dir, strlen($dir)-1, 1) != '/') - $dir .= '/'; - - if ($handle = opendir($dir)) { - while ($obj = readdir($handle)) { - if ($obj != '.' && $obj != '..') { - if (is_dir($dir.$obj)) { - if (!delete_dir($dir.$obj)) { - return false; - } - } - elseif (is_file($dir.$obj)) { - if (!unlink($dir.$obj)) { - return false; - } - } - } - } - - closedir($handle); - - if (!@rmdir($dir)) { - return false; - } - return true; - } - return false; -} - ?> Index: drush_pm_cvs/drush_pm_cvs.drush.inc =================================================================== RCS file: drush_pm_cvs/drush_pm_cvs.drush.inc diff -N drush_pm_cvs/drush_pm_cvs.drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drush_pm_cvs/drush_pm_cvs.drush.inc 20 Nov 2008 02:55:10 -0000 @@ -0,0 +1,90 @@ + 'drush_test_run', + 'description' => 'Run one or more Simpletest tests.', + ); + $items['test list'] = array( + 'callback' => 'drush_test_list', + 'description' => 'List the available Simpletest test classes.', + ); + return $items; +} + +function drush_test_list() { + simpletest_load(); + // TODO: Refactor simpletest.module so we don't copy code from DrupalUnitTests + $files = array(); + foreach (module_list() as $module) { + $module_path = drupal_get_path('module', $module); + if (file_exists($module_path .'/tests/')) { + $dir = $module_path .'/tests'; + $tests = file_scan_directory($dir, '\.test$'); + $files = array_merge($files, $tests); + } + } + $files = array_keys($files); + + $existing_classes = get_declared_classes(); + foreach ($files as $file) { + include_once($file); + } + $classes = array_diff(get_declared_classes(), $existing_classes); + $rows[] = array(t('Class'), t('Name'), t('Description')); + foreach ($classes as $class) { + $tmp = new $class; + if (method_exists($tmp, 'get_info')) { + $info = $tmp->get_info(); + $rows[] = array($class, $info['name'], truncate_utf8($info['desc'], 30, TRUE, TRUE)); + } + } + return drush_print_table($rows, 0, TRUE); +} + + +function drush_test_run($tests = NULL) { + simpletest_load(); + if (is_null($tests)) { + drush_print(t('Running all tests')); + $result = simpletest_run_tests(); + } + else { + $tests = explode(',', $tests); + $result = simpletest_run_tests($tests, 'text'); + } + return $result; +} Index: drush_simpletest/drush_simpletest.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush_simpletest/drush_simpletest.module,v retrieving revision 1.3.2.1 diff -u -5 -p -u -p -r1.3.2.1 drush_simpletest.module --- drush_simpletest/drush_simpletest.module 24 Jul 2008 14:21:13 -0000 1.3.2.1 +++ drush_simpletest/drush_simpletest.module 20 Nov 2008 02:55:11 -0000 @@ -4,10 +4,12 @@ /** * @file * */ +include_once('drush_simpletest.drush.inc'); + /** * Implementation of hook_help(). */ function drush_simpletest_help($section) { switch ($section) { @@ -16,63 +18,5 @@ function drush_simpletest_help($section) case 'drush:test list': return t("Usage drush [options] test list.\n\nList the available tests. Use drush test run command to run them. "); } } -/** - * Implementation of hook_drush_command(). - */ -function drush_simpletest_drush_command() { - $items['test run'] = array( - 'callback' => 'drush_test_run', - 'description' => 'Run one or more Simpletest tests.', - ); - $items['test list'] = array( - 'callback' => 'drush_test_list', - 'description' => 'List the available Simpletest test classes.', - ); - return $items; -} - -function drush_test_list() { - simpletest_load(); - // TODO: Refactor simpletest.module so we don't copy code from DrupalUnitTests - $files = array(); - foreach (module_list() as $module) { - $module_path = drupal_get_path('module', $module); - if (file_exists($module_path .'/tests/')) { - $dir = $module_path .'/tests'; - $tests = file_scan_directory($dir, '\.test$'); - $files = array_merge($files, $tests); - } - } - $files = array_keys($files); - - $existing_classes = get_declared_classes(); - foreach ($files as $file) { - include_once($file); - } - $classes = array_diff(get_declared_classes(), $existing_classes); - $rows[] = array(t('Class'), t('Name'), t('Description')); - foreach ($classes as $class) { - $tmp = new $class; - if (method_exists($tmp, 'get_info')) { - $info = $tmp->get_info(); - $rows[] = array($class, $info['name'], truncate_utf8($info['desc'], 30, TRUE, TRUE)); - } - } - return drush_print_table($rows, 0, TRUE); -} - - -function drush_test_run($tests = NULL) { - simpletest_load(); - if (is_null($tests)) { - drush_print(t('Running all tests')); - $result = simpletest_run_tests(); - } - else { - $tests = explode(',', $tests); - $result = simpletest_run_tests($tests, 'text'); - } - return $result; -} Index: drush_sql/drush_sql.drush.inc =================================================================== RCS file: drush_sql/drush_sql.drush.inc diff -N drush_sql/drush_sql.drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drush_sql/drush_sql.drush.inc 20 Nov 2008 02:55:11 -0000 @@ -0,0 +1,314 @@ + 'drush_sql_url', + 'description' => 'Print database connection details.' + ); + $items['sql version server'] = array( + 'callback' => 'drush_sql_version_server', + 'description' => 'Print database server version number.' + ); + $items['sql version client'] = array( + 'callback' => 'drush_sql_version_client', + 'description' => 'Print database client library version number.' + ); + $items['sql dump'] = array( + 'callback' => 'drush_sql_dump', + 'description' => 'Exports the Drupal DB as SQL using mysqldump or pg_dump.' + ); + $items['sql query'] = array( + 'callback' => 'drush_sql_query', + 'description' => 'Execute a query against the site database.' + ); + $items['sql load'] = array( + 'callback' => 'drush_sql_load', + 'description' => 'Copy source database to target database.' + ); + return $items; +} + + +/** + * Command callback. Displays the Drupal site's database connection string. + */ +function drush_sql_url() { + drush_print($GLOBALS['db_url']); +} + +/** + * Command callback. Displays the MySQL or PostgreSQL server version number. + */ +function drush_sql_version_server() { + switch (_drush_sql_get_scheme()) { + case 'mysql': + case 'mysqli': + drush_print(mysql_get_server_info()); + break; + case 'pgsql': + // NOTE: apparently the server version is only available if PHP was + // compiled with PostgreSQL 7.4 or later, so we'll fall back to + // displaying the client version if that's the case. + $info = pg_version(); + drush_print(isset($info['server_version']) ? $info['server_version'] : $info['client']); + break; + default: + drush_die(_drush_sql_get_invalid_url_msg()); + } +} + +/** + * Command callback. Displays the MySQL or PostgreSQL client version number. + */ +function drush_sql_version_client() { + switch (_drush_sql_get_scheme()) { + case 'mysql': + case 'mysqli': + drush_print(mysql_get_client_info()); + break; + case 'pgsql': + $info = pg_version(); + drush_print($info['client']); + break; + default: + drush_die(_drush_sql_get_invalid_url_msg()); + } +} + +/** + * Command callback. Outputs the entire Drupal database in SQL format using mysqldump or + * pg_dump. + * + * @param db_url + * @param execute + * @param skip + * A key in the sql_skip array which specifies a list of tables to ignore when migrating. + */ +function drush_sql_dump($db_url = NULL, $execute = TRUE, $skip = NULL) { + if (is_null($db_url)) { + $db_url = $GLOBALS['db_url']; + } + + switch (_drush_sql_get_scheme($db_url)) { + case 'mysql': + case 'mysqli': + $exec = 'mysqldump' . (DRUSH_VERBOSE ? ' -v' : ''); + if ($file = drush_get_option('result-file')) { + $exec .= ' --result-file '. $file; + } + $exec .= ' --opt -Q' . _drush_sql_get_credentials($db_url); + break; + case 'pgsql': + drush_die(t('Sorry, pg_dump support not implemented yet.')); // TODO: pg_dump command. + break; + default: + drush_die(_drush_sql_get_invalid_url_msg($db_url)); + } + + // Get any arguments to be passed through to the SQL client program. + if (func_num_args() > 3 && ($args = func_get_args())) { + $args = ' ' . implode(' ', array_slice($args, 3)); // skip standard arguments + } + + // Skip large core tables if instructed. Used by 'sql load' command. + if ($skip && strpos($exec, '--ignore-table') === FALSE) { + $all_skip_tables = (array)drush_get_option('skip-tables'); + $skip_tables = $all_skip_tables[$skip]; + $database = _drush_sql_get_database($db_url); + foreach ($skip_tables as $table) { + $ignores[] = "--ignore-table=$database.$table"; + } + $exec .= ' '. implode(' ', $ignores); + } + + if (!$execute) { + return $exec; + } + + if (DRUSH_VERBOSE) { + drush_print(t('Executing: !cmd', array('!cmd' => $exec))); + } + + return drush_op('system', $exec) !== FALSE; +} + +/** + * Command callback. Executes the given SQL query on the Drupal database. + * Reads from STDIN if no query is provided. + */ +function drush_sql_query($query = NULL) { + // Get any arguments to be passed through to the SQL client program. + if (func_num_args() > 1 && ($args = func_get_args())) { + $args = ' ' . implode(' ', array_slice($args, 1)); // skip query argument + } + + return drush_sql_query_execute($query, NULL, $args); +} + +function drush_sql_query_execute($query, $db_url = NULL, $args = NULL) { + // FIXME: currently we require the query due to an apparent inability to + // run the mysql child process interactively. Need to look more into + // proc_open() to see if it could be used for interactive execution. + if (empty($query)) { + if ($fstat = fstat(STDIN)) { + $query = fread(STDIN,$fstat[size]); + } + else { + drush_die(t('No SQL query given as argument.')); + } + } + + // Save query to a file. we will redirect it in. + $filename = time(). '.sql'; + if ($file = file_save_data($query, $filename)) { + switch (_drush_sql_get_scheme()) { + case 'mysql': + case 'mysqli': + $exec = 'mysql' . (DRUSH_VERBOSE ? ' -v' : ''); + $exec .= _drush_sql_get_credentials($db_url); + $exec .= " < ./$file"; + break; + case 'pgsql': + drush_die(t('Sorry, psql support not implemented yet.')); // TODO: psql command. + break; + default: + drush_die(_drush_sql_get_invalid_url_msg($db_url)); + } + $exec .= $args; + + if (DRUSH_VERBOSE) { + drush_print(t('Executing: !cmd', array('!cmd' => $exec))); + } + $return = drush_op('system', $exec) !== FALSE; + unlink($file); + return $return; + } +} + +/** + * Copy an entire database to another database. For example, migrate from Production to dev + * or dev to staging. + * + * conf_path() uses a static var so we can't use it to figure out paths based on URIs. + * + * @param source + * The name of a subdirectory under sites. Its settings.php specifies the database which should be migrated. + * @param target + * The name of a subdirectory under sites. Its settings.php specifies the database which whose tables will + * be replaced with the contents of `source`. + * @param skip + * A key in the sql_skip array which specifies a list of tables to ignore when migrating. + * + **/ +function drush_sql_load($source, $target, $skip = NULL) { + // Don't use require_once - we need to ovewrite db_url under some circumstances. + require "./sites/$source/settings.php"; + $db_url_source = is_array($db_url) ? $db_url['default'] : $db_url; + require "./sites/$target/settings.php"; + $db_url_target = is_array($db_url) ? $db_url['default'] : $db_url; + + // Prompt for confirmation. This is destructive. + if (!DRUSH_SIMULATE) { + drush_print(t("You will destroy data from !target and replace with data from !source.", array('!source' => $db_url_source, '!target' => $db_url_target))); + // TODO: actually make the backup if desired. + drush_print(t("You might want to make a backup first, using sql_dump command.\n")); + if (!drush_confirm(t('Do you really want to continue?'))) { + drush_die('Aborting.'); + } + } + + // Get command to export from source. + if ($retrieve = drush_sql_dump($db_url_source, FALSE, $skip)) { + // Get any arguments to be passed through to the mysqldump. + $args = array(); + if (func_num_args() > 3 && ($args = func_get_args())) { + $retrieve .= ' ' . implode(' ', array_slice($args, 3)); // skip standard arguments + } + + // Build import command for target. + $send = 'mysql' . (DRUSH_VERBOSE ? ' -v' : ''); + $send .= _drush_sql_get_credentials($db_url_target); + + // Build pipe command and redirect output to the bit bucket. + // Redirection prevented loads of SQL from writing to screen. + $exec = "$retrieve | $send > /dev/null 2>&1"; + + if (DRUSH_VERBOSE) { + drush_print(t('Executing: !cmd', array('!cmd' => $exec))); + } + + $return = drush_op('system', $exec) !== FALSE; + } + return $return; +} + +////////////////////////////////////////////////////////////////////////////// +// SQL SERVICE HELPERS + +// this sets some globals so please beware. +function drush_sql_get_path($uri) { + $drupal_base_url = parse_url($uri); + $_SERVER['HTTP_HOST'] = $drupal_base_url['host']; + $_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php'; + return conf_path(); +} + +function _drush_sql_get_scheme($db_url = NULL) { + if (is_null($db_url)) { + $db_url = $GLOBALS['db_url']; + } + $url = (object)parse_url($db_url); + return ($url->scheme); +} + +function _drush_sql_get_database($db_url = NULL) { + if (is_null($db_url)) { + $db_url = $GLOBALS['db_url']; + } + $url = (object)parse_url($db_url); + return substr($url->path, 1); +} + +function _drush_sql_get_credentials($db_url = NULL) { + if (is_null($db_url)) { + $db_url = $GLOBALS['db_url']; + } + + // NOTE: this regex could also parse the connection string URL: + // ^([\w]+)://([\w\d_]+):([^@]*)@([\w\d\.\-]*)/([\w\d_]+)$ + + $url = (object)parse_url($db_url); + $url->user = urldecode($url->user); + $url->pass = urldecode($url->pass); + $url->host = urldecode($url->host); + $url->path = substr(urldecode($url->path), 1); // skip leading '/' character + + switch ($url->scheme) { + case 'mysql': + case 'mysqli': + return ' -h' . $url->host . + (!isset($url->port) ? '' : ' -P' . $url->port) . + ' -u' . $url->user . + (empty($url->pass) ? '' : ' -p' . $url->pass) . ' ' . $url->path; + case 'pgsql': + drush_die(t('Sorry, psql support not implemented yet.')); // TODO: psql credentials. + return; + default: + drush_die(_drush_sql_get_invalid_url_msg()); + } +} + +function _drush_sql_get_invalid_url_msg($db_url = NULL) { + if (is_null($db_url)) { + $db_url = $GLOBALS['db_url']; + } + return t('Unable to parse DB connection string: `%url\'.', array('%url' => $db_url)); +} Index: drush_sql/drush_sql.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush_sql/drush_sql.module,v retrieving revision 1.12.2.1 diff -u -5 -p -u -p -r1.12.2.1 drush_sql.module --- drush_sql/drush_sql.module 1 Nov 2008 04:27:46 -0000 1.12.2.1 +++ drush_sql/drush_sql.module 20 Nov 2008 02:55:11 -0000 @@ -4,10 +4,12 @@ /** * @file * The drush SQL commands */ +include_once('drush_sql.drush.inc'); + /** * Implementation of hook_help(). */ function drush_sql_help($section) { switch ($section) { @@ -18,312 +20,5 @@ function drush_sql_help($section) { case 'drush:sql load': return t('Usage: drush [options] sql load . and are names of directories under \'sites\'. These determine from where and to where you want your database copied. Optional: specify \'common\' for if you wish to omit disposable tables like cache*, search*, etc. Your skip lists are specified in your drushrc.php file. Any additional arguments are passed to the mysqldump command directly.'); } } -/** - * Implementation of hook_drush_command(). - */ -function drush_sql_drush_command() { - $items['sql url'] = array( - 'callback' => 'drush_sql_url', - 'description' => 'Print database connection details.' - ); - $items['sql version server'] = array( - 'callback' => 'drush_sql_version_server', - 'description' => 'Print database server version number.' - ); - $items['sql version client'] = array( - 'callback' => 'drush_sql_version_client', - 'description' => 'Print database client library version number.' - ); - $items['sql dump'] = array( - 'callback' => 'drush_sql_dump', - 'description' => 'Exports the Drupal DB as SQL using mysqldump or pg_dump.' - ); - $items['sql query'] = array( - 'callback' => 'drush_sql_query', - 'description' => 'Execute a query against the site database.' - ); - $items['sql load'] = array( - 'callback' => 'drush_sql_load', - 'description' => 'Copy source database to target database.' - ); - return $items; -} - - -/** - * Command callback. Displays the Drupal site's database connection string. - */ -function drush_sql_url() { - drush_print($GLOBALS['db_url']); -} - -/** - * Command callback. Displays the MySQL or PostgreSQL server version number. - */ -function drush_sql_version_server() { - switch (_drush_sql_get_scheme()) { - case 'mysql': - case 'mysqli': - drush_print(mysql_get_server_info()); - break; - case 'pgsql': - // NOTE: apparently the server version is only available if PHP was - // compiled with PostgreSQL 7.4 or later, so we'll fall back to - // displaying the client version if that's the case. - $info = pg_version(); - drush_print(isset($info['server_version']) ? $info['server_version'] : $info['client']); - break; - default: - drush_die(_drush_sql_get_invalid_url_msg()); - } -} - -/** - * Command callback. Displays the MySQL or PostgreSQL client version number. - */ -function drush_sql_version_client() { - switch (_drush_sql_get_scheme()) { - case 'mysql': - case 'mysqli': - drush_print(mysql_get_client_info()); - break; - case 'pgsql': - $info = pg_version(); - drush_print($info['client']); - break; - default: - drush_die(_drush_sql_get_invalid_url_msg()); - } -} - -/** - * Command callback. Outputs the entire Drupal database in SQL format using mysqldump or - * pg_dump. - * - * @param db_url - * @param execute - * @param skip - * A key in the sql_skip array which specifies a list of tables to ignore when migrating. - */ -function drush_sql_dump($db_url = NULL, $execute = TRUE, $skip = NULL) { - if (is_null($db_url)) { - $db_url = $GLOBALS['db_url']; - } - - switch (_drush_sql_get_scheme($db_url)) { - case 'mysql': - case 'mysqli': - $exec = 'mysqldump' . (DRUSH_VERBOSE ? ' -v' : ''); - if ($file = drush_get_option('result-file')) { - $exec .= ' --result-file '. $file; - } - $exec .= ' --opt -Q' . _drush_sql_get_credentials($db_url); - break; - case 'pgsql': - drush_die(t('Sorry, pg_dump support not implemented yet.')); // TODO: pg_dump command. - break; - default: - drush_die(_drush_sql_get_invalid_url_msg($db_url)); - } - - // Get any arguments to be passed through to the SQL client program. - if (func_num_args() > 3 && ($args = func_get_args())) { - $args = ' ' . implode(' ', array_slice($args, 3)); // skip standard arguments - } - - // Skip large core tables if instructed. Used by 'sql load' command. - if ($skip && strpos($exec, '--ignore-table') === FALSE) { - $all_skip_tables = (array)drush_get_option('skip-tables'); - $skip_tables = $all_skip_tables[$skip]; - $database = _drush_sql_get_database($db_url); - foreach ($skip_tables as $table) { - $ignores[] = "--ignore-table=$database.$table"; - } - $exec .= ' '. implode(' ', $ignores); - } - - if (!$execute) { - return $exec; - } - - if (DRUSH_VERBOSE) { - drush_print(t('Executing: !cmd', array('!cmd' => $exec))); - } - - return drush_op('system', $exec) !== FALSE; -} - -/** - * Command callback. Executes the given SQL query on the Drupal database. - * Reads from STDIN if no query is provided. - */ -function drush_sql_query($query = NULL) { - // Get any arguments to be passed through to the SQL client program. - if (func_num_args() > 1 && ($args = func_get_args())) { - $args = ' ' . implode(' ', array_slice($args, 1)); // skip query argument - } - - return drush_sql_query_execute($query, NULL, $args); -} - -function drush_sql_query_execute($query, $db_url = NULL, $args = NULL) { - // FIXME: currently we require the query due to an apparent inability to - // run the mysql child process interactively. Need to look more into - // proc_open() to see if it could be used for interactive execution. - if (empty($query)) { - if ($fstat = fstat(STDIN)) { - $query = fread(STDIN,$fstat[size]); - } - else { - drush_die(t('No SQL query given as argument.')); - } - } - - // Save query to a file. we will redirect it in. - $filename = time(). '.sql'; - if ($file = file_save_data($query, $filename)) { - switch (_drush_sql_get_scheme()) { - case 'mysql': - case 'mysqli': - $exec = 'mysql' . (DRUSH_VERBOSE ? ' -v' : ''); - $exec .= _drush_sql_get_credentials($db_url); - $exec .= " < ./$file"; - break; - case 'pgsql': - drush_die(t('Sorry, psql support not implemented yet.')); // TODO: psql command. - break; - default: - drush_die(_drush_sql_get_invalid_url_msg($db_url)); - } - $exec .= $args; - - if (DRUSH_VERBOSE) { - drush_print(t('Executing: !cmd', array('!cmd' => $exec))); - } - $return = drush_op('system', $exec) !== FALSE; - unlink($file); - return $return; - } -} - -/** - * Copy an entire database to another database. For example, migrate from Production to dev - * or dev to staging. - * - * conf_path() uses a static var so we can't use it to figure out paths based on URIs. - * - * @param source - * The name of a subdirectory under sites. Its settings.php specifies the database which should be migrated. - * @param target - * The name of a subdirectory under sites. Its settings.php specifies the database which whose tables will - * be replaced with the contents of `source`. - * @param skip - * A key in the sql_skip array which specifies a list of tables to ignore when migrating. - * - **/ -function drush_sql_load($source, $target, $skip = NULL) { - // Don't use require_once - we need to ovewrite db_url under some circumstances. - require "./sites/$source/settings.php"; - $db_url_source = is_array($db_url) ? $db_url['default'] : $db_url; - require "./sites/$target/settings.php"; - $db_url_target = is_array($db_url) ? $db_url['default'] : $db_url; - - // Prompt for confirmation. This is destructive. - if (!DRUSH_SIMULATE) { - drush_print(t("You will destroy data from !target and replace with data from !source.", array('!source' => $db_url_source, '!target' => $db_url_target))); - // TODO: actually make the backup if desired. - drush_print(t("You might want to make a backup first, using sql_dump command.\n")); - if (!drush_confirm(t('Do you really want to continue?'))) { - drush_die('Aborting.'); - } - } - - // Get command to export from source. - if ($retrieve = drush_sql_dump($db_url_source, FALSE, $skip)) { - // Get any arguments to be passed through to the mysqldump. - $args = array(); - if (func_num_args() > 3 && ($args = func_get_args())) { - $retrieve .= ' ' . implode(' ', array_slice($args, 3)); // skip standard arguments - } - - // Build import command for target. - $send = 'mysql' . (DRUSH_VERBOSE ? ' -v' : ''); - $send .= _drush_sql_get_credentials($db_url_target); - - // Build pipe command and redirect output to the bit bucket. - // Redirection prevented loads of SQL from writing to screen. - $exec = "$retrieve | $send > /dev/null 2>&1"; - - if (DRUSH_VERBOSE) { - drush_print(t('Executing: !cmd', array('!cmd' => $exec))); - } - - $return = drush_op('system', $exec) !== FALSE; - } - return $return; -} - -////////////////////////////////////////////////////////////////////////////// -// SQL SERVICE HELPERS - -// this sets some globals so please beware. -function drush_sql_get_path($uri) { - $drupal_base_url = parse_url($uri); - $_SERVER['HTTP_HOST'] = $drupal_base_url['host']; - $_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php'; - return conf_path(); -} - -function _drush_sql_get_scheme($db_url = NULL) { - if (is_null($db_url)) { - $db_url = $GLOBALS['db_url']; - } - $url = (object)parse_url($db_url); - return ($url->scheme); -} - -function _drush_sql_get_database($db_url = NULL) { - if (is_null($db_url)) { - $db_url = $GLOBALS['db_url']; - } - $url = (object)parse_url($db_url); - return substr($url->path, 1); -} - -function _drush_sql_get_credentials($db_url = NULL) { - if (is_null($db_url)) { - $db_url = $GLOBALS['db_url']; - } - - // NOTE: this regex could also parse the connection string URL: - // ^([\w]+)://([\w\d_]+):([^@]*)@([\w\d\.\-]*)/([\w\d_]+)$ - - $url = (object)parse_url($db_url); - $url->user = urldecode($url->user); - $url->pass = urldecode($url->pass); - $url->host = urldecode($url->host); - $url->path = substr(urldecode($url->path), 1); // skip leading '/' character - - switch ($url->scheme) { - case 'mysql': - case 'mysqli': - return ' -h' . $url->host . - (!isset($url->port) ? '' : ' -P' . $url->port) . - ' -u' . $url->user . - (empty($url->pass) ? '' : ' -p' . $url->pass) . ' ' . $url->path; - case 'pgsql': - drush_die(t('Sorry, psql support not implemented yet.')); // TODO: psql credentials. - return; - default: - drush_die(_drush_sql_get_invalid_url_msg()); - } -} - -function _drush_sql_get_invalid_url_msg($db_url = NULL) { - if (is_null($db_url)) { - $db_url = $GLOBALS['db_url']; - } - return t('Unable to parse DB connection string: `%url\'.', array('%url' => $db_url)); -} \ No newline at end of file Index: drush_tools/drush_tools.drush.inc =================================================================== RCS file: drush_tools/drush_tools.drush.inc diff -N drush_tools/drush_tools.drush.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ drush_tools/drush_tools.drush.inc 20 Nov 2008 02:55:11 -0000 @@ -0,0 +1,132 @@ + 'drush_tools_cache_clear', + 'description' => 'Clear all caches' + ); + $items['cron'] = array( + 'callback' => 'drush_tools_cron_run', + 'description' => 'Run cron' + ); + $items['watchdog show'] = array( + 'callback' => 'drush_tools_watchdog_show', + 'description' => 'Show the most recent watchdog log messages' + ); + $items['watchdog delete'] = array( + 'callback' => 'drush_tools_watchdog_delete', + 'description' => 'Delete all messages of a certain type' + ); + $items['sync'] = array( + 'callback' => 'drush_tools_sync', + 'description' => 'Rsync the Drupal tree to/from another server using ssh' + ); + $items['eval'] = array( + 'callback' => 'drush_tools_eval', + 'description' => 'Evaluate a command', + ); + return $items; +} + +function drush_tools_cron_run() { + drupal_cron_run(); + drush_print(t('Cron run successfully.')); +} + +function drush_tools_cache_clear() { + drupal_flush_all_caches(); + drush_print(t('Cache cleared.')); +} + +/** + * Push files from or to the local Drupal install using SSH and RSync + * + * @return void + **/ +function drush_tools_sync($source, $destination) { + // Local paths are relative to Drupal root + if (!strstr($source, ':')) { + $source = DRUSH_DRUPAL_ROOT. "/$source"; + } + if (!strstr($destination, ':')) { + $destination = DRUSH_DRUPAL_ROOT. "/$destination"; + } + + // Prompt for confirmation. This is destructive. + if (!DRUSH_SIMULATE) { + drush_print(t("You will destroy data from !target and replace with data from !source", array('!source' => $source, '!target' => $destination))); + if (!drush_confirm(t('Do you really want to continue?'))) { + drush_die('Aborting.'); + } + } + + $options = '-az'; + $exec = "rsync -e ssh $options --exclude \"*.svn*\" $source $destination"; + if (DRUSH_VERBOSE) { + // the drush_op() will be verbose about the command that gets executed. + $options .= 'v'; + } + + return drush_op('system', $exec) !== FALSE; +} +/** + * Displays the most recent watchdog log messages (default: 10 messages). + */ +function drush_tools_watchdog_show($limit = 10, $type = NULL) { + $severities = array(WATCHDOG_NOTICE => t('notice'), WATCHDOG_WARNING => t('warning'), WATCHDOG_ERROR => t('error')); + + $sql = 'SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid ORDER BY w.wid DESC'; + $result = (!empty($type) ? + db_query_range($sql . " WHERE w.type = '%s'", $type, 0, (int)$limit) : + db_query_range($sql, 0, (int)$limit)); + + + $rows = array(); + module_load_include('inc', 'dblog', 'dblog.admin'); + while ($watchdog = db_fetch_object($result)) { + $rows[] = array( + format_date($watchdog->timestamp, 'small'), + $severities[$watchdog->severity], + t($watchdog->type), + truncate_utf8(decode_entities(strtr($watchdog->message, unserialize($watchdog->variables))), 68, FALSE, FALSE), + theme('username', $watchdog), + ); + } + + if (count($rows) == 0) { + drush_die(t('No log messages available.')); + } + drush_verbose(t('Last !count watchdog log messages:', array('!count' => $limit))); + + array_unshift($rows, array(t('Date'), t('Severity'), t('Type'), t('Message'), t('User'))); + drush_print_table($rows, 2, TRUE); +} + +/** + * Deletes all log messages of a certain type from the watchdog log + * (default: all). + */ +function drush_tools_watchdog_delete($type = NULL) { + if ($type == "all") { + drush_op('db_query', 'DELETE FROM {watchdog}'); // indiscriminately delete all + drush_print(t('Deleted !n rows.', array('!n' => db_affected_rows()))); + } + elseif (!empty($type)) { + drush_op('db_query', 'DELETE FROM {watchdog} WHERE type = \'%s\'', $type); + drush_print(t('Deleted !n rows.', array('!n' => db_affected_rows()))); + } + else { + drush_print(t('Please specify a message type, or "all" to delete all messages.')); + } +} + +function drush_tools_eval($command) { + eval($command); +} Index: drush_tools/drush_tools.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/drush_tools/drush_tools.module,v retrieving revision 1.9.2.6 diff -u -5 -p -u -p -r1.9.2.6 drush_tools.module --- drush_tools/drush_tools.module 15 Nov 2008 04:39:17 -0000 1.9.2.6 +++ drush_tools/drush_tools.module 20 Nov 2008 02:55:11 -0000 @@ -6,10 +6,12 @@ * * A soup of site utilities. * */ +include_once('drush_tools.drush.inc'); + /** * Implementation of hook_help(). */ function drush_tools_help($section) { switch ($section) { @@ -22,131 +24,5 @@ function drush_tools_help($section) { case 'drush:eval': return t("Usage: drush eval \n\nRun arbitrary PHP code in the context of Drupal. For example: drush eval \"variable_set('hello', 'world');\"."); } } -/** - * Implementation of hook_drush_command(). - */ -function drush_tools_drush_command() { - $items['cache clear'] = array( - 'callback' => 'drush_tools_cache_clear', - 'description' => 'Clear all caches' - ); - $items['cron'] = array( - 'callback' => 'drush_tools_cron_run', - 'description' => 'Run cron' - ); - $items['watchdog show'] = array( - 'callback' => 'drush_tools_watchdog_show', - 'description' => 'Show the most recent watchdog log messages' - ); - $items['watchdog delete'] = array( - 'callback' => 'drush_tools_watchdog_delete', - 'description' => 'Delete all messages of a certain type' - ); - $items['sync'] = array( - 'callback' => 'drush_tools_sync', - 'description' => 'Rsync the Drupal tree to/from another server using ssh' - ); - $items['eval'] = array( - 'callback' => 'drush_tools_eval', - 'description' => 'Evaluate a command', - ); - return $items; -} - -function drush_tools_cron_run() { - drupal_cron_run(); - drush_print(t('Cron run successfully.')); -} - -function drush_tools_cache_clear() { - drupal_flush_all_caches(); - drush_print(t('Cache cleared.')); -} - -/** - * Push files from or to the local Drupal install using SSH and RSync - * - * @return void - **/ -function drush_tools_sync($source, $destination) { - // Local paths are relative to Drupal root - if (!strstr($source, ':')) { - $source = DRUSH_DRUPAL_ROOT. "/$source"; - } - if (!strstr($destination, ':')) { - $destination = DRUSH_DRUPAL_ROOT. "/$destination"; - } - - // Prompt for confirmation. This is destructive. - if (!DRUSH_SIMULATE) { - drush_print(t("You will destroy data from !target and replace with data from !source", array('!source' => $source, '!target' => $destination))); - if (!drush_confirm(t('Do you really want to continue?'))) { - drush_die('Aborting.'); - } - } - - $options = '-az'; - $exec = "rsync -e ssh $options --exclude \"*.svn*\" $source $destination"; - if (DRUSH_VERBOSE) { - // the drush_op() will be verbose about the command that gets executed. - $options .= 'v'; - } - - return drush_op('system', $exec) !== FALSE; -} -/** - * Displays the most recent watchdog log messages (default: 10 messages). - */ -function drush_tools_watchdog_show($limit = 10, $type = NULL) { - $severities = array(WATCHDOG_NOTICE => t('notice'), WATCHDOG_WARNING => t('warning'), WATCHDOG_ERROR => t('error')); - - $sql = 'SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid ORDER BY w.wid DESC'; - $result = (!empty($type) ? - db_query_range($sql . " WHERE w.type = '%s'", $type, 0, (int)$limit) : - db_query_range($sql, 0, (int)$limit)); - - - $rows = array(); - module_load_include('inc', 'dblog', 'dblog.admin'); - while ($watchdog = db_fetch_object($result)) { - $rows[] = array( - format_date($watchdog->timestamp, 'small'), - $severities[$watchdog->severity], - t($watchdog->type), - truncate_utf8(decode_entities(strtr($watchdog->message, unserialize($watchdog->variables))), 68, FALSE, FALSE), - theme('username', $watchdog), - ); - } - - if (count($rows) == 0) { - drush_die(t('No log messages available.')); - } - drush_verbose(t('Last !count watchdog log messages:', array('!count' => $limit))); - - array_unshift($rows, array(t('Date'), t('Severity'), t('Type'), t('Message'), t('User'))); - drush_print_table($rows, 2, TRUE); -} - -/** - * Deletes all log messages of a certain type from the watchdog log - * (default: all). - */ -function drush_tools_watchdog_delete($type = NULL) { - if ($type == "all") { - drush_op('db_query', 'DELETE FROM {watchdog}'); // indiscriminately delete all - drush_print(t('Deleted !n rows.', array('!n' => db_affected_rows()))); - } - elseif (!empty($type)) { - drush_op('db_query', 'DELETE FROM {watchdog} WHERE type = \'%s\'', $type); - drush_print(t('Deleted !n rows.', array('!n' => db_affected_rows()))); - } - else { - drush_print(t('Please specify a message type, or "all" to delete all messages.')); - } -} - -function drush_tools_eval($command) { - eval($command); -} \ No newline at end of file