git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Matt McCutchen <hashproduct@gmail.com>
To: git@vger.kernel.org
Subject: [PATCH] gitweb: snapshot cleanups & support for offering multiple formats
Date: Thu, 28 Jun 2007 14:02:13 -0400	[thread overview]
Message-ID: <1183053733.6108.0.camel@mattlaptop2> (raw)

- Centralize knowledge about snapshot formats (mime types, extensions,
  commands) in %known_snapshot_formats and improve how some of that
  information is specified.  In particular, zip files are no longer a
  special case.

- Add support for offering multiple snapshot formats to the user so
  that he/she can download a snapshot in the format he/she prefers.
  The site-wide or project configuration now gives a list of formats
  to offer, and the "_snapshot_" link is replaced with, say,
  "snapshot (_tbz2_ _zip_)".

- Fix out-of-date "tarball" -> "archive" in comment.

Signed-off-by: Matt McCutchen <hashproduct@gmail.com>
---

I implemented this a while ago for my Web site.  You can see it in action at:

http://www.kepreon.com/~matt/mgear/mgear.git/

I thought I would submit it to the main project so you can adopt it if you like
it.

Matt

 gitweb/gitweb.perl |   89 +++++++++++++++++++++++++++++----------------------
 1 files changed, 51 insertions(+), 38 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index dbfb044..f36428e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -101,6 +101,15 @@ our $mimetypes_file = undef;
 # could be even 'utf-8' for the old behavior)
 our $fallback_encoding = 'latin1';
 
+# information about snapshot formats that gitweb is capable of serving
+# name => [mime type, filename suffix, --format for git-archive,
+#          compressor command suffix]
+our %known_snapshot_formats = (
+	'tgz'  => ['application/x-gzip' , '.tar.gz' , 'tar', '| gzip' ],
+	'tbz2' => ['application/x-bzip2', '.tar.bz2', 'tar', '| bzip2'],
+	'zip'  => ['application/zip'    , '.zip'    , 'zip', ''       ],
+);
+
 # You define site-wide feature defaults here; override them with
 # $GITWEB_CONFIG as necessary.
 our %feature = (
@@ -131,20 +140,22 @@ our %feature = (
 		'override' => 0,
 		'default' => [0]},
 
-	# Enable the 'snapshot' link, providing a compressed tarball of any
+	# Enable the 'snapshot' link, providing a compressed archive of any
 	# tree. This can potentially generate high traffic if you have large
 	# project.
 
+	# Value is a list of formats defined in %known_snapshot_formats that
+	# you wish to offer.
 	# To disable system wide have in $GITWEB_CONFIG
-	# $feature{'snapshot'}{'default'} = [undef];
+	# $feature{'snapshot'}{'default'} = [];
 	# To have project specific config enable override in $GITWEB_CONFIG
 	# $feature{'snapshot'}{'override'} = 1;
-	# and in project config gitweb.snapshot = none|gzip|bzip2|zip;
+	# and in project config, a comma-separated list of formats or "none"
+	# to disable.  Example: gitweb.snapshot = tbz2,zip;
 	'snapshot' => {
 		'sub' => \&feature_snapshot,
 		'override' => 0,
-		#         => [content-encoding, suffix, program]
-		'default' => ['x-gzip', 'gz', 'gzip']},
+		'default' => ['tgz']},
 
 	# Enable text search, which will list the commits which match author,
 	# committer or commit text to a given string.  Enabled by default.
