public-inbox.git  about / heads / tags
an "archives first" approach to mailing lists
blob ee9436f3bb70a9d7fd5d60eed6e3e885ae46be8f 2860 bytes (raw)
$ git show repobrowse:lib/PublicInbox/RepoGitSummary.pm	# shows this blob on the CLI

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
 
# Copyright (C) 2016 all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>

# The main summary/landing page of a git repository viewer
package PublicInbox::RepoGitSummary;
use strict;
use warnings;
use PublicInbox::Hval qw(utf8_html);
use base qw(PublicInbox::RepoBase);
use PublicInbox::Qspawn;

sub call_git_summary {
	my ($self, $req) = @_;
	my $git = $req->{-repo}->{git};
	my $env = $req->{env};
	sub {
		my ($res) = @_; # Plack streaming callback
		for_each_ref($self, $req, $res, $req->{-repo}->tip);
	}
}

use constant EACH_REF_FMT => '--format=' .
		join(' ', map { "%($_)" }
		qw(refname objecttype objectname creatordate:short subject));

sub for_each_ref {
	my ($self, $req, $res, $head_ref) = @_;
	my $count = 10; # TODO: configurable
	my $fh;
	my $repo = $req->{-repo};
	my $git = $repo->{git};
	my $refs = $git->popen(qw(for-each-ref --sort=-creatordate),
				EACH_REF_FMT, "--count=$count",
				qw(refs/heads/ refs/tags/));
	$fh = $res->($self->rt(200, 'html'));
	# ref names are unpredictable in length and requires tables :<
	$fh->write($self->html_start($req,
				"$repo->{repo}: overview") .
			'</pre><table>');

	my $rel = $req->{relcmd};
	while (<$refs>) {
		my ($ref, $type, $hex, $date, $s) = split(' ', $_, 5);
		my $x = $ref eq $head_ref ? ' (HEAD)' : '';
		$ref =~ s!\Arefs/(?:heads|tags)/!!;
		$ref = PublicInbox::Hval->utf8($ref);
		my $h = $ref->as_html;
		$ref = $ref->as_href;
		my $sref;
		if ($type eq 'tag') {
			$h = "<b>$h</b>";
			$sref = $ref = $rel . 'tag/' . $ref;
		} elsif ($type eq 'commit') {
			$sref = $rel . 'commit/' . $ref;
			$ref = $rel . 'log/' . $ref;
		} else {
			# no point in wasting code to support tagged
			# trees/blobs...
			next;
		}
		chomp $s;
		$fh->write(qq(<tr><td><tt><a\nhref="$ref">$h</a>$x</tt></td>) .
			qq(<td><tt>$date <a\nhref="$sref">) . utf8_html($s) .
			'</a></tt></td></tr>');

	}
	$fh->write('</table>');

	# some people will use README.md or even README.sh here...
	my $readme = $repo->{readme};
	defined $readme or $readme = [ 'README', 'README.md' ];
	$readme = [ $readme ] if (ref($readme) ne 'ARRAY');
	foreach my $r (@$readme) {
		my $doc = $git->cat_file('HEAD:'.$r);
		defined $doc or next;
		$fh->write('<pre>' . readme_path_links($req, $rel, $r) .
			" (HEAD)\n\n" . utf8_html($$doc) . '</pre>');
	}
	$fh->write('</body></html>');
	$fh->close;
}

sub readme_path_links {
	my ($req, $rel, $readme) = @_;
	my @path = split(m!/+!, $readme);
	my $tip = $req->{-repo}->tip;
	my $s = "tree <a\nhref=\"${rel}src/$tip\">root</a>/";
	my @t;
	$s .= join('/', (map {
		push @t, $_;
		my $e = PublicInbox::Hval->utf8($_, join('/', @t));
		my $ep = $e->as_path;
		my $eh = $e->as_html;
		$e = "<a\nhref=\"${rel}src/$tip/$ep\">$eh</a>";
		# bold the last one
		scalar(@t) == scalar(@path) ? "<b>$e</b>" : $e;
	} @path));
}

1;

git clone https://public-inbox.org/public-inbox.git
git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/public-inbox.git