? 797190.patch ? drush-797190.patch ? includes/table.inc Index: commands/pm/pm.drush.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/pm.drush.inc,v retrieving revision 1.200 diff -u -r1.200 pm.drush.inc --- commands/pm/pm.drush.inc 5 Jan 2011 06:41:42 -0000 1.200 +++ commands/pm/pm.drush.inc 5 Jan 2011 10:56:31 -0000 @@ -1772,6 +1772,24 @@ ), ), ), + 'git' => array( + 'signature' => 'cd %s; git rev-parse', + 'options' => array( + 'version-control=git' => 'Quickly add/remove/commit your project changes to Git.', + ), + 'sub-options' => array( + 'version-control=git' => array( + 'gitsync' => 'Automatically add new files to the Git repository and remove deleted files. Caution.', + 'gitcommit' => 'Automatically commit changes to Git repository. You must also usw the --gitsync option.', + ), + 'gitcommit' => array( + 'gitmessage' => 'Override default commit message which is: Drush automatic commit. Project Command: ', + ), + ), + 'examples' => array( + 'drush dl cck --version-control=git --gitsync --gitcommit' => 'Download the cck project and then add it and commit it to Git.' + ), + ), 'bzr' => array( 'signature' => 'bzr root %s', 'options' => array( Index: commands/pm/updatecode.pm.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/updatecode.pm.inc,v retrieving revision 1.42 diff -u -r1.42 updatecode.pm.inc --- commands/pm/updatecode.pm.inc 5 Jan 2011 06:28:44 -0000 1.42 +++ commands/pm/updatecode.pm.inc 5 Jan 2011 10:56:31 -0000 @@ -240,6 +240,16 @@ return drush_set_error('DRUSH_PATH_NO_WRITABLE', dt('Drupal root path is not writable.')); } + if (!$version_control = drush_pm_include_version_control($drupal_root)) { + return FALSE; + } + + $project['full_project_path'] = $drupal_root; + // Check we have a version control system, and it clears its pre-flight. + if (!$version_control->pre_update($project)) { + return FALSE; + } + // Create a directory 'core' if it does not already exist. $project['path'] = 'drupal-' . $project['candidate_version']; $project['full_project_path'] = $drupal_root . '/' . $project['path']; @@ -250,12 +260,10 @@ // Create a list of directories to exclude from the update process. $skip_list = array('sites', $project['path']); // Add non-writable directories: we can't move them around. - // We will also use $items_to_test later for $version_control check. - $items_to_test = drush_scan_directory($drupal_root, '/.*/', array_merge(array('.', '..'), $skip_list), 0, FALSE, 'basename', 0, TRUE); - foreach (array_keys($items_to_test) as $item) { + $files = drush_scan_directory($drupal_root, '/.*/', array_merge(array('.', '..'), $skip_list), 0, FALSE, 'basename', 0, TRUE); + foreach (array_keys($files) as $item) { if (is_dir($item) && !is_writable($item)) { $skip_list[] = $item; - unset($items_to_test[$item]); } } $project['skip_list'] = $skip_list; @@ -268,15 +276,7 @@ // the _pm_update_move_files above. drush_set_context('DRUSH_PM_DRUPAL_CORE', $project); - if (!$version_control = drush_pm_include_version_control($project['full_project_path'])) { - return FALSE; - } - $project['base_project_path'] = dirname($project['full_project_path']); - // Check we have a version control system, and it clears its pre-flight. - if (!$version_control->pre_update($project, $items_to_test)) { - return FALSE; - } // Package handlers want the project directory in project_dir. $project['project_dir'] = $project['path']; Index: commands/pm/version_control/bzr.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/version_control/bzr.inc,v retrieving revision 1.12 diff -u -r1.12 bzr.inc --- commands/pm/version_control/bzr.inc 4 Jan 2011 09:27:46 -0000 1.12 +++ commands/pm/version_control/bzr.inc 5 Jan 2011 10:56:31 -0000 @@ -12,20 +12,16 @@ * * Check that the project or drupal core directory looks clean */ - public function pre_update(&$project, $items_to_test = array()) { - // If items to test is empty, test everything; otherwise, pass just - // the list of files to test to Bazaar status. - $args = array_keys($items_to_test); - array_unshift($args, 'bzr status --short ' . str_repeat('%s ', count($items_to_test))); - array_unshift($args, $project['full_project_path']); - if (call_user_func_array('drush_shell_cd_and_exec', $args)) { + public function pre_update(&$project) { + // Check the project directory looks clean. + if (drush_shell_cd_and_exec($project['full_project_path'], 'bzr status --short')) { $output = preg_grep('/^[\sRCP][\sNDKM][\s\*]/', drush_shell_exec_output()); if (!empty($output)) { return drush_set_error('DRUSH_PM_BZR_LOCAL_CHANGES', dt("The Bazaar working copy at !path appears to have uncommitted changes (see below). Please commit or revert these changes before continuing:\n!output", array('!path' => $project['full_project_path'], '!output' => implode("\n", $output)))); } } else { - return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to get the bzr status on !path. Check that you have Bazaar \ninstalled and that this directory is a Bazaar working copy.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to get the bzr status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } return TRUE; } @@ -41,7 +37,7 @@ } } else { - return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to get the Bazaar status on !path. Check that you have Bazaar \ninstalled and that this directory is a Bazaar working copy.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to revert the Bazaar working copy on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } } @@ -98,7 +94,7 @@ } } else { - return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to get the bzr status. Check that you have Bazaar \ninstalled and that the site is a Bazaar working copy.\nThe specific errors are below:\n!errors", array('!errors' => implode("\n", drush_shell_exec_output())))); + return drush_set_error('DRUSH_PM_BZR_NOT_FOUND', dt("Drush was unable to get the bzr status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } return TRUE; } Index: commands/pm/version_control/git.inc =================================================================== RCS file: commands/pm/version_control/git.inc diff -N commands/pm/version_control/git.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ commands/pm/version_control/git.inc 5 Jan 2011 10:56:31 -0000 @@ -0,0 +1,136 @@ + $project['full_project_path'], '!output' => implode("\n", $output)))); + } + } + } + else { + return drush_set_error('DRUSH_PM_GIT_NOT_FOUND', dt("Drush was unable to get the git status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + } + return TRUE; + } + + /** + * Implementation of rollback(). + */ + public function rollback($project) { + if (drush_shell_exec('git checkout %s', $project['full_project_path'])) { + $output = drush_shell_exec_output(); + if (!empty($output)) { + return drush_set_error('DRUSH_PM_GIT_LOCAL_CHANGES', dt("The Git working copy at !path appears to have uncommitted changes (see below). Please commit or revert these changes before continuing:\n!output", array('!path' => $project['full_project_path'], '!output' => implode("\n", $output)))); + } + } + else { + return drush_set_error('DRUSH_PM_GIT_NOT_FOUND', dt("Drush was unable to revert the Git working copy on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + } + } + + /** + * Implementation of post_update(). + */ + public function post_update($project) { + if ($this->sync($project)) { + // Only attempt commit on a sucessful sync + $this->commit($project); + } + } + + /** + * Implementation of post_download(). + */ + public function post_download($project) { + if ($this->sync($project)) { + // Only attempt commit on a sucessful sync + $this->commit($project); + } + } + + /** + * Automatically add any unversioned files to Git and remove any files + * that have been deleted on the file system + */ + private function sync($project) { + if (drush_get_option('gitsync')) { + if (drush_shell_cd_and_exec($project['full_project_path'], 'git status --short')) { + // git status doesn't provide an exit code for this usecase. + // We need to test $output is not empty. + $output = drush_shell_exec_output(); + if (!empty($output)) { + $errors = ''; + // All paths returned by git status are relative to the cwd so let's + // temporary change to the project directory. + $olddir = getcwd(); + drush_op('chdir', $project['full_project_path']); + foreach ($output as $line) { + // git add untracked files + if (preg_match('/^\?\?\s(.*)/', $line, $matches)) { + $path = $matches[1]; + if (!drush_shell_exec('git add %s', $path)) { + $errors .= implode("\n", drush_shell_exec_output()); + } + } + // git rm deleted files + else if (preg_match('/^\sD\s(.*)/', $line, $matches)) { + $path = $matches[1]; + if (!drush_shell_exec('git rm %s', $path)) { + $errors .= implode("\n", drush_shell_exec_output()); + } + } + } + drush_op('chdir', $olddir); + if (!empty($errors)) { + return drush_set_error('DRUSH_PM_GIT_SYNC_PROBLEMS', dt("Problems were encountered adding or removing files to/from Bazaar.\nThe specific errors are below:\n!errors", array('!errors' => $errors))); + } + } + } + else { + return drush_set_error('DRUSH_PM_GIT_NOT_FOUND', dt("Drush was unable to get the git status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + } + return TRUE; + } + } + + /** + * Automatically commit changes to the repository + */ + private function commit($project) { + if (drush_get_option('gitcommit')) { + $message = drush_get_option('gitmessage'); + if (empty($message)) { + $message = dt("Drush automatic commit.\nProject: @name @type\nCommand: @arguments", array('@name' => $project['name'], '@type' => $project['project_type'], '@arguments' => implode(' ', $_SERVER['argv']))); + } + if (drush_shell_exec('git commit --message=%s %s', $message, $project['full_project_path'])) { + drush_log(dt('Project !name committed to Git successfully', array('!name' => $project['name'])), 'ok'); + } + else { + drush_set_error('DRUSH_PM_GIT_COMMIT_PROBLEMS', dt("Problems were encountered committing your changes to Git.\nThe specific errors are below:\n!errors", array('!errors' => implode("\n", drush_shell_exec_output())))); + } + } + else { + drush_print(dt("You should consider committing the new code to your Git repository.\nIf this version becomes undesireable, use Git to roll back.")); + } + } + + public static function reserved_files() { + return array('.git', '.gitignore'); + } +} Index: commands/pm/version_control/svn.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush/commands/pm/version_control/svn.inc,v retrieving revision 1.16 diff -u -r1.16 svn.inc --- commands/pm/version_control/svn.inc 7 Dec 2010 16:35:09 -0000 1.16 +++ commands/pm/version_control/svn.inc 5 Jan 2011 10:56:31 -0000 @@ -10,12 +10,8 @@ /** * Implementation of pre_update(). */ - public function pre_update(&$project, $items_to_test = array()) { - // If items to test is empty, test everything; otherwise, pass just - // the list of files to test to svn status. - $status_files = implode(' ', array_keys($items_to_test)); - - // Check the project directory looks clean + public function pre_update(&$project) { + // Check the project directory looks clean. if (drush_shell_cd_and_exec($project['full_project_path'], 'svn status '. drush_get_option('svnstatusparams') .' '. $status_files)) { $output = preg_grep('/^[ ACDMRX?!~][ CM][ L][ +][ SX][ K]/', drush_shell_exec_output()); if (!empty($output)) { @@ -26,8 +22,8 @@ return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to get the svn status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } - // Check for incoming updates - if (drush_shell_cd_and_exec($project['full_project_path'], 'svn status -u '. drush_get_option('svnstatusparams') .' '. $status_files)) { + // Check for incoming updates. + if (drush_shell_cd_and_exec($project['full_project_path'], 'svn status -u '. drush_get_option('svnstatusparams'))) { $output = preg_grep('/\*/', drush_shell_exec_output()); if (!empty($output)) { return drush_set_error('DRUSH_PM_SVN_REMOTE_CHANGES', dt("The SVN working copy at !path appears to be out of date with the repository (see below). Please run 'svn update' to pull down changes before continuing:\n!output", array('!path' => $project['full_project_path'], '!output' => implode("\n", $output)))); @@ -50,7 +46,7 @@ } } else { - return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to get the svn status on !path. Check that you have Subversion \ninstalled and that this directory is a subversion working copy.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to revert the svn working copy on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } } @@ -100,7 +96,7 @@ } } else { - return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to get the svn status on !path. Check that you have Subversion \ninstalled and that this directory is a subversion working copy.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); + return drush_set_error('DRUSH_PM_SVN_NOT_FOUND', dt("Drush was unable to get the svn status on !path.\nThe specific errors are below:\n!errors", array('!path' => $project['full_project_path'], '!errors' => implode("\n", drush_shell_exec_output())))); } return TRUE; } @@ -113,7 +109,7 @@ if (drush_get_option('svncommit')) { $message = drush_get_option('svnmessage'); if (empty($message)) { - $message = dt("Drush automatic commit: \n") . implode(' ', $_SERVER['argv']); + $message = dt("Drush automatic commit.\nProject: @name @type\nCommand: @arguments", array('@name' => $project['name'], '@type' => $project['project_type'], '@arguments' => implode(' ', $_SERVER['argv']))); } if (drush_shell_exec('svn commit '. drush_get_option('svncommitparams') .' -m "'. $message .'" '. $project['full_project_path'])) { drush_log(dt('Project committed to Subversion successfully'), 'ok');