@@ -243,28 +254,15 @@ sub feature_blame {
 }
 
 sub feature_snapshot {
-	my ($ctype, $suffix, $command) = @_;
+	my (@fmts) = @_;
 
 	my ($val) = git_get_project_config('snapshot');
 
-	if ($val eq 'gzip') {
-		return ('x-gzip', 'gz', 'gzip');
-	} elsif ($val eq 'bzip2') {
-		return ('x-bzip2', 'bz2', 'bzip2');
-	} elsif ($val eq 'zip') {
-		return ('x-zip', 'zip', '');
-	} elsif ($val eq 'none') {
-		return ();
+	if ($val) {
+		@fmts = ($val eq 'none' ? () : split /,/, $val);
 	}
 
-	return ($ctype, $suffix, $command);
-}
-
-sub gitweb_have_snapshot {
-	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
-	my $have_snapshot = (defined $ctype && defined $suffix);
-
-	return $have_snapshot;
+	return grep exists $known_snapshot_formats{$_}, @fmts;
 }
 
 sub feature_grep {
@@ -542,6 +540,7 @@ sub href(%) {
 		order => "o",
 		searchtext => "s",
 		searchtype => "st",
+		snapshot_format => "sf",
 	);
 	my %mapping = @mapping;
 
@@ -1236,6 +1235,21 @@ sub format_diff_line {
 	return "<div class=\"diff$diff_class\">" . esc_html($line, -nbsp=>1) . "</div>\n";
 }
 
+# Generates undef or something like "snapshot (tbz2 zip)", linked.
+# Pass the hash.
+sub format_snapshot_links {
+	my ($hash) = @_;
+	my @snapshot_fmts = gitweb_check_feature('snapshot');
+	if (@snapshot_fmts) {
+		return "snapshot (" . join(' ', map $cgi->a(
+			{-href => href(action=>"snapshot", hash=>$hash, snapshot_format=>$_)}, "$_"),
+			@snapshot_fmts)
+		. ")";
+	} else {
+		return undef;
+	}
+}
+
 ## ----------------------------------------------------------------------
 ## git utility subroutines, invoking git commands
 
@@ -3280,8 +3294,6 @@ sub git_shortlog_body {
 	# uses global variable $project
 	my ($commitlist, $from, $to, $refs, $extra) = @_;
 
-	my $have_snapshot = gitweb_have_snapshot();
-
 	$from = 0 unless defined $from;
 	$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
 
@@ -3308,8 +3320,9 @@ sub git_shortlog_body {
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
 		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . " | " .
 		      $cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree");
-		if ($have_snapshot) {
-			print " | " . $cgi->a({-href => href(action=>"snapshot", hash=>$commit)}, "snapshot");
+		my $snapshot_links = format_snapshot_links($commit);
+		if (defined $snapshot_links) {
+			print " | " . $snapshot_links;
 		}
 		print "</td>\n" .
 		      "</tr>\n";
@@ -4194,11 +4207,16 @@ sub git_tree {
 }
 
 sub git_snapshot {
-	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
-	my $have_snapshot = (defined $ctype && defined $suffix);
-	if (!$have_snapshot) {
-		die_error('403 Permission denied', "Permission denied");
+	my @supported_fmts = gitweb_check_feature('snapshot');
+
+	my $format = $cgi->param('sf');
+	unless ($format =~ m/[a-z0-9]+/
+		&& exists($known_snapshot_formats{$format})
+		&& grep($_ eq $format, @supported_fmts)) {
+		die_error(undef, "Unsupported snapshot format");
 	}
+	my ($ctype, $suffix, $ga_format, $pipe_compressor) =
+		@{$known_snapshot_formats{$format}};
 
 	if (!defined $hash) {
 		$hash = git_get_head_hash($project);
@@ -4211,16 +4229,11 @@ sub git_snapshot {
 	my $filename = to_utf8($name);
 	$name =~ s/\047/\047\\\047\047/g;
 	my $cmd;
-	if ($suffix eq 'zip') {
-		$filename .= "-$hash.$suffix";
-		$cmd = "$git archive --format=zip --prefix=\'$name\'/ $hash";
-	} else {
-		$filename .= "-$hash.tar.$suffix";
-		$cmd = "$git archive --format=tar --prefix=\'$name\'/ $hash | $command";
-	}
+	$filename .= "-$hash$suffix";
+	$cmd = "$git archive --format=$ga_format --prefix=\'$name\'/ $hash $pipe_compressor";
 
 	print $cgi->header(
-		-type => "application/$ctype",
+		-type => "$ctype",
 		-content_disposition => 'inline; filename="' . "$filename" . '"',
 		-status => '200 OK');
 
-- 
1.5.2.2.552.gc32f

             reply	other threads:[~2007-06-28 18:02 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-28 18:02 Matt McCutchen [this message]
2007-07-07 20:52 ` [PATCH] gitweb: snapshot cleanups & support for offering multiple formats Junio C Hamano
2007-07-08  9:06   ` Junio C Hamano
2007-07-11 15:55   ` Jakub Narebski
2007-07-11 21:26     ` Junio C Hamano
2007-07-12  1:15       ` Matt McCutchen
2007-07-12 11:07         ` Jakub Narebski
2007-07-17 18:03           ` Matt McCutchen
2007-07-17 19:11             ` Matt McCutchen
2007-07-18 23:40               ` Jakub Narebski
2007-07-19  1:12                 ` Junio C Hamano
2007-07-19  3:30                   ` Luben Tuikov
2007-07-19  7:30                     ` Jakub Narebski
2007-07-19  7:40                       ` Luben Tuikov
2007-07-25 18:39                         ` [RFC/PATCH] gitweb: Enable transparent compression form HTTP output Jakub Narebski
2007-08-25 18:03                           ` Petr Baudis
2007-08-25 22:09                             ` Jakub Narebski
2007-08-25 22:14                               ` Petr Baudis
2007-08-27 11:01                                 ` Jakub Narebski
2007-07-19  9:05                   ` [PATCH] gitweb: snapshot cleanups & support for offering multiple formats Jakub Narebski
2007-07-20  4:29                     ` Junio C Hamano
2007-07-19  9:14               ` Jakub Narebski
2007-07-21 23:30               ` Jakub Narebski
2007-07-22  5:26                 ` Junio C Hamano
2007-07-22 15:05                   ` Matt McCutchen
2007-07-22 21:41                     ` [PATCH] gitweb: Fix support for legacy gitweb config for snapshots Jakub Narebski
2007-07-22 23:10                       ` Matt McCutchen
2007-07-22 23:35                         ` Junio C Hamano
2007-07-08 21:54 ` [PATCH] gitweb: snapshot cleanups & support for offering multiple formats Junio C Hamano
2007-07-09 22:52   ` Matt McCutchen
2007-07-09 23:21     ` Matt McCutchen
2007-07-10 23:41       ` Jakub Narebski
2007-07-09 23:48     ` Junio C Hamano
2007-07-10  1:14       ` Matt McCutchen
2007-07-10  1:14       ` Matt McCutchen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1183053733.6108.0.camel@mattlaptop2 \
    --to=hashproduct@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).