git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* gitweb: Support for snapshot
@ 2006-08-17 15:29 Aneesh Kumar K.V
  2006-08-18  5:06 ` [PATCH] " Aneesh Kumar K.V
  0 siblings, 1 reply; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-17 15:29 UTC (permalink / raw)
  To: git

This adds snapshort support in gitweb. To enable one need to
set gitweb.snapshot = true in the config file.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@hp.com>
---
 gitweb/gitweb.perl |   41 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 04282fa..52653a0 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -15,6 +15,7 @@ use CGI::Carp qw(fatalsToBrowser);
 use Encode;
 use Fcntl ':mode';
 use File::Find qw();
+use File::Basename qw(basename);
 binmode STDOUT, ':utf8';
 
 our $cgi = new CGI;
@@ -175,6 +176,7 @@ my %actions = (
 	"tag" => \&git_tag,
 	"tags" => \&git_tags,
 	"tree" => \&git_tree,
+	"snapshot" => \&git_snapshot,
 );
 
 $action = 'summary' if (!defined($action));
@@ -1320,6 +1322,7 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
+	my $have_snapshot = git_get_project_config_bool('snapshot');
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1344,8 +1347,11 @@ sub git_shortlog_body {
 		print "</td>\n" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
-		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
-		      "</td>\n" .
+		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff");
+		if ($have_snapshot) {
+			print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$commit)}, "snapshot");
+		}
+		print "</td>\n" .
 		      "</tr>\n";
 	}
 	if (defined $extra) {
@@ -2112,6 +2118,29 @@ sub git_tree {
 	git_footer_html();
 }
 
+sub git_snapshot {
+
+	if (!defined $hash) {
+		$hash = git_get_head_hash($project);
+	}
+
+	my $filename = basename($project) . "-$hash.tar.gz";
+
+	print $cgi->header(-type => 'application/x-tar',
+			-content-encoding => 'gzip',
+			'-content-disposition' => "inline; filename=\"$filename\"",
+			-status => '200 OK');
+
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
+				die_error(undef, "Execute git-tar-tree failed.");
+	binmode STDOUT, ':raw';
+	print <$fd>;
+	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
+	close $fd;
+
+
+}
+
 sub git_log {
 	my $head = git_get_head_hash($project);
 	if (!defined $hash) {
@@ -2206,6 +2235,7 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
+	my $have_snapshot = git_get_project_config_bool('snapshot');
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};
@@ -2241,8 +2271,11 @@ sub git_commit {
 	      "<td class=\"sha1\">" .
 	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash), class => "list"}, $co{'tree'}) .
 	      "</td>" .
-	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree") .
-	      "</td>" .
+	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree");
+	if ($have_snapshot) {
+		print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot");
+	}
+	print "</td>" .
 	      "</tr>\n";
 	my $parents = $co{'parents'};
 	foreach my $par (@$parents) {
-- 
1.4.2.rc1.g83e1-dirty

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH] gitweb: Support for snapshot
  2006-08-17 15:29 gitweb: Support for snapshot Aneesh Kumar K.V
@ 2006-08-18  5:06 ` Aneesh Kumar K.V
  2006-08-18 19:51   ` Luben Tuikov
  0 siblings, 1 reply; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-18  5:06 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 214 bytes --]

Now I read RFC 2616  the content-encoding need to be specified as x-gzip. 
Also i am not sure whether the fact that it is registered with IANA exempt us from
adding it to html header.

The corrected patch below. 


[-- Attachment #2: 0001-gitweb-Support-for-snapshot.txt --]
[-- Type: text/plain, Size: 3423 bytes --]


This adds snapshort support in gitweb. To enable one need to
set gitweb.snapshot = true in the config file.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
---
 gitweb/gitweb.perl |   41 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 04282fa..d6f96a3 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -15,6 +15,7 @@ use CGI::Carp qw(fatalsToBrowser);
 use Encode;
 use Fcntl ':mode';
 use File::Find qw();
+use File::Basename qw(basename);
 binmode STDOUT, ':utf8';
 
 our $cgi = new CGI;
@@ -175,6 +176,7 @@ my %actions = (
 	"tag" => \&git_tag,
 	"tags" => \&git_tags,
 	"tree" => \&git_tree,
+	"snapshot" => \&git_snapshot,
 );
 
 $action = 'summary' if (!defined($action));
@@ -1320,6 +1322,7 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
+	my $have_snapshot = git_get_project_config_bool('snapshot');
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1344,8 +1347,11 @@ sub git_shortlog_body {
 		print "</td>\n" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
-		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
-		      "</td>\n" .
+		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff");
+		if ($have_snapshot) {
+			print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$commit)}, "snapshot");
+		}
+		print "</td>\n" .
 		      "</tr>\n";
 	}
 	if (defined $extra) {
@@ -2112,6 +2118,29 @@ sub git_tree {
 	git_footer_html();
 }
 
+sub git_snapshot {
+
+	if (!defined $hash) {
+		$hash = git_get_head_hash($project);
+	}
+
+	my $filename = basename($project) . "-$hash.tar.gz";
+
+	print $cgi->header(-type => 'application/x-tar',
+			-content-encoding => 'x-gzip',
+			'-content-disposition' => "inline; filename=\"$filename\"",
+			-status => '200 OK');
+
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
+				die_error(undef, "Execute git-tar-tree failed.");
+	binmode STDOUT, ':raw';
+	print <$fd>;
+	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
+	close $fd;
+
+
+}
+
 sub git_log {
 	my $head = git_get_head_hash($project);
 	if (!defined $hash) {
@@ -2206,6 +2235,7 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
+	my $have_snapshot = git_get_project_config_bool('snapshot');
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};
@@ -2241,8 +2271,11 @@ sub git_commit {
 	      "<td class=\"sha1\">" .
 	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash), class => "list"}, $co{'tree'}) .
 	      "</td>" .
-	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree") .
-	      "</td>" .
+	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree");
+	if ($have_snapshot) {
+		print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot");
+	}
+	print "</td>" .
 	      "</tr>\n";
 	my $parents = $co{'parents'};
 	foreach my $par (@$parents) {
-- 
1.4.2.rc1.g83e1-dirty


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-18  5:06 ` [PATCH] " Aneesh Kumar K.V
@ 2006-08-18 19:51   ` Luben Tuikov
  2006-08-18 20:05     ` Timo Hirvonen
       [not found]     ` <7v64gp7prk.fsf@assigned-by-dhcp.cox.net>
  0 siblings, 2 replies; 14+ messages in thread
From: Luben Tuikov @ 2006-08-18 19:51 UTC (permalink / raw)
  To: Aneesh Kumar K.V, git

--- "Aneesh Kumar K.V" <aneesh.kumar@gmail.com> wrote:
> This adds snapshort support in gitweb. To enable one need to
> set gitweb.snapshot = true in the config file.

Could you use bzip2?  It generates smaller files (better compression),
which is a good thing when downloading over a network.

   Luben

> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
> ---
>  gitweb/gitweb.perl |   41 +++++++++++++++++++++++++++++++++++++----
>  1 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 04282fa..d6f96a3 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -15,6 +15,7 @@ use CGI::Carp qw(fatalsToBrowser);
>  use Encode;
>  use Fcntl ':mode';
>  use File::Find qw();
> +use File::Basename qw(basename);
>  binmode STDOUT, ':utf8';
>  
>  our $cgi = new CGI;
> @@ -175,6 +176,7 @@ my %actions = (
>  	"tag" => \&git_tag,
>  	"tags" => \&git_tags,
>  	"tree" => \&git_tree,
> +	"snapshot" => \&git_snapshot,
>  );
>  
>  $action = 'summary' if (!defined($action));
> @@ -1320,6 +1322,7 @@ sub git_difftree_body {
>  sub git_shortlog_body {
>  	# uses global variable $project
>  	my ($revlist, $from, $to, $refs, $extra) = @_;
> +	my $have_snapshot = git_get_project_config_bool('snapshot');
>  	$from = 0 unless defined $from;
>  	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
>  
> @@ -1344,8 +1347,11 @@ sub git_shortlog_body {
>  		print "</td>\n" .
>  		      "<td class=\"link\">" .
>  		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
> -		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
> -		      "</td>\n" .
> +		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff");
> +		if ($have_snapshot) {
> +			print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$commit)}, "snapshot");
> +		}
> +		print "</td>\n" .
>  		      "</tr>\n";
>  	}
>  	if (defined $extra) {
> @@ -2112,6 +2118,29 @@ sub git_tree {
>  	git_footer_html();
>  }
>  
> +sub git_snapshot {
> +
> +	if (!defined $hash) {
> +		$hash = git_get_head_hash($project);
> +	}
> +
> +	my $filename = basename($project) . "-$hash.tar.gz";
> +
> +	print $cgi->header(-type => 'application/x-tar',
> +			-content-encoding => 'x-gzip',
> +			'-content-disposition' => "inline; filename=\"$filename\"",
> +			-status => '200 OK');
> +
> +	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
> +				die_error(undef, "Execute git-tar-tree failed.");
> +	binmode STDOUT, ':raw';
> +	print <$fd>;
> +	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
> +	close $fd;
> +
> +
> +}
> +
>  sub git_log {
>  	my $head = git_get_head_hash($project);
>  	if (!defined $hash) {
> @@ -2206,6 +2235,7 @@ sub git_commit {
>  	}
>  	my $refs = git_get_references();
>  	my $ref = format_ref_marker($refs, $co{'id'});
> +	my $have_snapshot = git_get_project_config_bool('snapshot');
>  	my $formats_nav = '';
>  	if (defined $file_name && defined $co{'parent'}) {
>  		my $parent = $co{'parent'};
> @@ -2241,8 +2271,11 @@ sub git_commit {
>  	      "<td class=\"sha1\">" .
>  	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash), class =>
> "list"}, $co{'tree'}) .
>  	      "</td>" .
> -	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'},
> hash_base=>$hash)}, "tree") .
> -	      "</td>" .
> +	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'},
> hash_base=>$hash)}, "tree");
> +	if ($have_snapshot) {
> +		print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot");
> +	}
> +	print "</td>" .
>  	      "</tr>\n";
>  	my $parents = $co{'parents'};
>  	foreach my $par (@$parents) {
> -- 
> 1.4.2.rc1.g83e1-dirty
> 
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-18 19:51   ` Luben Tuikov
@ 2006-08-18 20:05     ` Timo Hirvonen
       [not found]     ` <7v64gp7prk.fsf@assigned-by-dhcp.cox.net>
  1 sibling, 0 replies; 14+ messages in thread
