diff --git a/src/IDF/Git.php b/src/IDF/Git.php index 09a3791..0fb373a 100644 --- a/src/IDF/Git.php +++ b/src/IDF/Git.php @@ -301,4 +301,19 @@ class IDF_Git return $res; } + /** + * Generate the command to create a zip archive at a given commit. + * + * @param string Commit + * @param string Prefix ('git-repo-dump') + * @return string Command + */ + public function getArchiveCommand($commit, $prefix='git-repo-dump/') + { + return sprintf('GIT_DIR=%s git archive --format=zip --prefix=%s %s', + escapeshellarg($this->repo), + escapeshellarg($prefix), + escapeshellarg($commit)); + } + } \ No newline at end of file diff --git a/src/IDF/Views/Source.php b/src/IDF/Views/Source.php index ce7188d..7cff9dc 100644 --- a/src/IDF/Views/Source.php +++ b/src/IDF/Views/Source.php @@ -148,7 +148,6 @@ class IDF_Views_Source public function commit($request, $match) { - $git = new IDF_Git(Pluf::f('git_repository')); $commit = $match[2]; $branches = $git->getBranches(); @@ -176,7 +175,29 @@ class IDF_Views_Source $request); } - + /** + * Get a zip archive of the current commit. + * + */ + public function download($request, $match) + { + $commit = trim($match[2]); + $git = new IDF_Git(Pluf::f('git_repository')); + $branches = $git->getBranches(); + if ('commit' != $git->testHash($commit)) { + // Redirect to the first branch + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', + array($request->project->shortname, + $branches[0])); + return new Pluf_HTTP_Response_Redirect($url); + } + $base = $request->project->shortname.'-'.$commit; + $cmd = $git->getArchiveCommand($commit, $base.'/'); + $rep = new Pluf_HTTP_Response_CommandPassThru($cmd, 'application/x-zip'); + $rep->headers['Content-Transfer-Encoding'] = 'binary'; + $rep->headers['Content-Disposition'] = 'attachment; filename="'.$base.'.zip"'; + return $rep; + } } function IDF_Views_Source_PrettySize($size) diff --git a/src/IDF/conf/views.php b/src/IDF/conf/views.php index 3db9523..d47cc6a 100644 --- a/src/IDF/conf/views.php +++ b/src/IDF/conf/views.php @@ -141,6 +141,12 @@ $ctl[] = array('regex' => '#^/p/(\w+)/source/commit/(\w+)/$#', 'model' => 'IDF_Views_Source', 'method' => 'commit'); +$ctl[] = array('regex' => '#^/p/(\w+)/source/download/(\w+)/$#', + 'base' => $base, + 'priority' => 4, + 'model' => 'IDF_Views_Source', + 'method' => 'download'); + // ---------- ADMIN -------------------------------------- diff --git a/src/IDF/templates/source/tree.html b/src/IDF/templates/source/tree.html index eee2bd2..3430c89 100644 --- a/src/IDF/templates/source/tree.html +++ b/src/IDF/templates/source/tree.html @@ -2,6 +2,7 @@ {block docclass}yui-t1{assign $inSourceTree=true}{/block} {block body}

{trans 'Root'}/{if $breadcrumb}{$breadcrumb|safe}{/if}

+ @@ -41,6 +42,8 @@ {/foreach}
+{aurl 'url', 'IDF_Views_Source::download', array($project.shortname, $commit)} +

{trans 'Archive'} {trans 'Download this version'}

{/block} {block context} diff --git a/www/media/idf/img/package.png b/www/media/idf/img/package.png new file mode 100644 index 0000000..9015426 Binary files /dev/null and b/www/media/idf/img/package.png differ