diff --git a/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php b/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php new file mode 100644 index 0000000..43296c3 --- /dev/null +++ b/Mage/Task/BuiltIn/Deployment/Strategy/GitRemoteCacheTask.php @@ -0,0 +1,137 @@ + + */ +class GitRemoteCacheTask extends AbstractTask implements IsReleaseAware +{ + /** + * Returns the Title of the Task + * @return string + */ + public function getName() + { + return 'Deploy via remote cached git repository [built-in]'; + } + + /** + * Runs the task + * + * @return boolean + * @throws Exception + * @throws ErrorWithMessageException + * @throws SkipException + */ + public function run() + { + $overrideRelease = $this->getParameter('overrideRelease', false); + + if ($overrideRelease == true) { + $releaseToOverride = false; + $resultFetch = $this->runCommandRemote('ls -ld current | cut -d"/" -f2', $releaseToOverride); + if ($resultFetch && is_numeric($releaseToOverride)) { + $this->getConfig()->setReleaseId($releaseToOverride); + } + } + + $excludes = array( + '.git', + '.svn', + '.mage', + '.gitignore', + '.gitkeep', + 'nohup.out' + ); + + // Look for User Excludes + $userExcludes = $this->getConfig()->deployment('excludes', array()); + + $deployToDirectory = $this->getConfig()->deployment('to'); + if ($this->getConfig()->release('enabled', false) == true) { + $releasesDirectory = $this->getConfig()->release('directory', 'releases'); + + $deployToDirectory = rtrim($this->getConfig()->deployment('to'), '/') + . '/' . $releasesDirectory + . '/' . $this->getConfig()->getReleaseId(); + $this->runCommandRemote('mkdir -p ' . $releasesDirectory . '/' . $this->getConfig()->getReleaseId()); + } + + $branch = $this->getParameter('branch'); + $remote = $this->getParameter('remote', 'origin'); + + $remoteCacheParam = $this->getParameter('remote_cache', 'shared/git-remote-cache'); + $remoteCacheFolder = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $remoteCacheParam; + + // Don't use -C as git 1.7 does not support it + $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git fetch ' . $remote; + $result = $this->runCommandRemote($command); + + $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git checkout ' . $branch; + $result = $this->runCommandRemote($command) && $result; + + $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git pull --rebase ' . $branch; + $result = $this->runCommandRemote($command) && $result; + + $excludes = array_merge($excludes, $userExcludes); + $excludeCmd = ''; + foreach ($excludes as $excludeFile) { + $excludeCmd .= ' --exclude=' . $excludeFile; + } + + $command = 'cd ' . $remoteCacheFolder . ' && /usr/bin/env git archive ' . $branch . ' | tar -x -C ' . $deployToDirectory . ' ' . $excludeCmd; + $result = $this->runCommandRemote($command) && $result; + + // Count Releases + if ($this->getConfig()->release('enabled', false) == true) { + $releasesDirectory = $this->getConfig()->release('directory', 'releases'); + $symlink = $this->getConfig()->release('symlink', 'current'); + + if (substr($symlink, 0, 1) == '/') { + $releasesDirectory = rtrim($this->getConfig()->deployment('to'), '/') . '/' . $releasesDirectory; + } + + $maxReleases = $this->getConfig()->release('max', false); + if (($maxReleases !== false) && ($maxReleases > 0)) { + $releasesList = ''; + $countReleasesFetch = $this->runCommandRemote('ls -1 ' . $releasesDirectory, $releasesList); + $releasesList = trim($releasesList); + + if ($countReleasesFetch && $releasesList != '') { + $releasesList = explode(PHP_EOL, $releasesList); + if (count($releasesList) > $maxReleases) { + $releasesToDelete = array_diff($releasesList, array($this->getConfig()->getReleaseId())); + sort($releasesToDelete); + $releasesToDeleteCount = count($releasesToDelete) - $maxReleases; + $releasesToDelete = array_slice($releasesToDelete, 0, $releasesToDeleteCount + 1); + + foreach ($releasesToDelete as $releaseIdToDelete) { + $directoryToDelete = $releasesDirectory . '/' . $releaseIdToDelete; + if ($directoryToDelete != '/') { + $command = 'rm -rf ' . $directoryToDelete; + $result = $result && $this->runCommandRemote($command); + } + } + } + } + } + } + + return $result; + } +}