From: Timo Hirvonen @ 2006-08-18 20:05 UTC (permalink / raw)
  To: Luben Tuikov; +Cc: aneesh.kumar, git

Luben Tuikov <ltuikov@yahoo.com> wrote:

> --- "Aneesh Kumar K.V" <aneesh.kumar@gmail.com> wrote:
> > This adds snapshort support in gitweb. To enable one need to
> > set gitweb.snapshot = true in the config file.
> 
> Could you use bzip2?  It generates smaller files (better compression),
> which is a good thing when downloading over a network.

bzip2 is much slower than gzip.  Often just uncompressing .tar.bz2 takes
more time than downloading bigger .tar.gz file.  For small projects it
doesn't matter which one you use.

-- 
http://onion.dynserv.net/~timo/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
       [not found]     ` <7v64gp7prk.fsf@assigned-by-dhcp.cox.net>
@ 2006-08-19  8:10       ` Aneesh Kumar
  2006-08-19 10:51         ` Junio C Hamano
  0 siblings, 1 reply; 14+ messages in thread
From: Aneesh Kumar @ 2006-08-19  8:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Luben Tuikov, git, jakub narebski

[-- Attachment #1: Type: text/plain, Size: 958 bytes --]

On 8/19/06, Junio C Hamano <junkio@cox.net> wrote:
> Luben Tuikov <ltuikov@yahoo.com> writes:
>
> > --- "Aneesh Kumar K.V" <aneesh.kumar@gmail.com> wrote:
> >> This adds snapshort support in gitweb. To enable one need to
> >> set gitweb.snapshot = true in the config file.
> >
> > Could you use bzip2?  It generates smaller files (better compression),
> > which is a good thing when downloading over a network.
>
> Because bzip2 is heavier on the server than gzip is (and gzip is
> heavier than "gzip -1" is), there obviously is a trade-off.  We
> would want it to be configurable just like blame and snapshot
> itself.
>
> Maybe:
>
>         config.snapshot = no | yes | gzip | bzip2 ...
>
> By the way, I think it is a mistake to use only $GIT_DIR/config
> to control these features.
>

I have coded this at

What should be the content-encoding in this case x-$snapshot ?

This is the untested diff that i have. Is this what we are looking for ?


-aneesh

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch; name="gitweb.diff", Size: 2484 bytes --]

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..6ad3141 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,15 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+# don't enable snapshot support by default
+# possible values are no|gzip|bzip2|
+our $snapshot = "no";
+
+# this indicate whether the snapshot support can be overridden
+# by a project specific config.
+# possible values are yes|no
+our $snapshot_override = "no";
+
 our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
 require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
 
@@ -1397,7 +1406,7 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+	my ($have_snapshot, $snapshot_comp) = git_get_project_snapshot_config();
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -2200,13 +2209,14 @@ sub git_snapshot {
 	}
 
 	my $filename = basename($project) . "-$hash.tar.gz";
+	my ($have_snapshot, $snapshot_comp) = git_get_project_snapshot_config();
 
 	print $cgi->header(-type => 'application/x-tar',
-			-content-encoding => 'x-gzip',
+			-content-encoding => "x-$snapshot_comp",
 			'-content-disposition' => "inline; filename=\"$filename\"",
 			-status => '200 OK');
 
-	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $snapshot_comp" or
 				die_error(undef, "Execute git-tar-tree failed.");
 	binmode STDOUT, ':raw';
 	print <$fd>;
@@ -2215,6 +2225,27 @@ sub git_snapshot {
 
 
 }
+sub git_get_project_snapshot_config()
+{
+	my $snap;
+
+	if ($snapshot =~ m/no/) {
+		return (0, undef);
+	}
+
+	if ($snapshot_override =~ m/no/) {
+		return (1, $snapshot);
+	}
+
+	$snap = git_get_project_config('snapshot');
+
+	if ($snap and $snap =~ m/no/) {
+		return (0, undef);
+	}
+	return (1, $snap);
+}
+
+}
 
 sub git_log {
 	my $head = git_get_head_hash($project);
@@ -2293,7 +2324,7 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+	my ($have_snapshot, $snapshot_comp) = git_get_project_snapshot_config();
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19  8:10       ` Aneesh Kumar
@ 2006-08-19 10:51         ` Junio C Hamano
  2006-08-19 11:09           ` Jakub Narebski
                             ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Junio C Hamano @ 2006-08-19 10:51 UTC (permalink / raw)
  To: Aneesh Kumar; +Cc: Luben Tuikov, git, jakub narebski

