Permalink
Browse files

Snapshot improvements

- Snapshots are now stored on disk so they can be reused, tmpwatch can
  be used to clean up
- .tar.{gz,xz,bz2} snapshots are now supported
- Snapshot dir and format are configurable in the gitalist config
- shortlog/longlog now contain links to snapshots, defaulting to bz2
- Use the abbreviated sha1 in the snapshot filename and directory name
  like gitweb does
  • Loading branch information...
1 parent 4837a63 commit 723a8f6521044e7de3208f15e58a88fed9b6a8ca @seveas committed Jul 27, 2012
Showing with 55 additions and 13 deletions.
  1. +0 −1 ISSUES
  2. +5 −0 gitalist.conf
  3. +7 −4 lib/Gitalist/Controller/Ref.pm
  4. +38 −7 lib/Gitalist/Git/Repository.pm
  5. +1 −0 root/fragment/repository/shortlog.tt2
  6. +4 −1 root/static/css/core.css
View
@@ -4,4 +4,3 @@
* Gitweb compat URIs are borked - there were some I just wholesale ripped out. Put back..
* Sort out commitdiff so conflicted merges have an equivalent display to gitweb (d7f39bebabeb31ce9a7b4f1b6f3db9f391b78c3e as a reference)
* Need to sanitise the input ...
-* The snapshot action does not properly support tgz - requests for this format will receive a tar. tbz2 is not supported at all (yet).
View
@@ -20,3 +20,8 @@ sitename "A Gitalist"
<patches>
max = 16
</patches>
+
+<snapshot>
+ format = tar.bz2
+ tmpdir = /tmp/gitalist/snapshot
+</snapshot>
@@ -49,15 +49,18 @@ Provides a snapshot of a given commit.
sub snapshot : Chained('find') PathPart('snapshot') Args() {
my ($self, $c, $format) = @_;
- $format ||= 'tgz';
+ $format ||= Gitalist->config->{snapshot}{format} || "tar.bz2";
my @snap = $c->stash->{Repository}->snapshot(
sha1 => $c->stash->{Commit}->sha1,
format => $format
);
$c->response->status(200);
- $c->response->headers->header( 'Content-Disposition' =>
- "attachment; filename=$snap[0]");
- $c->response->body($snap[1]);
+ $c->response->content_type($snap[0]);
+ $c->response->content_length(-s $snap[2]);
+ $c->response->headers->header('Content-Disposition' =>
+ "attachment; filename=$snap[1]");
+ open(my $fh, '<', $snap[2]);
+ $c->response->body($fh);
}
=head2 patch
@@ -12,6 +12,9 @@ class Gitalist::Git::Repository with (Gitalist::Git::HasUtils, Gitalist::Git::Se
use aliased 'DateTime' => 'DT';
use List::MoreUtils qw/any zip/;
use Encode qw/decode/;
+ use IPC::Run qw/run/;
+ use File::Spec qw/catfile/;
+ use File::Path qw/mkpath/;
use if $^O ne 'MSWin32' => 'I18N::Langinfo', qw/langinfo CODESET/;
@@ -150,20 +153,48 @@ class Gitalist::Git::Repository with (Gitalist::Git::HasUtils, Gitalist::Git::Se
NonEmptySimpleStr :$format
) {
# TODO - only valid formats are 'tar' and 'zip'
- my $formats = { tgz => 'tar', zip => 'zip' };
+ my $formats = {
+ 'tar.gz' => 'tar',
+ 'tar.bz2' => 'tar',
+ zip => 'zip',
+ };
+ my $compressors = {
+ 'tar.gz' => 'gzip',
+ 'tar.bz2' => 'bzip2',
+ 'tar.xz' => 'xz',
+ };
+ my $mimetypes = {
+ 'tar.gz' => 'application/x-gzip',
+ 'tar.bz2' => 'application/x-bzip2',
+ 'tar.xz' => 'application/octet-stream',
+ };
unless ($formats->exists($format)) {
die("No such format: $format");
}
- $format = $formats->{$format};
+ my $ga_format = $formats->{$format};
my $name = $self->name;
$name =~ s,([^/])/*\.git$,$1,;
- my $filename = $name;
- $filename .= "-$sha1.$format";
+ my $sha1_abbrev = $self->run_cmd(('log', '--pretty=format:%h', '-1', $sha1));
+ my $filename = "$name-$sha1_abbrev.$format";
+ my $ga_filename = "$name-$sha1_abbrev.$ga_format";
$name =~ s/\047/\047\\\047\047/g;
- my @cmd = ('archive', "--format=$format", "--prefix=$name/", $sha1);
- return ($filename, $self->run_cmd_fh(@cmd));
- # TODO - support compressed archives
+ my $local_dir = Gitalist->config->{snapshot}{tmpdir} || "/tmp/gitalist/snapshot";
+ $local_dir = File::Spec->catfile($local_dir, substr($sha1,0,2), substr($sha1,0,4));
+ my $local_filename = File::Spec->catfile($local_dir, $filename);
+ my $local_ga_filename = File::Spec->catfile($local_dir, $ga_filename);
+ if(!-e $local_filename) {
+ if(! -e $local_dir) {
+ mkpath($local_dir, 0, 0755);
+ }
+ my @cmd = ('archive', "--format=$ga_format", "--prefix=$name-$sha1_abbrev/", $sha1, "--output=$local_ga_filename");
+ $self->run_cmd(@cmd);
+ if($compressors->exists($format)) {
+ run [$compressors->{$format}, $local_ga_filename];
+ }
+ }
+
+ return ($mimetypes->{$format}, $filename, $local_filename);
}
method reflog (@logargs) {
@@ -33,6 +33,7 @@
<a href="[% c.uri_for_action("/ref/commit", [Repository.name, line.sha1]) %]" title="Commit details" class="button commit">commit</a>
<a href="[% c.uri_for_action("/ref/diff_fancy", [Repository.name, line.sha1]) %]" title="Commit difference" class="button diff">commitdiff</a>
<a href="[% c.uri_for_action("/ref/tree", [Repository.name, line.sha1]) %]" title="Tree" class="button tree">tree</a>
+ <a href="[% c.uri_for_action("/ref/snapshot", [Repository.name, line.sha1]) %]" title="Snapshot" class="button snapshot">snapshot</a>
</td>
</tr>
[% END %]
@@ -258,6 +258,9 @@ a.longlog{
a.blob{
background:transparent url([% c.uri_for('/static/i/icons/blob.png') %]) no-repeat;
}
+a.snapshot{
+ background:transparent url([% c.uri_for('/static/i/icons/blob.png') %]) no-repeat;
+}
a.blame{
background:transparent url([% c.uri_for('/static/i/icons/blame.png') %]) no-repeat;
}
@@ -444,7 +447,7 @@ BUT the final width needs to be set with javascript based on the parent element
*/
.action-list{
- width:120px;
+ width:160px;
}
.diff-tree{

0 comments on commit 723a8f6

Please sign in to comment.