# if we're called with PATH_INFO, we have to strip that
# from the URL to find our real URL
# we make $path_info global because it's also used later on
-my $path_info = $ENV{"PATH_INFO"};
+our $path_info = $ENV{"PATH_INFO"};
if ($path_info) {
$my_url =~ s,\Q$path_info\E$,,;
$my_uri =~ s,\Q$path_info\E$,,;
# (only effective if this variable evaluates to true)
our $export_ok = "++GITWEB_EXPORT_OK++";
+# show repository only if this subroutine returns true
+# when given the path to the project, for example:
+# sub { return -e "$_[0]/git-daemon-export-ok"; }
+our $export_auth_hook = undef;
+
# only allow viewing of repositories also shown on the overview page
our $strict_export = "++GITWEB_STRICT_EXPORT++";
# if there is no 'sub' key (no feature-sub), then feature cannot be
# overriden
#
- # use gitweb_check_feature(<feature>) to check if <feature> is enabled
+ # use gitweb_get_feature(<feature>) to retrieve the <feature> value
+ # (an array) or gitweb_check_feature(<feature>) to check if <feature>
+ # is enabled
# Enable the 'blame' blob view, showing the last commit that modified
# each line in the file. This can be very CPU-intensive.
# $feature{'grep'}{'override'} = 1;
# and in project config gitweb.grep = 0|1;
'grep' => {
+ 'sub' => \&feature_grep,
'override' => 0,
'default' => [1]},
# The 'default' value consists of a list of triplets in the form
# (label, link, position) where position is the label after which
- # to inster the link and link is a format string where %n expands
+ # to insert the link and link is a format string where %n expands
# to the project name, %f to the project path within the filesystem,
# %h to the current hash (h gitweb parameter) and %b to the current
- # hash base (hb gitweb parameter).
+ # hash base (hb gitweb parameter); %% expands to %.
# To enable system wide have in $GITWEB_CONFIG e.g.
# $feature{'actions'}{'default'} = [('graphiclog',
'default' => [0]},
);
-sub gitweb_check_feature {
+sub gitweb_get_feature {
my ($name) = @_;
return unless exists $feature{$name};
my ($sub, $override, @defaults) = (
return $sub->(@defaults);
}
+# A wrapper to check if a given feature is enabled.
+# With this, you can say
+#
+# my $bool_feat = gitweb_check_feature('bool_feat');
+# gitweb_check_feature('bool_feat') or somecode;
+#
+# instead of
+#
+# my ($bool_feat) = gitweb_get_feature('bool_feat');
+# (gitweb_get_feature('bool_feat'))[0] or somecode;
+#
+sub gitweb_check_feature {
+ return (gitweb_get_feature(@_))[0];
+}
+
+
sub feature_blame {
my ($val) = git_get_project_config('blame', '--bool');
sub check_export_ok {
my ($dir) = @_;
return (check_head_link($dir) &&
- (!$export_ok || -e "$dir/$export_ok"));
+ (!$export_ok || -e "$dir/$export_ok") &&
+ (!$export_auth_hook || $export_auth_hook->($dir)));
}
# process alternate names for backward compatibility
# together during validation: this allows subsequent uses (e.g. href()) to be
# agnostic of the parameter origin
-my %input_params = ();
+our %input_params = ();
# input parameters are stored with the long parameter name as key. This will
# also be used in the href subroutine to convert parameters to their CGI
# XXX: Warning: If you touch this, check the search form for updating,
# too.
-my @cgi_param_mapping = (
+our @cgi_param_mapping = (
project => "p",
action => "a",
file_name => "f",
extra_options => "opt",
search_use_regexp => "sr",
);
-my %cgi_param_mapping = @cgi_param_mapping;
+our %cgi_param_mapping = @cgi_param_mapping;
# we will also need to know the possible actions, for validation
-my %actions = (
+our %actions = (
"blame" => \&git_blame,
"blobdiff" => \&git_blobdiff,
"blobdiff_plain" => \&git_blobdiff_plain,
# finally, we have the hash of allowed extra_options for the commands that
# allow them
-my %allowed_options = (
+our %allowed_options = (
"--no-merges" => [ qw(rss atom log shortlog history) ],
);
$git_dir = "$projectroot/$project" if $project;
# list of supported snapshot formats
-our @snapshot_fmts = gitweb_check_feature('snapshot');
+our @snapshot_fmts = gitweb_get_feature('snapshot');
@snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);
# dispatch
}
}
- my ($use_pathinfo) = gitweb_check_feature('pathinfo');
+ my $use_pathinfo = gitweb_check_feature('pathinfo');
if ($use_pathinfo) {
# try to put as many parameters as possible in PATH_INFO:
# - project name
my $input = shift || return undef;
if (!validate_pathname($input) ||
!(-d "$projectroot/$input") ||
- !check_head_link("$projectroot/$input") ||
- ($export_ok && !(-e "$projectroot/$input/$export_ok")) ||
+ !check_export_ok("$projectroot/$input") ||
($strict_export && !project_in_list($input))) {
return undef;
} else {
my $ctags = {};
$git_dir = "$projectroot/$path";
- foreach (<$git_dir/ctags/*>) {
+ unless (opendir D, "$git_dir/ctags") {
+ return $ctags;
+ }
+ foreach (grep { -f $_ } map { "$git_dir/ctags/$_" } readdir(D)) {
open CT, $_ or next;
my $val = <CT>;
chomp $val;
my $ctag = $_; $ctag =~ s#.*/##;
$ctags->{$ctag} = $val;
}
+ closedir D;
$ctags;
}
$filter ||= '';
$filter =~ s/\.git$//;
- my ($check_forks) = gitweb_check_feature('forks');
+ my $check_forks = gitweb_check_feature('forks');
if (-d $projects_list) {
# search in directory
return to_utf8($owner);
}
+# assume that file exists
+sub insert_file {
+ my $filename = shift;
+
+ open my $fd, '<', $filename;
+ print map(to_utf8, <$fd>);
+ close $fd;
+}
+
## ......................................................................
## mimetype related functions
"<body>\n";
if (-f $site_header) {
- open (my $fd, $site_header);
- print <$fd>;
- close $fd;
+ insert_file($site_header);
}
print "<div class=\"page_header\">\n" .
}
print "</div>\n";
- my ($have_search) = gitweb_check_feature('search');
+ my $have_search = gitweb_check_feature('search');
if (defined $project && $have_search) {
if (!defined $searchtext) {
$searchtext = "";
$search_hash = "HEAD";
}
my $action = $my_uri;
- my ($use_pathinfo) = gitweb_check_feature('pathinfo');
+ my $use_pathinfo = gitweb_check_feature('pathinfo');
if ($use_pathinfo) {
$action .= "/".esc_url($project);
}
print "</div>\n"; # class="page_footer"
if (-f $site_footer) {
- open (my $fd, $site_footer);
- print <$fd>;
- close $fd;
+ insert_file($site_footer);
}
print "</body>\n" .
$arg{'tree'}{'hash'} = $treehead if defined $treehead;
$arg{'tree'}{'hash_base'} = $treebase if defined $treebase;
- my @actions = gitweb_check_feature('actions');
+ my @actions = gitweb_get_feature('actions');
+ my %repl = (
+ '%' => '%',
+ 'n' => $project, # project name
+ 'f' => $git_dir, # project path within filesystem
+ 'h' => $treehead || '', # current hash ('h' parameter)
+ 'b' => $treebase || '', # hash base ('hb' parameter)
+ );
while (@actions) {
- my ($label, $link, $pos) = (shift(@actions), shift(@actions), shift(@actions));
+ my ($label, $link, $pos) = splice(@actions,0,3);
+ # insert
@navs = map { $_ eq $pos ? ($_, $label) : $_ } @navs;
# munch munch
- $link =~ s#%n#$project#g;
- $link =~ s#%f#$git_dir#g;
- $treehead ? $link =~ s#%h#$treehead#g : $link =~ s#%h##g;
- $treebase ? $link =~ s#%b#$treebase#g : $link =~ s#%b##g;
+ $link =~ s/%([%nfhb])/$repl{$1}/g;
$arg{$label}{'_href'} = $link;
}
sub git_difftree_body {
my ($difftree, $hash, @parents) = @_;
my ($parent) = $parents[0];
- my ($have_blame) = gitweb_check_feature('blame');
+ my $have_blame = gitweb_check_feature('blame');
print "<div class=\"list_head\">\n";
if ($#{$difftree} > 10) {
print(($#{$difftree} + 1) . " files changed:\n");
# actually uses global variable $project
my ($projlist, $order, $from, $to, $extra, $no_header) = @_;
- my ($check_forks) = gitweb_check_feature('forks');
+ my $check_forks = gitweb_check_feature('forks');
my @projects = fill_project_list_info($projlist, $check_forks);
$order ||= $default_projects_order;
git_header_html();
if (-f $home_text) {
print "<div class=\"index_include\">\n";
- open (my $fd, $home_text);
- print <$fd>;
- close $fd;
+ insert_file($home_text);
print "</div>\n";
}
print $cgi->startform(-method => "get") .
my @taglist = git_get_tags_list(16);
my @headlist = git_get_heads_list(16);
my @forklist;
- my ($check_forks) = gitweb_check_feature('forks');
+ my $check_forks = gitweb_check_feature('forks');
if ($check_forks) {
@forklist = git_get_projects_list($project);
}
# Tag cloud
- my $show_ctags = (gitweb_check_feature('ctags'))[0];
+ my $show_ctags = gitweb_check_feature('ctags');
if ($show_ctags) {
my $ctags = git_get_project_ctags($project);
my $cloud = git_populate_project_tagcloud($ctags);
print "</table>\n";
if (-s "$projectroot/$project/README.html") {
- if (open my $fd, "$projectroot/$project/README.html") {
- print "<div class=\"title\">readme</div>\n" .
- "<div class=\"readme\">\n";
- print $_ while (<$fd>);
- print "\n</div>\n"; # class="readme"
- close $fd;
- }
+ print "<div class=\"title\">readme</div>\n" .
+ "<div class=\"readme\">\n";
+ insert_file("$projectroot/$project/README.html");
+ print "\n</div>\n"; # class="readme"
}
# we need to request one more than 16 (0..15) to check if
$expires = "+1d";
}
- my ($have_blame) = gitweb_check_feature('blame');
+ my $have_blame = gitweb_check_feature('blame');
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
or die_error(500, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
my $ref = format_ref_marker($refs, $hash_base);
git_header_html();
my $basedir = '';
- my ($have_blame) = gitweb_check_feature('blame');
+ my $have_blame = gitweb_check_feature('blame');
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
my @views_nav = ();
if (defined $file_name) {
<dt><b>commit</b></dt>
<dd>The commit messages and authorship information will be scanned for the given pattern.</dd>
EOT
- my ($have_grep) = gitweb_check_feature('grep');
+ my $have_grep = gitweb_check_feature('grep');
if ($have_grep) {
print <<EOT;
<dt><b>grep</b></dt>
<dt><b>committer</b></dt>
<dd>Name and e-mail of the committer and date of commit will be scanned for the given pattern.</dd>
EOT
- my ($have_pickaxe) = gitweb_check_feature('pickaxe');
+ my $have_pickaxe = gitweb_check_feature('pickaxe');
if ($have_pickaxe) {
print <<EOT;
<dt><b>pickaxe</b></dt>
sub git_feed {
my $format = shift || 'atom';
- my ($have_blame) = gitweb_check_feature('blame');
+ my $have_blame = gitweb_check_feature('blame');
# Atom: http://www.atomenabled.org/developers/syndication/
# RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