What I had in mind is more like this.

 * The global hash %feature defines optional features that site
   administrator can enable (or allow repo-owners to enable).
   The hash is keyed with feature name.

 * The value of the hash is an array whose first two elements
   are a sub and a bool, and the rest of the elements are the
   default values of feature specific parameters.

 * The bool tells gitweb_check_feature if the feature is
   overridable per repository, and the sub is called with the
   rest of elements in the array only when it is overridable.
   The sub should read from the repository config and if the
   values are satisfactory return them; otherwise it should
   throw back the default parameters.

 * When you want to know if a feature with enabled (and with
   what option), you call gitweb_check_feature with the feature
   name.  It will return either the default parameters for the
   feature, or the parameters overridden by the repository.

In the example, I do not allow overriding the setting of
'blame', so calling gitweb_check_feature('blame') would always
return 0 (because the third element of the feature array is that
value).

If you want to allow repositories to override, you put true
value as the second member; then repositories that define their
own gitweb.blame can override the default.

The patch demonstrates the use of overridable configuration;
gitweb.snapshot can be left undefined (to get site-wide
default), or defined to be 'none' (to disable it for the
repository even when site-wide default allows it), or 'gzip', or
'bzip2'.

While I was at it, I got rid of git_get_project_config_bool()
which was poorly designed.  It did not understand various ways
you can spell true and false, and did not distinguish between
defining a variable to false and not having any definition for
the variable.

I did this patch as a demonstration of the overall framework, so
minor details of feature_xxx implementation might be wrong.
Obviously patch is not tested.

But personally, this patch makes things a bit easier to read
(but I am biased -- I wrote it).

