Index: drush_make.download.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush_make/Attic/drush_make.download.inc,v retrieving revision 1.1.2.99 diff -u -p -r1.1.2.99 drush_make.download.inc --- drush_make.download.inc 21 Nov 2010 23:25:50 -0000 1.1.2.99 +++ drush_make.download.inc 3 Dec 2010 09:42:34 -0000 @@ -1,10 +1,10 @@ $name, '%module' => $download['module'])), 'ok'); + if ($update_in_place) { + drush_log(dt('%project updated.', array('%project' => $name)), 'ok'); + } + else { + drush_log(dt('%project downloaded from %module.', array('%project' => $name, '%module' => $download['module'])), 'ok'); + } return $download_location; } } @@ -62,7 +75,48 @@ function drush_make_download_cvs($name, return FALSE; } -function drush_make_download_file($name, $download, $download_location) { +/ Can't use `drush_get_projects`, since it requires a full drupal environment +function drush_make_parse_project_info($filename) { + $contents = file_get_contents($filename); + $struct = array( + 'project' => null, + 'core' => null, + 'version' => null); + if (preg_match_all('/^project\s*=\s*[\'"]?([^\'"\n]+)[\'"]?\s*$/m', $contents, $mm)) { + $struct['project'] = $mm[1][count($mm[1])-1]; + } + if (preg_match_all('/^version\s*=\s*[\'"]?([^\'"\n]+)[\'"]?\s*$/m', $contents, $mm)) { + $full_version = $mm[1][count($mm[1])-1]; + list($core, $version) = explode('-', $full_version, 2); + $struct['core'] = $core; + $struct['version'] = $version; + } + return $struct; +} + +// Finds and parses all info files in a directory +function drush_make_load_project_info_from_dir($path) { + $finder = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.')), '/^.+\.info$/', RecursiveRegexIterator::GET_MATCH); + $files = array_map('array_pop', iterator_to_array($finder)); + $projects = array(); + foreach ($files as $filename) { + $info = drush_make_parse_project_info($filename); + $projects[$info['project']] = $info; + } + return $projects; +} + +function drush_make_download_file($name, $download, $download_location, $project = null) { + if (drush_get_option('remake') && $project) { + // Check if we're about to download something that already is there + $infos = drush_make_load_project_info_from_dir($download_location . '/' . $name); + if (isset($infos[$name])) { + if ($infos[$name]['core'] == $project->core && $infos[$name]['version'] == $project->version) { + drush_log(dt('%project version %version already installed.', array('%project' => $name, '%version' => $infos[$name]['version'])), 'ok'); + return TRUE; + } + } + } if ($filename = _drush_make_download_file($download)) { if (isset($download['md5'])) { if (_drush_make_verify_checksum($filename, $download['md5']) === FALSE) { @@ -292,7 +346,7 @@ function drush_make_download_file_unpack list($main_directory) = array_reverse(explode('/', $download_location)); drush_make_mkdir($tmp_path . '/__unzip__'); - drush_shell_exec("unzip %s -d %s", $filename, $tmp_path . '/__unzip__'); + drush_shell_exec("unzip -o %s -d %s", $filename, $tmp_path . '/__unzip__'); _drush_make_download_file_move($tmp_path, $filename, $download_location); } @@ -326,8 +380,8 @@ function _drush_make_download_file_move( // Backwards compatibility. -function drush_make_download_get($name, $download, $download_location) { - return drush_make_download_file($name, $download, $download_location); +function drush_make_download_get($name, $download, $download_location, $project = null) { + return drush_make_download_file($name, $download, $download_location, $project); } function drush_make_download_post($name, $download, $download_location) { @@ -339,6 +393,7 @@ function drush_make_download_post($name, function drush_make_download_git($name, $download, $download_location) { $tmp_path = drush_make_tmp(); $wc = drush_get_option('working-copy'); + $update_in_place = drush_get_option('remake') && $wc && is_dir($download_location . '/.git'); // check if branch option is set in info file, otherwise set default to master branch $download['branch'] = isset($download['branch']) ? $download['branch'] : 'master'; @@ -406,12 +461,25 @@ function drush_make_download_git($name, } } - $tmp_location = $tmp_path . '/__git__/' . basename($download_location); - - drush_make_mkdir($tmp_path . '/__git__/'); + // clone|pull the given repository + if ($update_in_place) { + $tmp_location = $download_location; + $cwd = getcwd(); + chdir($tmp_location); + drush_shell_exec("git stash"); + chdir($cwd); + $clone_ok = true; + drush_log(dt('%project already cloned.', array('%project' => $name)), 'ok'); + } else { + $tmp_location = $tmp_path . '/__git__/' . basename($download_location); + drush_make_mkdir($tmp_path . '/__git__/'); + $clone_ok = drush_shell_exec("git clone %s %s", $url, $tmp_location); + if ($clone_ok) { + drush_log(dt('%project cloned from %url.', array('%project' => $name, '%url' => $url)), 'ok'); + } + } - // clone the given repository - if (drush_shell_exec("git clone %s %s", $url, $tmp_location)) { + if ($clone_ok) { drush_log(dt('%project cloned from %url.', array('%project' => $name, '%url' => $url)), 'ok'); // GIT Checkout only work on a ready cloned repo. So we switch to branch or to tag (only if we have no branch) after cloneing. @@ -479,8 +547,10 @@ function drush_make_download_git($name, if (!$wc && file_exists($tmp_location . '/.git')) { drush_shell_exec("rm -rf %s", $tmp_location . '/.git'); } - drush_shell_exec('cp -Rf %s %s', $tmp_location, dirname($download_location)); - drush_shell_exec("rm -rf %s", dirname($tmp_location)); + if (!$update_in_place) { + drush_shell_exec('cp -Rf %s %s', $tmp_location, dirname($download_location)); + drush_shell_exec("rm -rf %s", dirname($tmp_location)); + } return dirname($tmp_location); } else { @@ -546,7 +616,11 @@ function drush_make_download_svn($name, $options = '--force --non-interactive'; $function = 'drush_shell_exec'; } - if (drush_get_option('working-copy')) { + $update_in_place = drush_get_option('remake') && drush_get_option('working-copy') && is_dir($download_location . '/.svn'); + if ($update_in_place) { + $command = 'svn ' . $options . ' update'; + } + elseif (drush_get_option('working-copy')) { $command = 'svn ' . $options . ' checkout'; } else { @@ -560,9 +634,15 @@ function drush_make_download_svn($name, $args[] = $download['revision']; } - $command .= ' %s %s'; - $args[] = $download['url']; - $args[] = $download_location; + if ($update_in_place) { + $command .= ' %s'; + $args[] = $download_location; + } + else { + $command .= ' %s %s'; + $args[] = $download['url']; + $args[] = $download_location; + } if (!empty($download['username'])) { $command .= ' --username %s'; @@ -575,7 +655,12 @@ function drush_make_download_svn($name, array_unshift($args, $command); $result = call_user_func_array($function, $args); if ($result) { - drush_log(dt('%project @command from %url.', array('%project' => $name, '@command' => $command, '%url' => $download['url'])), 'ok'); + if ($update_in_place) { + drush_log(dt('%project @command.', array('%project' => $name, '@command' => $command)), 'ok'); + } + else { + drush_log(dt('%project @command from %url.', array('%project' => $name, '@command' => $command, '%url' => $download['url'])), 'ok'); + } return $download_location; } else { Index: drush_make.drush.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush_make/Attic/drush_make.drush.inc,v retrieving revision 1.11.2.84 diff -u -p -r1.11.2.84 drush_make.drush.inc --- drush_make.drush.inc 23 Nov 2010 08:08:23 -0000 1.11.2.84 +++ drush_make.drush.inc 3 Dec 2010 09:42:34 -0000 @@ -45,6 +45,7 @@ function drush_make_drush_command() { '--test' => 'Run a temporary test build and clean up.', '--translations=languages' => 'Retrieve translations for the specified comma-separated list of language(s) if available for all projects.', '--working-copy' => 'Where possible, retrieve a working copy of projects from their respective repositories.', + '--remake' => 'Will update modules in place, overriding downloaded code or updating working copies of modules.', ), ); @@ -103,9 +104,19 @@ function drush_drush_make_make($makefile return; } + if (drush_get_option('remake') && (drush_get_option('test') || drush_get_option('tar'))) { + drush_make_error('BUILD_ERROR', "The options --test, --tar are incompatible with --remake"); + return FALSE; + } + if (!($build_path = drush_make_build_path($build_path))) { return; } + if (drush_get_option('remake')) { + $GLOBALS['drush_make_tmp_build_path'] = $build_path; + } else { + $GLOBALS['drush_make_tmp_build_path'] = null; + } $info = drush_make_parse_info_file($makefile); if ( $info === FALSE || ($info = drush_make_validate_info_file($info)) === FALSE) { return FALSE; @@ -121,13 +132,16 @@ function drush_drush_make_make($makefile drush_make_md5(); } - // Only take final build steps if not in testing mode. - if (!drush_get_option('test')) { - if (drush_get_option('tar')) { - drush_make_tar($build_path); - } - else { - drush_make_move_build($build_path); + // Don't do the final cleanup job if we're remaking, since it's in-place + if (!drush_get_option('remake')) { + // Only take final build steps if not in testing mode. + if (!drush_get_option('test')) { + if (drush_get_option('tar')) { + drush_make_tar($build_path); + } + else { + drush_make_move_build($build_path); + } } } @@ -168,7 +182,7 @@ function drush_make_projects($recursion, $projects[($project['type'] == 'core' ? 'core' : 'contrib')][$project['name']] = new $class_name($project); } else { - drush_make_error(dt('Non-existent project type %type on project %project', array('%type' => $project['type'], '%project' => $key))); + drush_make_error('BUILD_ERROR', dt('Non-existent project type %type on project %project', array('%type' => $project['type'], '%project' => $key))); } } @@ -354,7 +368,7 @@ function drush_make_build_path($build_pa $build_path = rtrim($build_path, '/'); } // Allow tests to run without a specified base path. - elseif (drush_get_option('test') || drush_confirm(dt("Make new site in the current directory?"))) { + elseif (drush_get_option('test') || drush_get_option('remake') || drush_confirm(dt("Make new site in the current directory?"))) { $build_path = '.'; } else { @@ -372,15 +386,15 @@ function drush_make_move_build($build_pa $tmp_path = drush_make_tmp(); $ret = TRUE; if ($build_path == '.') { - drush_shell_exec('ls -A %s', $tmp_path . '/__build__'); + drush_shell_exec('ls -A %s', drush_make_tmp_build_path()); $info = drush_shell_exec_output(); foreach ($info as $file) { - $ret = $ret && drush_shell_exec("cp -Rf %s %s", $tmp_path . '/__build__/' . $file, $build_path); + $ret = $ret && drush_shell_exec("cp -Rf %s %s", drush_make_tmp_build_path() . '/' . $file, $build_path); } } else { drush_make_mkdir(dirname($build_path)); - drush_shell_exec("mv %s %s", $tmp_path . '/__build__', $tmp_path . '/' . basename($build_path)); + drush_shell_exec("mv %s %s", drush_make_tmp_build_path(), $tmp_path . '/' . basename($build_path)); drush_shell_exec("cp -Rf %s %s", $tmp_path . '/' . basename($build_path), dirname($build_path)); } if (!$ret) { Index: drush_make.project.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush_make/Attic/drush_make.project.inc,v retrieving revision 1.1.2.53 diff -u -p -r1.1.2.53 drush_make.project.inc --- drush_make.project.inc 12 Nov 2010 05:31:59 -0000 1.1.2.53 +++ drush_make.project.inc 3 Dec 2010 09:42:34 -0000 @@ -23,7 +23,7 @@ class DrushMakeProject { return FALSE; } $download_location = $this->findDownloadLocation(); - if (drush_make_download_factory($this->name, $this->download, $download_location) === FALSE) { + if (drush_make_download_factory($this->name, $this->download, $download_location, $this) === FALSE) { return FALSE; } if (!$this->addLockfile($download_location)) { @@ -48,8 +48,11 @@ class DrushMakeProject { $this->download_location = $this->path . '/' . $this->project_directory; // This directory shouldn't exist yet -- if it does, stop. if (is_dir($this->download_location)) { - drush_set_error(dt('Directory not empty: %directory', array('%directory' => $this->download_location))); - return FALSE; + // .. except if we're remaking + if (!drush_get_option('remake')) { + drush_set_error(dt('Directory not empty: %directory', array('%directory' => $this->download_location))); + return FALSE; + } } else { drush_make_mkdir($this->download_location); @@ -65,37 +68,58 @@ class DrushMakeProject { return TRUE; } + $patches_file_name = $project_directory . '/PATCHES.txt'; + $already_applied_patches = array(); + + if (drush_get_option('remake') && is_file($patches_file_name)) { + $contents = file_get_contents($patches_file_name); + if (!preg_match('/The following patches have been applied to this project:(.*)This file was automatically generated by Drush Make/s', $contents, $mm)) { + drush_make_error('BUILD_ERROR', "Unable to parse $patches_file_name"); + return FALSE; + } + preg_match_all('~^- (.*://.*)~m', $contents, $mm); + $already_applied_patches = $mm[1]; + } + $patches_txt = ''; $ignore_checksums = drush_get_option('ignore-checksums'); foreach ($this->patch as $info) { if (!is_array($info)) { $info = array('url' => $info); } - // Download the patch. - if ($filename = _drush_make_download_file($info)) { - $patched = drush_shell_exec("patch -p0 -d %s < %s", $project_directory, $filename); - if ($patched) { - if (!$ignore_checksums) { - if (isset($info['md5']) && md5(file_get_contents($filename)) !== $info['md5']) { - drush_set_error(dt('Checksum failed to validate for %filename.', array('%filename' => $filename))); - return FALSE; + if (!in_array($info['url'], $already_applied_patches)) { + // Download the patch. + if ($filename = _drush_make_download_file($info)) { + $patched = drush_shell_exec("patch -p0 -d %s < %s", $project_directory, $filename); + if ($patched) { + if (!$ignore_checksums) { + if (isset($info['md5']) && md5(file_get_contents($filename)) !== $info['md5']) { + drush_set_error(dt('Checksum failed to validate for %filename.', array('%filename' => $filename))); + return FALSE; + } } + $patches_txt .= '- ' . $info['url'] . "\n"; } - $patches_txt .= '- ' . $info['url'] . "\n"; + drush_log($this->name . ' patched with ' . basename($filename) . '.', $patched ? 'ok' : 'error'); + drush_op('unlink', $filename); + } + else { + drush_make_error('BUILD_ERROR', 'Unable to download ' . $info['url'] . '.'); + return FALSE; } - drush_log($this->name . ' patched with ' . basename($filename) . '.', $patched ? 'ok' : 'error'); - drush_op('unlink', $filename); - } - else { - drush_make_error('Unable to download ' . $info['url'] . '.'); - return FALSE; } } if (!empty($patches_txt) && !drush_get_option('no-patch-txt') && !file_exists($project_directory . '/PATCHES.txt')) { + // Make sure that already applied patches are kept in the registry + $tmp = ""; + foreach ($already_applied_patches as $patch_url) { + $tmp .= '- ' . $patch_url . "\n"; + } $patches_txt = "The following patches have been applied to this project:\n" . + $tmp . $patches_txt . "\nThis file was automatically generated by Drush Make (http://drupal.org/project/drush_make)."; - file_put_contents($project_directory . '/PATCHES.txt', $patches_txt); + file_put_contents($patches_file_name, $patches_txt); drush_log('Generated PATCHES.txt file for ' . $this->name, 'ok'); } return TRUE; @@ -206,8 +230,7 @@ class DrushMakeProject { protected function generatePath($base = TRUE) { $path = array(); if ($base) { - $path[] = drush_make_tmp(); - $path[] = '__build__'; + $path[] = drush_make_tmp_build_path(); } if (!empty($this->contrib_destination)) { $path[] = $this->contrib_destination; Index: drush_make.utilities.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/drush_make/Attic/drush_make.utilities.inc,v retrieving revision 1.1.2.56 diff -u -p -r1.1.2.56 drush_make.utilities.inc --- drush_make.utilities.inc 24 Nov 2010 07:41:49 -0000 1.1.2.56 +++ drush_make.utilities.inc 3 Dec 2010 09:42:34 -0000 @@ -296,6 +296,14 @@ function drush_make_tmp($set = TRUE) { return $tmp_dir; } +function drush_make_tmp_build_path() { + global $drush_make_tmp_build_path; + if (!isset($drush_make_tmp_build_path)) { + $drush_make_tmp_build_path = drush_make_tmp() . '/__build__'; + } + return $drush_make_tmp_build_path; +} + function drush_make_clean_tmp() { if (!($tmp_dir = drush_make_tmp(FALSE))) { return; @@ -309,7 +317,7 @@ function drush_make_clean_tmp() { } function drush_make_prepare_install($build_path) { - $default = drush_make_tmp() . '/__build__/sites/default'; + $default = drush_make_tmp_build_path() . '/sites/default'; drush_shell_exec("cp %s %s", $default . '/default.settings.php', $default . '/settings.php'); drush_make_mkdir($default . '/files'); drush_shell_exec("chmod a+w %s %s", $default . '/settings.php', $default . '/files'); @@ -340,14 +348,14 @@ function drush_make_tar($build_path) { $dirname = basename($build_path, '.tar.gz'); // Move the build directory to a more human-friendly name, so that tar will // use it instead. - drush_shell_exec("mv %s %s", $tmp_path . '/__build__', $tmp_path . '/' . $dirname); + drush_shell_exec("mv %s %s", drush_make_tmp_build_path(), $tmp_path . '/' . $dirname) // Only move the tar file to it's final location if it's been built // successfully. if (drush_shell_exec("tar -C %s -Pczf %s %s", $tmp_path, $tmp_path . '/' . $filename, $dirname)) { drush_shell_exec("mv %s %s", $tmp_path . '/' . $filename, $build_path); }; // Move the build directory back to it's original location for consistency. - drush_shell_exec("mv %s %s", $tmp_path . '/' . $dirname, $tmp_path . '/__build__'); + drush_shell_exec("mv %s %s", $tmp_path . '/' . $dirname, drush_make_tmp_build_path()); } /**