|
|
|
|
@ -115,6 +115,14 @@ our $projects_list = "++GITWEB_LIST++";
|
|
|
|
|
# the width (in characters) of the projects list "Description" column
|
|
|
|
|
our $projects_list_description_width = 25;
|
|
|
|
|
|
|
|
|
|
# group projects by category on the projects list
|
|
|
|
|
# (enabled if this variable evaluates to true)
|
|
|
|
|
our $projects_list_group_categories = 0;
|
|
|
|
|
|
|
|
|
|
# default category if none specified
|
|
|
|
|
# (leave the empty string for no category)
|
|
|
|
|
our $project_list_default_category = "";
|
|
|
|
|
|
|
|
|
|
# default order of projects list
|
|
|
|
|
# valid values are none, project, descr, owner, and age
|
|
|
|
|
our $default_projects_order = "project";
|
|
|
|
|
@ -2574,20 +2582,34 @@ sub git_get_path_by_hash {
|
|
|
|
|
## ......................................................................
|
|
|
|
|
## git utility functions, directly accessing git repository
|
|
|
|
|
|
|
|
|
|
sub git_get_project_description {
|
|
|
|
|
my $path = shift;
|
|
|
|
|
# get the value of config variable either from file named as the variable
|
|
|
|
|
# itself in the repository ($GIT_DIR/$name file), or from gitweb.$name
|
|
|
|
|
# configuration variable in the repository config file.
|
|
|
|
|
sub git_get_file_or_project_config {
|
|
|
|
|
my ($path, $name) = @_;
|
|
|
|
|
|
|
|
|
|
$git_dir = "$projectroot/$path";
|
|
|
|
|
open my $fd, '<', "$git_dir/description"
|
|
|
|
|
or return git_get_project_config('description');
|
|
|
|
|
my $descr = <$fd>;
|
|
|
|
|
open my $fd, '<', "$git_dir/$name"
|
|
|
|
|
or return git_get_project_config($name);
|
|
|
|
|
my $conf = <$fd>;
|
|
|
|
|
close $fd;
|
|
|
|
|
if (defined $descr) {
|
|
|
|
|
chomp $descr;
|
|
|
|
|
if (defined $conf) {
|
|
|
|
|
chomp $conf;
|
|
|
|
|
}
|
|
|
|
|
return $descr;
|
|
|
|
|
return $conf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub git_get_project_description {
|
|
|
|
|
my $path = shift;
|
|
|
|
|
return git_get_file_or_project_config($path, 'description');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub git_get_project_category {
|
|
|
|
|
my $path = shift;
|
|
|
|
|
return git_get_file_or_project_config($path, 'category');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# supported formats:
|
|
|
|
|
# * $GIT_DIR/ctags/<tagname> file (in 'ctags' subdirectory)
|
|
|
|
|
# - if its contents is a number, use it as tag weight,
|
|
|
|
|
@ -4881,8 +4903,9 @@ sub git_patchset_body {
|
|
|
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
|
|
|
|
|
|
|
# fills project list info (age, description, owner, forks) for each
|
|
|
|
|
# project in the list, removing invalid projects from returned list
|
|
|
|
|
# fills project list info (age, description, owner, category, forks)
|
|
|
|
|
# for each project in the list, removing invalid projects from
|
|
|
|
|
# returned list
|
|
|
|
|
# NOTE: modifies $projlist, but does not remove entries from it
|
|
|
|
|
sub fill_project_list_info {
|
|
|
|
|
my $projlist = shift;
|
|
|
|
|
@ -4908,6 +4931,12 @@ sub fill_project_list_info {
|
|
|
|
|
if ($show_ctags) {
|
|
|
|
|
$pr->{'ctags'} = git_get_project_ctags($pr->{'path'});
|
|
|
|
|
}
|
|
|
|
|
if ($projects_list_group_categories && !defined $pr->{'category'}) {
|
|
|
|
|
my $cat = git_get_project_category($pr->{'path'}) ||
|
|
|
|
|
$project_list_default_category;
|
|
|
|
|
$pr->{'category'} = to_utf8($cat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
push @projects, $pr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -4935,6 +4964,23 @@ sub sort_projects_list {
|
|
|
|
|
return @projects;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# returns a hash of categories, containing the list of project
|
|
|
|
|
# belonging to each category
|
|
|
|
|
sub build_projlist_by_category {
|
|
|
|
|
my ($projlist, $from, $to) = @_;
|
|
|
|
|
my %categories;
|
|
|
|
|
|
|
|
|
|
$from = 0 unless defined $from;
|
|
|
|
|
$to = $#$projlist if (!defined $to || $#$projlist < $to);
|
|
|
|
|
|
|
|
|
|
for (my $i = $from; $i <= $to; $i++) {
|
|
|
|
|
my $pr = $projlist->[$i];
|
|
|
|
|
push @{$categories{ $pr->{'category'} }}, $pr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return wantarray ? %categories : \%categories;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# print 'sort by' <th> element, generating 'sort by $name' replay link
|
|
|
|
|
# if that order is not selected
|
|
|
|
|
sub print_sort_th {
|
|
|
|
|
@ -4958,6 +5004,55 @@ sub format_sort_th {
|
|
|
|
|
return $sort_th;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub git_project_list_rows {
|
|
|
|
|
my ($projlist, $from, $to, $check_forks) = @_;
|
|
|
|
|
|
|
|
|
|
$from = 0 unless defined $from;
|
|
|
|
|
$to = $#$projlist if (!defined $to || $#$projlist < $to);
|
|
|
|
|
|
|
|
|
|
my $alternate = 1;
|
|
|
|
|
for (my $i = $from; $i <= $to; $i++) {
|
|
|
|
|
my $pr = $projlist->[$i];
|
|
|
|
|
|
|
|
|
|
if ($alternate) {
|
|
|
|
|
print "<tr class=\"dark\">\n";
|
|
|
|
|
} else {
|
|
|
|
|
print "<tr class=\"light\">\n";
|
|
|
|
|
}
|
|
|
|
|
$alternate ^= 1;
|
|
|
|
|
|
|
|
|
|
if ($check_forks) {
|
|
|
|
|
print "<td>";
|
|
|
|
|
if ($pr->{'forks'}) {
|
|
|
|
|
my $nforks = scalar @{$pr->{'forks'}};
|
|
|
|
|
if ($nforks > 0) {
|
|
|
|
|
print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks"),
|
|
|
|
|
-title => "$nforks forks"}, "+");
|
|
|
|
|
} else {
|
|
|
|
|
print $cgi->span({-title => "$nforks forks"}, "+");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
print "</td>\n";
|
|
|
|
|
}
|
|
|
|
|
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
|
|
|
|
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
|
|
|
|
|
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
|
|
|
|
-class => "list", -title => $pr->{'descr_long'}},
|
|
|
|
|
esc_html($pr->{'descr'})) . "</td>\n" .
|
|
|
|
|
"<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
|
|
|
|
|
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
|
|
|
|
|
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
|
|
|
|
|
"<td class=\"link\">" .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"shortlog")}, "shortlog") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") .
|
|
|
|
|
($pr->{'forks'} ? " | " . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "forks") : '') .
|
|
|
|
|
"</td>\n" .
|
|
|
|
|
"</tr>\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub git_project_list_body {
|
|
|
|
|
# actually uses global variable $project
|
|
|
|
|
my ($projlist, $order, $from, $to, $extra, $no_header) = @_;
|
|
|
|
|
@ -5013,47 +5108,27 @@ sub git_project_list_body {
|
|
|
|
|
print "<th></th>\n" . # for links
|
|
|
|
|
"</tr>\n";
|
|
|
|
|
}
|
|
|
|
|
my $alternate = 1;
|
|
|
|
|
for (my $i = $from; $i <= $to; $i++) {
|
|
|
|
|
my $pr = $projects[$i];
|
|
|
|
|
|
|
|
|
|
if ($alternate) {
|
|
|
|
|
print "<tr class=\"dark\">\n";
|
|
|
|
|
} else {
|
|
|
|
|
print "<tr class=\"light\">\n";
|
|
|
|
|
}
|
|
|
|
|
$alternate ^= 1;
|
|
|
|
|
|
|
|
|
|
if ($check_forks) {
|
|
|
|
|
print "<td>";
|
|
|
|
|
if ($pr->{'forks'}) {
|
|
|
|
|
my $nforks = scalar @{$pr->{'forks'}};
|
|
|
|
|
if ($nforks > 0) {
|
|
|
|
|
print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks"),
|
|
|
|
|
-title => "$nforks forks"}, "+");
|
|
|
|
|
} else {
|
|
|
|
|
print $cgi->span({-title => "$nforks forks"}, "+");
|
|
|
|
|
if ($projects_list_group_categories) {
|
|
|
|
|
# only display categories with projects in the $from-$to window
|
|
|
|
|
@projects = sort {$a->{'category'} cmp $b->{'category'}} @projects[$from..$to];
|
|
|
|
|
my %categories = build_projlist_by_category(\@projects, $from, $to);
|
|
|
|
|
foreach my $cat (sort keys %categories) {
|
|
|
|
|
unless ($cat eq "") {
|
|
|
|
|
print "<tr>\n";
|
|
|
|
|
if ($check_forks) {
|
|
|
|
|
print "<td></td>\n";
|
|
|
|
|
}
|
|
|
|
|
print "<td class=\"category\" colspan=\"5\">".esc_html($cat)."</td>\n";
|
|
|
|
|
print "</tr>\n";
|
|
|
|
|
}
|
|
|
|
|
print "</td>\n";
|
|
|
|
|
|
|
|
|
|
git_project_list_rows($categories{$cat}, undef, undef, $check_forks);
|
|
|
|
|
}
|
|
|
|
|
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
|
|
|
|
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
|
|
|
|
|
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
|
|
|
|
-class => "list", -title => $pr->{'descr_long'}},
|
|
|
|
|
esc_html($pr->{'descr'})) . "</td>\n" .
|
|
|
|
|
"<td><i>" . chop_and_escape_str($pr->{'owner'}, 15) . "</i></td>\n";
|
|
|
|
|
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
|
|
|
|
|
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
|
|
|
|
|
"<td class=\"link\">" .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"shortlog")}, "shortlog") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " .
|
|
|
|
|
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") .
|
|
|
|
|
($pr->{'forks'} ? " | " . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "forks") : '') .
|
|
|
|
|
"</td>\n" .
|
|
|
|
|
"</tr>\n";
|
|
|
|
|
} else {
|
|
|
|
|
git_project_list_rows(\@projects, $from, $to, $check_forks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defined $extra) {
|
|
|
|
|
print "<tr>\n";
|
|
|
|
|
if ($check_forks) {
|
|
|
|
|
|