---
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..af8867e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,51 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+################################################################
+# Feature configuration.
+# These subs are only called when per repository
+# overrides are allowed.  They take the default options,
+# inspect the repository and return the values from there if
+# the repository wants to override the system default.
+
+sub feature_blame {
+	my ($val) = git_get_project_config('blame', '--bool');
+	if ($val eq 'true') { return 1; }
+	elsif ($val eq 'false') { return 0; }
+
+	return $_[0];
+}
+
+sub feature_snapshot {
+	my ($ctype, $suffix, $command) = @_;
+	my ($val) = git_get_project_config('snapshot');
+	if ($val eq 'gzip') { return ('gzip', 'gz'); }
+	elsif ($val eq 'bzip2') { return ('bzip2', 'bz2'); }
+	elsif ($val eq 'none') { return (); }
+
+	return ($ctype, $suffix, $command);
+}
+
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature = 
+(
+	# feature	=> [feature-sub, allow-override, default options...]
+
+	'blame'		=> [\&feature_blame, 0, 0],
+ 	'snapshot'	=> [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
+);
+
+sub gitweb_check_feature {
+	my ($name) = @_;
+	return undef unless exists $feature{$name};
+	my ($sub, $override, @defaults) = @{$feature{$name}};
+	if (!$override) { return @defaults; }
+	return $sub->(@defaults);
+}
+
+################################################################
+
 our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
 require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
 
@@ -485,24 +530,19 @@ sub git_get_type {
 }
 
 sub git_get_project_config {
-	my $key = shift;
+	my ($key, $type) = @_;
 
 	return unless ($key);
 	$key =~ s/^gitweb\.//;
 	return if ($key =~ m/\W/);
 
-	my $val = qx($GIT repo-config --get gitweb.$key);
+	my @x = ($GIT, 'repo-config', '--get');
+	if (defined $type) { push @x, $type; }
+	push @x, "gitweb.$key";
+	my $val = qx(@x);
 	return ($val);
 }
 
-sub git_get_project_config_bool {
-	my $val = git_get_project_config (@_);
-	if ($val and $val =~ m/true|yes|on/) {
-		return (1);
-	}
-	return; # implicit false
-}
-
 # get hash of given path at given ref
 sub git_get_hash_by_path {
 	my $base = shift;
@@ -1397,7 +1437,10 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1858,7 +1901,10 @@ sub git_tag {
 sub git_blame2 {
 	my $fd;
 	my $ftype;
-	die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error(undef, "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1962,10 @@ sub git_blame2 {
 
 sub git_blame {
 	my $fd;
-	die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error(undef, "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2195,25 +2244,31 @@ 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(undef, "Permission denied");
+	}
+
 	if (!defined $hash) {
 		$hash = git_get_head_hash($project);
 	}
 
-	my $filename = basename($project) . "-$hash.tar.gz";
+	my $filename = basename($project) . "-$hash.tar.$suffix";
 
 	print $cgi->header(-type => 'application/x-tar',
-			-content-encoding => 'x-gzip',
-			'-content-disposition' => "inline; filename=\"$filename\"",
-			-status => '200 OK');
+			   -content-encoding => $ctype,
+			   '-content-disposition' =>
+			   "inline; filename=\"$filename\"",
+			   -status => '200 OK');
 
-	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
-				die_error(undef, "Execute git-tar-tree failed.");
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+		die_error(undef, "Execute git-tar-tree failed.");
 	binmode STDOUT, ':raw';
 	print <$fd>;
 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 
-
 }
 
 sub git_log {

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 10:51         ` Junio C Hamano
@ 2006-08-19 11:09           ` Jakub Narebski
  2006-08-19 11:13           ` Jakub Narebski
  2006-08-19 13:56           ` Aneesh Kumar K.V
  2 siblings, 0 replies; 14+ messages in thread
From: Jakub Narebski @ 2006-08-19 11:09 UTC (permalink / raw)
  To: git

Junio C Hamano wrote:

> +sub feature_snapshot {
> +       my ($ctype, $suffix, $command) = @_;
> +       my ($val) = git_get_project_config('snapshot');
> +       if ($val eq 'gzip') { return ('gzip', 'gz'); }
> +       elsif ($val eq 'bzip2') { return ('bzip2', 'bz2'); }
> +       elsif ($val eq 'none') { return (); }
> +
> +       return ($ctype, $suffix, $command);
> +}

Should it be ('x-gzip', 'gzip', 'gz') and ('x-bzip2', 'bzip2', 'bz2'),
i.e. with $ctype first?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 10:51         ` Junio C Hamano
  2006-08-19 11:09           ` Jakub Narebski
@ 2006-08-19 11:13           ` Jakub Narebski
  2006-08-19 11:58             ` Aneesh Kumar K.V
  2006-08-19 13:56           ` Aneesh Kumar K.V
  2 siblings, 1 reply; 14+ messages in thread
From: Jakub Narebski @ 2006-08-19 11:13 UTC (permalink / raw)
  To: git

Junio C Hamano wrote:

>  * The value of the hash is an array whose first two elements
>    are a sub and a bool, and the rest of the elements are the
>    default values of feature specific parameters.

Which means that it is not that easy to change defaults from 
$GITWEB_CONFIG ($feature{'blame'}->[1] = 1; ?).

And there is no way to enable for example 'blame' support for all
repositories...
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 11:13           ` Jakub Narebski
@ 2006-08-19 11:58             ` Aneesh Kumar K.V
  0 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-19 11:58 UTC (permalink / raw)
  To: git

Jakub Narebski wrote:
> Junio C Hamano wrote:
> 
>>  * The value of the hash is an array whose first two elements
>>    are a sub and a bool, and the rest of the elements are the
>>    default values of feature specific parameters.
> 
> Which means that it is not that easy to change defaults from 
> $GITWEB_CONFIG ($feature{'blame'}->[1] = 1; ?).
> 

how about 

   'blame'         => [\&feature_blame, $feature_blame_override, 0],

and picking only $feature_blame_override from $GITWEB_CONFIG

-aneesh 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 10:51         ` Junio C Hamano
  2006-08-19 11:09           ` Jakub Narebski
  2006-08-19 11:13           ` Jakub Narebski
@ 2006-08-19 13:56           ` Aneesh Kumar K.V
  2006-08-19 14:22             ` Jakub Narebski
  2 siblings, 1 reply; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-19 13:56 UTC (permalink / raw)
  To: git; +Cc: Luben Tuikov, git, jakub narebski

[-- Attachment #1: Type: text/plain, Size: 584 bytes --]

Junio C Hamano wrote:

> 
> I did this patch as a demonstration of the overall framework, so
> minor details of feature_xxx implementation might be wrong.
> Obviously patch is not tested.
> 
> But personally, this patch makes things a bit easier to read
> (but I am biased -- I wrote it).
> 

I tested this and added some comments. I also fixed some code. I am attaching the full diff.
BTW git-repo-config have the below bug. 

$ git repo-config --bool --get gitweb.blame
true
$ git repo-config --get --bool gitweb.blame
$

So i dropped --get from the git_get_project_config

-aneesh

[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6453 bytes --]

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..1037ab9 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,58 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+# Feature configuration.
+# These subs are only called when per repository
+# overrides are allowed.  They take the default options,
+# inspect the repository and return the values from there if
+# the repository wants to override the system default.
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'} =  [\&feature_blame, 0, 1];
+# To disbale project wide 
+# you should have allow-override enabled in  $GITWEB_CONFIG
+# and in project config   gitweb.blame = 0;
+sub feature_blame {
+	my ($val) = git_get_project_config('blame', '--bool');
+	if ($val eq 'true') { return 1; }
+	elsif ($val eq 'false') { return 0; }
+
+	return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'} =  [\&feature_snapshot, 0, undef, undef, undef];
+# To change the  encoding type 
+# you should have allow-override enabled in  $GITWEB_CONFIG
+# and in project config  gitweb.snapshot = bzip2
+sub feature_snapshot {
+	my ($ctype, $suffix, $command) = @_;
+	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 'none') { return (); }
+
+	return ($ctype, $suffix, $command);
+}
+
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+	# feature	=> [feature-sub, allow-override, default options...]
+
+	'blame'		=> [\&feature_blame, 0, 0],
+	'snapshot'	=> [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
+);
+
+sub gitweb_check_feature {
+	my ($name) = @_;
+	return undef unless exists $feature{$name};
+	my ($sub, $override, @defaults) = @{$feature{$name}};
+	if (!$override) { return @defaults; }
+	return $sub->(@defaults);
+}
+
 our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
 require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
 
@@ -485,24 +537,20 @@ sub git_get_type {
 }
 
 sub git_get_project_config {
-	my $key = shift;
+	my ($key, $type) = @_;
 
 	return unless ($key);
 	$key =~ s/^gitweb\.//;
 	return if ($key =~ m/\W/);
 
-	my $val = qx($GIT repo-config --get gitweb.$key);
+	my @x = ($GIT, 'repo-config');
+	if (defined $type) { push @x, $type; }
+	push @x, "gitweb.$key";
+	my $val = qx(@x);
+	chomp $val;
 	return ($val);
 }
 
-sub git_get_project_config_bool {
-	my $val = git_get_project_config (@_);
-	if ($val and $val =~ m/true|yes|on/) {
-		return (1);
-	}
-	return; # implicit false
-}
-
 # get hash of given path at given ref
 sub git_get_hash_by_path {
 	my $base = shift;
@@ -1397,7 +1445,10 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1858,7 +1909,10 @@ sub git_tag {
 sub git_blame2 {
 	my $fd;
 	my $ftype;
-	die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error(undef, "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1970,10 @@ sub git_blame2 {
 
 sub git_blame {
 	my $fd;
-	die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error(undef, "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2126,7 @@ sub git_blob {
 			die_error(undef, "No file name defined");
 		}
 	}
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	open my $fd, "-|", $GIT, "cat-file", "blob", $hash
 		or die_error(undef, "Couldn't cat $file_name, $hash");
 	my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2191,7 @@ sub git_tree {
 	git_header_html();
 	my %base_key = ();
 	my $base = "";
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	if (defined $hash_base && (my %co = parse_commit($hash_base))) {
 		$base_key{hash_base} = $hash_base;
 		git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2252,31 @@ 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(undef, "Permission denied");
+	}
+
 	if (!defined $hash) {
 		$hash = git_get_head_hash($project);
 	}
 
-	my $filename = basename($project) . "-$hash.tar.gz";
+	my $filename = basename($project) . "-$hash.tar.$suffix";
 
 	print $cgi->header(-type => 'application/x-tar',
-			-content-encoding => 'x-gzip',
-			'-content-disposition' => "inline; filename=\"$filename\"",
-			-status => '200 OK');
+			   -content-encoding => $ctype,
+			   '-content-disposition' =>
+			   "inline; filename=\"$filename\"",
+			   -status => '200 OK');
 
-	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
-				die_error(undef, "Execute git-tar-tree failed.");
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+		die_error(undef, "Execute git-tar-tree failed.");
 	binmode STDOUT, ':raw';
 	print <$fd>;
 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 
-
 }
 
 sub git_log {
@@ -2293,7 +2356,10 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 13:56           ` Aneesh Kumar K.V
@ 2006-08-19 14:22             ` Jakub Narebski
  2006-08-19 16:17               ` Aneesh Kumar K.V
  2006-08-19 21:49               ` Junio C Hamano
  0 siblings, 2 replies; 14+ messages in thread
From: Jakub Narebski @ 2006-08-19 14:22 UTC (permalink / raw)
  To: git

Aneesh Kumar K.V wrote:

> I tested this and added some comments. I also fixed some code. 
> I am attaching the full diff. 

Below comments to the patch.

> BTW git-repo-config have the below bug. 
> 
> $ git repo-config --bool --get gitweb.blame
> true
> $ git repo-config --get --bool gitweb.blame
> $
> 
> So i dropped --get from the git_get_project_config

Wouldn't it be better to correct the error in git-repo-config? 
Or (easier) add '--get' last (see comments)?

> +# Feature configuration.

Wouldn't it make it easier to understand code to put %feature hash 
and gitweb_check_feature subroutine _before_ subroutines for specific
features?

> +# These subs are only called when per repository
> +# overrides are allowed.  They take the default options,
> +# inspect the repository and return the values from there if
> +# the repository wants to override the system default.
> +
> +# To enable system wide have in $GITWEB_CONFIG
> +# $feature{'blame'} =  [\&feature_blame, 0, 1];

This enables system wide, but also disables per-project override.
To enable system wide, while allowing for per project disabling
it should read
# $feature{'blame'} = [\&feature_blame, 1, 1]; # overridable, enabled by default

> +# To disbale project wide 

Typo. disbale -> disable.

> +# you should have allow-override enabled in  $GITWEB_CONFIG
Example:
# $feature{'blame'} = [\&feature_blame, 1, 1]; # overridable, enabled by default
or just

$feature{'blame'}->[1] = 1;

(See below for comments on that form)

> +# and in project config   gitweb.blame = 0;
Example:
# $ git repo-config --bool gitweb.blame false

> +# To disable system wide have in $GITWEB_CONFIG
> +# $feature{'snapshot'} =  [\&feature_snapshot, 0, undef, undef, undef];
It would be enough to put:
$feature{'snapshot'} =  [\&feature_snapshot, 0, undef];

> +# You define site-wide feature defaults here; override them with
> +# $GITWEB_CONFIG as necessary.
> +our %feature =
> +(
> +       # feature       => [feature-sub, allow-override, default options...]
> +
> +       'blame'         => [\&feature_blame, 0, 0],
> +       'snapshot'      => [\&feature_snapshot, 0, 'x-gzip', 'gz', 'gzip'],
> +);

By the way, wouldn't it be better to use _hash_ for mixed meaning
than _array_? I.e.

our %feature =
(
       # feature       => {'sub' => feature-sub, 'override' => allow-override, 'default' => default options...]

       'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => 0},
   #or 'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => [ 0 ]},
       'snapshot'      => {'sub' => \&feature_snapshot, 'override' => 0, 'default => [ 'x-gzip', 'gz', 'gzip' ]},
);

Then you could enable override, or change default simplier in
$GITWEB_CONFIG, e.g. $feature{'blame'}{'override'} = 1; instead
of $feature{'blame'}[1] = 1;

By the way, it has more sense to have feature by default 
(i.e. in gitweb.perl) with override enabled if it is set to on.

>  sub git_get_project_config {
[...]
> -       my $val = qx($GIT repo-config --get gitweb.$key);
> +       my @x = ($GIT, 'repo-config');
> +       if (defined $type) { push @x, $type; }
Just add '--get' as the last argument, _after_ type:
  +       push @x, '--get';
> +       push @x, "gitweb.$key";
> +       my $val = qx(@x);
> +       chomp $val;
>         return ($val);
>  }


> -       die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
> +
> +       if (!gitweb_check_feature('blame')) {
> +               die_error(undef, "Permission denied");
> +       }

Why did you drop '403 Permission denied' HTTP return code from call
to die_error? (And not set in other similar cases)?

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 14:22             ` Jakub Narebski
@ 2006-08-19 16:17               ` Aneesh Kumar K.V
  2006-08-19 16:26                 ` Aneesh Kumar K.V
  2006-08-19 21:49               ` Junio C Hamano
  1 sibling, 1 reply; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-19 16:17 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 274 bytes --]

Jakub Narebski wrote:
> Aneesh Kumar K.V wrote:
> 
>> I tested this and added some comments. I also fixed some code. 
>> I am attaching the full diff. 
> 
> Below comments to the patch.
> 

updated patch attached. I guess i have taken care of all your comments. 


-aneesh 

[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6518 bytes --]

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..e8a4a6f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,68 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+
+# feature  => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
+
+'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => [0]},
+'snapshot'      => {'sub' => \&feature_snapshot, 'override' => 0, 'default' => ['x-gzip', 'gz', 'gzip']},
+
+);
+
+sub gitweb_check_feature {
+	my ($name) = @_;
+	return undef unless exists $feature{$name};
+	my ($sub, $override, @defaults) = ($feature{$name}{'sub'},
+						$feature{$name}{'override'},
+						@{$feature{$name}{'default'}});
+	if (!$override) { return @defaults; }
+	return $sub->(@defaults);
+}
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'}{'default'} =  [0];
+# To have project specific config enable override in  $GITWEB_CONFIG
+# $feature{'blame'}{'override'} =  1;
+# and in project config gitweb.blame = 0|1;
+
+sub feature_blame {
+	my ($val) = git_get_project_config('blame', '--bool');
+
+	if ($val eq 'true') {
+		return 1;
+	} elsif ($val eq 'false') {
+		return 0;
+	}
+
+	return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'}{'default'} =  [undef];
+# To have project specific config enable override in  $GITWEB_CONFIG
+# $feature{'blame'}{'override'} =  1;
+# and in project config  gitweb.snapshot = no|gzip|bzip2
+
+sub feature_snapshot {
+	my ($ctype, $suffix, $command) = @_;
+
+	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 'none') {
+		return ();
+	}
+
+	return ($ctype, $suffix, $command);
+}
+
 our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
 require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
 
@@ -485,24 +547,21 @@ sub git_get_type {
 }
 
 sub git_get_project_config {
-	my $key = shift;
+	my ($key, $type) = @_;
 
 	return unless ($key);
 	$key =~ s/^gitweb\.//;
 	return if ($key =~ m/\W/);
 
-	my $val = qx($GIT repo-config --get gitweb.$key);
+	my @x = ($GIT, 'repo-config');
+	if (defined $type) { push @x, $type; }
+	push @x, "--get";
+	push @x, "gitweb.$key";
+	my $val = qx(@x);
+	chomp $val;
 	return ($val);
 }
 
-sub git_get_project_config_bool {
-	my $val = git_get_project_config (@_);
-	if ($val and $val =~ m/true|yes|on/) {
-		return (1);
-	}
-	return; # implicit false
-}
-
 # get hash of given path at given ref
 sub git_get_hash_by_path {
 	my $base = shift;
@@ -1397,7 +1456,10 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1858,7 +1920,10 @@ sub git_tag {
 sub git_blame2 {
 	my $fd;
 	my $ftype;
-	die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error('403 Permission denied', "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1981,10 @@ sub git_blame2 {
 
 sub git_blame {
 	my $fd;
-	die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error('403 Permission denied', "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2137,7 @@ sub git_blob {
 			die_error(undef, "No file name defined");
 		}
 	}
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	open my $fd, "-|", $GIT, "cat-file", "blob", $hash
 		or die_error(undef, "Couldn't cat $file_name, $hash");
 	my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2202,7 @@ sub git_tree {
 	git_header_html();
 	my %base_key = ();
 	my $base = "";
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	if (defined $hash_base && (my %co = parse_commit($hash_base))) {
 		$base_key{hash_base} = $hash_base;
 		git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2263,31 @@ 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");
+	}
+
 	if (!defined $hash) {
 		$hash = git_get_head_hash($project);
 	}
 
-	my $filename = basename($project) . "-$hash.tar.gz";
+	my $filename = basename($project) . "-$hash.tar.$suffix";
 
 	print $cgi->header(-type => 'application/x-tar',
-			-content-encoding => 'x-gzip',
-			'-content-disposition' => "inline; filename=\"$filename\"",
-			-status => '200 OK');
+			   -content-encoding => $ctype,
+			   '-content-disposition' =>
+			   "inline; filename=\"$filename\"",
+			   -status => '200 OK');
 
-	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
-				die_error(undef, "Execute git-tar-tree failed.");
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+		die_error(undef, "Execute git-tar-tree failed.");
 	binmode STDOUT, ':raw';
 	print <$fd>;
 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 
-
 }
 
 sub git_log {
@@ -2293,7 +2367,10 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 16:17               ` Aneesh Kumar K.V
@ 2006-08-19 16:26                 ` Aneesh Kumar K.V
  0 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2006-08-19 16:26 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

Aneesh Kumar K.V wrote:
> Jakub Narebski wrote:
>> Aneesh Kumar K.V wrote:
>>
>>> I tested this and added some comments. I also fixed some code. I am 
>>> attaching the full diff. 
>>
>> Below comments to the patch.
>>
> 
> updated patch attached. I guess i have taken care of all your comments.

After fixing some comments and adding signed-off

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>

-aneesh


[-- Attachment #2: gitweb.diff --]
[-- Type: text/x-patch, Size: 6520 bytes --]

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f8d1036..063735d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -67,6 +67,68 @@ # file to use for guessing MIME types be
 # (relative to the current git repository)
 our $mimetypes_file = undef;
 
+# You define site-wide feature defaults here; override them with
+# $GITWEB_CONFIG as necessary.
+our %feature =
+(
+
+# feature  => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
+
+'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => [0]},
+'snapshot'      => {'sub' => \&feature_snapshot, 'override' => 0, 'default' => ['x-gzip', 'gz', 'gzip']},
+
+);
+
+sub gitweb_check_feature {
+	my ($name) = @_;
+	return undef unless exists $feature{$name};
+	my ($sub, $override, @defaults) = ($feature{$name}{'sub'},
+						$feature{$name}{'override'},
+						@{$feature{$name}{'default'}});
+	if (!$override) { return @defaults; }
+	return $sub->(@defaults);
+}
+
+# To enable system wide have in $GITWEB_CONFIG
+# $feature{'blame'}{'default'} =  [1];
+# To have project specific config enable override in  $GITWEB_CONFIG
+# $feature{'blame'}{'override'} =  1;
+# and in project config gitweb.blame = 0|1;
+
+sub feature_blame {
+	my ($val) = git_get_project_config('blame', '--bool');
+
+	if ($val eq 'true') {
+		return 1;
+	} elsif ($val eq 'false') {
+		return 0;
+	}
+
+	return $_[0];
+}
+
+# To disable system wide have in $GITWEB_CONFIG
+# $feature{'snapshot'}{'default'} =  [undef];
+# To have project specific config enable override in  $GITWEB_CONFIG
+# $feature{'blame'}{'override'} =  1;
+# and in project config  gitweb.snapshot = none|gzip|bzip2
+
+sub feature_snapshot {
+	my ($ctype, $suffix, $command) = @_;
+
+	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 'none') {
+		return ();
+	}
+
+	return ($ctype, $suffix, $command);
+}
+
 our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
 require $GITWEB_CONFIG if -e $GITWEB_CONFIG;
 
@@ -485,24 +547,21 @@ sub git_get_type {
 }
 
 sub git_get_project_config {
-	my $key = shift;
+	my ($key, $type) = @_;
 
 	return unless ($key);
 	$key =~ s/^gitweb\.//;
 	return if ($key =~ m/\W/);
 
-	my $val = qx($GIT repo-config --get gitweb.$key);
+	my @x = ($GIT, 'repo-config');
+	if (defined $type) { push @x, $type; }
+	push @x, "--get";
+	push @x, "gitweb.$key";
+	my $val = qx(@x);
+	chomp $val;
 	return ($val);
 }
 
-sub git_get_project_config_bool {
-	my $val = git_get_project_config (@_);
-	if ($val and $val =~ m/true|yes|on/) {
-		return (1);
-	}
-	return; # implicit false
-}
-
 # get hash of given path at given ref
 sub git_get_hash_by_path {
 	my $base = shift;
@@ -1397,7 +1456,10 @@ sub git_difftree_body {
 sub git_shortlog_body {
 	# uses global variable $project
 	my ($revlist, $from, $to, $refs, $extra) = @_;
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1858,7 +1920,10 @@ sub git_tag {
 sub git_blame2 {
 	my $fd;
 	my $ftype;
-	die_error(undef, "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error('403 Permission denied', "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -1916,7 +1981,10 @@ sub git_blame2 {
 
 sub git_blame {
 	my $fd;
-	die_error('403 Permission denied', "Permission denied") if (!git_get_project_config_bool ('blame'));
+
+	if (!gitweb_check_feature('blame')) {
+		die_error('403 Permission denied', "Permission denied");
+	}
 	die_error('404 Not Found', "File name not defined") if (!$file_name);
 	$hash_base ||= git_get_head_hash($project);
 	die_error(undef, "Couldn't find base commit") unless ($hash_base);
@@ -2069,7 +2137,7 @@ sub git_blob {
 			die_error(undef, "No file name defined");
 		}
 	}
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	open my $fd, "-|", $GIT, "cat-file", "blob", $hash
 		or die_error(undef, "Couldn't cat $file_name, $hash");
 	my $mimetype = blob_mimetype($fd, $file_name);
@@ -2134,7 +2202,7 @@ sub git_tree {
 	git_header_html();
 	my %base_key = ();
 	my $base = "";
-	my $have_blame = git_get_project_config_bool ('blame');
+	my $have_blame = gitweb_check_feature('blame');
 	if (defined $hash_base && (my %co = parse_commit($hash_base))) {
 		$base_key{hash_base} = $hash_base;
 		git_print_page_nav('tree','', $hash_base);
@@ -2195,25 +2263,31 @@ 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");
+	}
+
 	if (!defined $hash) {
 		$hash = git_get_head_hash($project);
 	}
 
-	my $filename = basename($project) . "-$hash.tar.gz";
+	my $filename = basename($project) . "-$hash.tar.$suffix";
 
 	print $cgi->header(-type => 'application/x-tar',
-			-content-encoding => 'x-gzip',
-			'-content-disposition' => "inline; filename=\"$filename\"",
-			-status => '200 OK');
+			   -content-encoding => $ctype,
+			   '-content-disposition' =>
+			   "inline; filename=\"$filename\"",
+			   -status => '200 OK');
 
-	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | gzip" or
-				die_error(undef, "Execute git-tar-tree failed.");
+	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
+		die_error(undef, "Execute git-tar-tree failed.");
 	binmode STDOUT, ':raw';
 	print <$fd>;
 	binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi
 	close $fd;
 
-
 }
 
 sub git_log {
@@ -2293,7 +2367,10 @@ sub git_commit {
 	}
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
-	my $have_snapshot = git_get_project_config_bool('snapshot');
+
+	my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot');
+	my $have_snapshot = (defined $ctype && defined $suffix);
+
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] gitweb: Support for snapshot
  2006-08-19 14:22             ` Jakub Narebski
  2006-08-19 16:17               ` Aneesh Kumar K.V
@ 2006-08-19 21:49               ` Junio C Hamano
  1 sibling, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2006-08-19 21:49 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git

Jakub Narebski <jnareb@gmail.com> writes:

> Below comments to the patch.
>...
> Wouldn't it make it easier to understand code to put %feature hash 
> and gitweb_check_feature subroutine _before_ subroutines for specific
> features?
>
> It would be enough to put:
> $feature{'snapshot'} =  [\&feature_snapshot, 0, undef];

Yes; although actually even 'undef' is not needed, I think it
makes sense to have at least one there ;-).

> By the way, wouldn't it be better to use _hash_ for mixed meaning
> than _array_? I.e.
>
> our %feature =
> (
>        # feature       => {'sub' => feature-sub, 'override' => allow-override, 'default' => default options...]
>
>        'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => 0},
>    #or 'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => [ 0 ]},
>        'snapshot'      => {'sub' => \&feature_snapshot, 'override' => 0, 'default => [ 'x-gzip', 'gz', 'gzip' ]},
> );

I like it better except that you made it wider than my terminal
again making it a lot harder to read.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2006-08-19 21:50 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-17 15:29 gitweb: Support for snapshot Aneesh Kumar K.V
2006-08-18  5:06 ` [PATCH] " Aneesh Kumar K.V
2006-08-18 19:51   ` Luben Tuikov
2006-08-18 20:05     ` Timo Hirvonen
     [not found]     ` <7v64gp7prk.fsf@assigned-by-dhcp.cox.net>
2006-08-19  8:10       ` Aneesh Kumar
2006-08-19 10:51         ` Junio C Hamano
2006-08-19 11:09           ` Jakub Narebski
2006-08-19 11:13           ` Jakub Narebski
2006-08-19 11:58             ` Aneesh Kumar K.V
2006-08-19 13:56           ` Aneesh Kumar K.V
2006-08-19 14:22             ` Jakub Narebski
2006-08-19 16:17               ` Aneesh Kumar K.V
2006-08-19 16:26                 ` Aneesh Kumar K.V
2006-08-19 21:49               ` Junio C Hamano

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 NNTP newsgroup(s).