Merge branch 'pb/web'
* pb/web: gitweb: Support for 'forks'
This commit is contained in:
commit
9004dcbe82
@ -160,6 +160,21 @@ our %feature = (
|
||||
'pathinfo' => {
|
||||
'override' => 0,
|
||||
'default' => [0]},
|
||||
|
||||
# Make gitweb consider projects in project root subdirectories
|
||||
# to be forks of existing projects. Given project $projname.git,
|
||||
# projects matching $projname/*.git will not be shown in the main
|
||||
# projects list, instead a '+' mark will be added to $projname
|
||||
# there and a 'forks' view will be enabled for the project, listing
|
||||
# all the forks. This feature is supported only if project list
|
||||
# is taken from a directory, not file.
|
||||
|
||||
# To enable system wide have in $GITWEB_CONFIG
|
||||
# $feature{'forks'}{'default'} = [1];
|
||||
# Project specific override is not supported.
|
||||
'forks' => {
|
||||
'override' => 0,
|
||||
'default' => [0]},
|
||||
);
|
||||
|
||||
sub gitweb_check_feature {
|
||||
@ -405,6 +420,7 @@ my %actions = (
|
||||
"commitdiff" => \&git_commitdiff,
|
||||
"commitdiff_plain" => \&git_commitdiff_plain,
|
||||
"commit" => \&git_commit,
|
||||
"forks" => \&git_forks,
|
||||
"heads" => \&git_heads,
|
||||
"history" => \&git_history,
|
||||
"log" => \&git_log,
|
||||
@ -897,15 +913,21 @@ sub git_get_project_url_list {
|
||||
}
|
||||
|
||||
sub git_get_projects_list {
|
||||
my ($filter) = @_;
|
||||
my @list;
|
||||
|
||||
$filter ||= '';
|
||||
$filter =~ s/\.git$//;
|
||||
|
||||
if (-d $projects_list) {
|
||||
# search in directory
|
||||
my $dir = $projects_list;
|
||||
my $dir = $projects_list . ($filter ? "/$filter" : '');
|
||||
# remove the trailing "/"
|
||||
$dir =~ s!/+$!!;
|
||||
my $pfxlen = length("$dir");
|
||||
|
||||
my $check_forks = gitweb_check_feature('forks');
|
||||
|
||||
File::Find::find({
|
||||
follow_fast => 1, # follow symbolic links
|
||||
dangling_symlinks => 0, # ignore dangling symlinks, silently
|
||||
@ -917,8 +939,10 @@ sub git_get_projects_list {
|
||||
|
||||
my $subdir = substr($File::Find::name, $pfxlen + 1);
|
||||
# we check related file in $projectroot
|
||||
if (check_export_ok("$projectroot/$subdir")) {
|
||||
push @list, { path => $subdir };
|
||||
if ($check_forks and $subdir =~ m#/.#) {
|
||||
$File::Find::prune = 1;
|
||||
} elsif (check_export_ok("$projectroot/$filter/$subdir")) {
|
||||
push @list, { path => ($filter ? "$filter/" : '') . $subdir };
|
||||
$File::Find::prune = 1;
|
||||
}
|
||||
},
|
||||
@ -2185,6 +2209,124 @@ sub git_patchset_body {
|
||||
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
sub git_project_list_body {
|
||||
my ($projlist, $order, $from, $to, $extra, $no_header) = @_;
|
||||
|
||||
my $check_forks = gitweb_check_feature('forks');
|
||||
|
||||
my @projects;
|
||||
foreach my $pr (@$projlist) {
|
||||
my (@aa) = git_get_last_activity($pr->{'path'});
|
||||
unless (@aa) {
|
||||
next;
|
||||
}
|
||||
($pr->{'age'}, $pr->{'age_string'}) = @aa;
|
||||
if (!defined $pr->{'descr'}) {
|
||||
my $descr = git_get_project_description($pr->{'path'}) || "";
|
||||
$pr->{'descr'} = chop_str($descr, 25, 5);
|
||||
}
|
||||
if (!defined $pr->{'owner'}) {
|
||||
$pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || "";
|
||||
}
|
||||
if ($check_forks) {
|
||||
my $pname = $pr->{'path'};
|
||||
$pname =~ s/\.git$//;
|
||||
$pr->{'forks'} = -d "$projectroot/$pname";
|
||||
}
|
||||
push @projects, $pr;
|
||||
}
|
||||
|
||||
$order ||= "project";
|
||||
$from = 0 unless defined $from;
|
||||
$to = $#projects if (!defined $to || $#projects < $to);
|
||||
|
||||
print "<table class=\"project_list\">\n";
|
||||
unless ($no_header) {
|
||||
print "<tr>\n";
|
||||
if ($check_forks) {
|
||||
print "<th></th>\n";
|
||||
}
|
||||
if ($order eq "project") {
|
||||
@projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
|
||||
print "<th>Project</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'project'),
|
||||
-class => "header"}, "Project") .
|
||||
"</th>\n";
|
||||
}
|
||||
if ($order eq "descr") {
|
||||
@projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
|
||||
print "<th>Description</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'descr'),
|
||||
-class => "header"}, "Description") .
|
||||
"</th>\n";
|
||||
}
|
||||
if ($order eq "owner") {
|
||||
@projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
|
||||
print "<th>Owner</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'owner'),
|
||||
-class => "header"}, "Owner") .
|
||||
"</th>\n";
|
||||
}
|
||||
if ($order eq "age") {
|
||||
@projects = sort {$a->{'age'} <=> $b->{'age'}} @projects;
|
||||
print "<th>Last Change</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'age'),
|
||||
-class => "header"}, "Last Change") .
|
||||
"</th>\n";
|
||||
}
|
||||
print "<th></th>\n" .
|
||||
"</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'}) {
|
||||
print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+");
|
||||
}
|
||||
print "</td>\n";
|
||||
}
|
||||
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
||||
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
|
||||
"<td>" . esc_html($pr->{'descr'}) . "</td>\n" .
|
||||
"<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
|
||||
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
|
||||
$pr->{'age_string'} . "</td>\n" .
|
||||
"<td class=\"link\">" .
|
||||
$cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " .
|
||||
$cgi->a({-href => '/git-browser/by-commit.html?r='.$pr->{'path'}}, "graphiclog") . " | " .
|
||||
$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";
|
||||
}
|
||||
if (defined $extra) {
|
||||
print "<tr>\n";
|
||||
if ($check_forks) {
|
||||
print "<td></td>\n";
|
||||
}
|
||||
print "<td colspan=\"5\">$extra</td>\n" .
|
||||
"</tr>\n";
|
||||
}
|
||||
print "</table>\n";
|
||||
}
|
||||
|
||||
sub git_shortlog_body {
|
||||
# uses global variable $project
|
||||
my ($revlist, $from, $to, $refs, $extra) = @_;
|
||||
@ -2402,25 +2544,9 @@ sub git_project_list {
|
||||
}
|
||||
|
||||
my @list = git_get_projects_list();
|
||||
my @projects;
|
||||
if (!@list) {
|
||||
die_error(undef, "No projects found");
|
||||
}
|
||||
foreach my $pr (@list) {
|
||||
my (@aa) = git_get_last_activity($pr->{'path'});
|
||||
unless (@aa) {
|
||||
next;
|
||||
}
|
||||
($pr->{'age'}, $pr->{'age_string'}) = @aa;
|
||||
if (!defined $pr->{'descr'}) {
|
||||
my $descr = git_get_project_description($pr->{'path'}) || "";
|
||||
$pr->{'descr'} = chop_str($descr, 25, 5);
|
||||
}
|
||||
if (!defined $pr->{'owner'}) {
|
||||
$pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || "";
|
||||
}
|
||||
push @projects, $pr;
|
||||
}
|
||||
|
||||
git_header_html();
|
||||
if (-f $home_text) {
|
||||
@ -2430,75 +2556,30 @@ sub git_project_list {
|
||||
close $fd;
|
||||
print "</div>\n";
|
||||
}
|
||||
print "<table class=\"project_list\">\n" .
|
||||
"<tr>\n";
|
||||
$order ||= "project";
|
||||
if ($order eq "project") {
|
||||
@projects = sort {$a->{'path'} cmp $b->{'path'}} @projects;
|
||||
print "<th>Project</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'project'),
|
||||
-class => "header"}, "Project") .
|
||||
"</th>\n";
|
||||
git_project_list_body(\@list, $order);
|
||||
git_footer_html();
|
||||
}
|
||||
|
||||
sub git_forks {
|
||||
my $order = $cgi->param('o');
|
||||
if (defined $order && $order !~ m/project|descr|owner|age/) {
|
||||
die_error(undef, "Unknown order parameter");
|
||||
}
|
||||
if ($order eq "descr") {
|
||||
@projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects;
|
||||
print "<th>Description</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'descr'),
|
||||
-class => "header"}, "Description") .
|
||||
"</th>\n";
|
||||
|
||||
my @list = git_get_projects_list($project);
|
||||
if (!@list) {
|
||||
die_error(undef, "No forks found");
|
||||
}
|
||||
if ($order eq "owner") {
|
||||
@projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects;
|
||||
print "<th>Owner</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'owner'),
|
||||
-class => "header"}, "Owner") .
|
||||
"</th>\n";
|
||||
}
|
||||
if ($order eq "age") {
|
||||
@projects = sort {$a->{'age'} <=> $b->{'age'}} @projects;
|
||||
print "<th>Last Change</th>\n";
|
||||
} else {
|
||||
print "<th>" .
|
||||
$cgi->a({-href => href(project=>undef, order=>'age'),
|
||||
-class => "header"}, "Last Change") .
|
||||
"</th>\n";
|
||||
}
|
||||
print "<th></th>\n" .
|
||||
"</tr>\n";
|
||||
my $alternate = 1;
|
||||
foreach my $pr (@projects) {
|
||||
if ($alternate) {
|
||||
print "<tr class=\"dark\">\n";
|
||||
} else {
|
||||
print "<tr class=\"light\">\n";
|
||||
}
|
||||
$alternate ^= 1;
|
||||
print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
|
||||
-class => "list"}, esc_html($pr->{'path'})) . "</td>\n" .
|
||||
"<td>" . esc_html($pr->{'descr'}) . "</td>\n" .
|
||||
"<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
|
||||
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
|
||||
$pr->{'age_string'} . "</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") .
|
||||
"</td>\n" .
|
||||
"</tr>\n";
|
||||
}
|
||||
print "</table>\n";
|
||||
|
||||
git_header_html();
|
||||
git_print_page_nav('','');
|
||||
git_print_header_div('summary', "$project forks");
|
||||
git_project_list_body(\@list, $order);
|
||||
git_footer_html();
|
||||
}
|
||||
|
||||
sub git_project_index {
|
||||
my @projects = git_get_projects_list();
|
||||
my @projects = git_get_projects_list($project);
|
||||
|
||||
print $cgi->header(
|
||||
-type => 'text/plain',
|
||||
@ -2532,6 +2613,10 @@ sub git_summary {
|
||||
my $refs = git_get_references();
|
||||
my @taglist = git_get_tags_list(15);
|
||||
my @headlist = git_get_heads_list(15);
|
||||
my @forklist;
|
||||
if (gitweb_check_feature('forks')) {
|
||||
@forklist = git_get_projects_list($project);
|
||||
}
|
||||
|
||||
git_header_html();
|
||||
git_print_page_nav('summary','', $head);
|
||||
@ -2582,6 +2667,13 @@ sub git_summary {
|
||||
$cgi->a({-href => href(action=>"heads")}, "..."));
|
||||
}
|
||||
|
||||
if (@forklist) {
|
||||
git_print_header_div('forks');
|
||||
git_project_list_body(\@forklist, undef, 0, 15,
|
||||
$cgi->a({-href => href(action=>"forks")}, "..."),
|
||||
'noheader');
|
||||
}
|
||||
|
||||
git_footer_html();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user