);
}
+sub project_index : Local {
+ my ( $self, $c ) = @_;
+
+ my @list = @{ $c->model()->projects };
+ die 'No projects found in '. $c->model->repo_dir
+ unless @list;
+
+ $c->response->content_type('text/plain');
+ $c->response->body(
+ join "\n", map $_->name, @list
+ );
+ $c->response->status(200);
+}
+
=head2 summary
A summary of what's happening in the repo.
}
-=head2 blob
-
-The blob action i.e the contents of a file.
-
-=cut
-
-sub blob : Local {
+sub _blob_objs {
my ( $self, $c ) = @_;
my $project = $c->stash->{Project};
my $h = $c->req->param('h')
my $filename = $c->req->param('f') || '';
+ my $blob = $project->get_object($h);
+ $blob = $project->get_object(
+ $project->hash_by_path($h || $hb, $filename)
+ ) if $blob->type ne 'blob';
+
+ return $blob, $project->get_object($hb), $filename;
+}
+
+=head2 blob
+
+The blob action i.e the contents of a file.
+
+=cut
+
+sub blob : Local {
+ my ( $self, $c ) = @_;
+
+ my($blob, $head, $filename) = $self->_blob_objs($c);
$c->stash(
- blob => $project->get_object($h)->content,
- head => $project->get_object($hb),
+ blob => $blob->content,
+ head => $head,
filename => $filename,
# XXX Hack hack hack, see View::SyntaxHighlight
language => ($filename =~ /\.p[lm]$/ ? 'Perl' : ''),
unless $c->stash->{no_wrapper};
}
+=head2 blob_plain
+
+The plain text version of blob, where file is rendered as is.
+
+=cut
+
sub blob_plain : Local {
my($self, $c) = @_;
- $c->stash(no_wrapper => 1);
+ my($blob) = $self->_blob_objs($c);
$c->response->content_type('text/plain; charset=utf-8');
-
- $c->forward('blob');
+ $c->response->body($blob->content);
+ $c->response->status(200);
}
+=head2 blobdiff_plain
+
+The plain text version of blobdiff.
+
+=cut
+
sub blobdiff_plain : Local {
my($self, $c) = @_;
$c->response->content_type('text/plain; charset=utf-8');
$c->forward('blobdiff');
-
}
=head2 blobdiff
short_cmt => sub {
my $cmt = shift;
my($line) = split /\n/, $cmt;
- $line =~ s/^(.{70,80}\b).*/$1 …/;
+ $line =~ s/^(.{70,80}\b).*/$1 \x{2026}/;
return $line;
},
abridged_description => sub {
);
}
-sub project_index : Local {
- # FIXME - implement snapshot
- Carp::croak "Not implemented.";
-}
sub opml : Local {
# FIXME - implement snapshot
Carp::croak "Not implemented.";
<div class='pager'>
- <a href='[% c.uri_for(action, {h=HEAD}) %]'>HEAD</a> §
+ <a href='[% c.uri_for(action, {h=HEAD}) %]'>HEAD</a> §
[% IF log_lines.first.sha1 != commit.sha1 %]
- <a href='[% c.uri_for(action, {pg=page - 1, h=commit.sha1}) %]'>« prev</a>
+ <a href='[% c.uri_for(action, {pg=page - 1, h=commit.sha1}) %]'>« prev</a>
[% END %]
[% IF log_lines.size == 50 %]
- <a href='[% c.uri_for(action, {pg=page + 1, h=commit.sha1}) %]'>next »</a>
+ <a href='[% c.uri_for(action, {pg=page + 1, h=commit.sha1}) %]'>next »</a>
[% END %]
</div>
<td class='time-since' title='[% line.authored_time %]'>[% time_since(line.authored_time) %]</td>
<td class='author'>[% line.author.name | html %]</td>
<td>
- [% short_cmt(line.comment) | html %]
+ [% short_cmt(line.comment) | html_entity %]
[% INCLUDE '_refs.tt2' object = line %]
</td>
<td class='action-list'>
</div>
[% END %]
-<h3>BLOB PATH</h3>
+[% INCLUDE 'nav/path.tt2' %]
<div id='blame'>
<table>
<link rel="stylesheet" type="text/css" href="/static/css/syntax/[% language %].css"/>
[% PROCESS 'nav/actions.tt2' object = head %]
-[% IF object.type == 'commit' %]
-<div class='commit-message'>
-[% head.comment.substr(0, 85) %] ...
-</div>
+ [% IF object.type == 'commit' %]
+ <div class='commit-message'>
+ [% short_cmt(head.comment) %]
+ </div>
[% END %]
-<div class='path'>
- <a href="[% c.uri_for("tree", {hb=head.sha1}) %]">[% Project.name %]</a>
- [% # XXX The last part should link to blob_plain (or something) but doesn't ATM
- FOREACH part IN filename.split('/') %]
- / <a href="[% c.uri_for("tree", {hb=head.sha1}) %]">[% part %]</a>
- [% END %]
-</div>
+[% INCLUDE 'nav/path.tt2' %]
<div>
<pre class='blob'>[% blob %]</pre>
</div>
+++ /dev/null
-[% blob %]
<!-- git web interface version [% version %], (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke -->
<!-- git core binaries version [% git_version %] -->
<meta charset="utf-8">
- <meta name="generator" content="gitweb/[% version %] git/[% git_version %][% mod_perl_version %]"/>
- <meta name="robots" content="index, nofollow"/>
+ <meta name="generator" content="gitweb/[% version %] git/[% git_version %][% mod_perl_version %]">
+ <meta name="robots" content="index, nofollow">
<title>[%-
title = BLOCK;
c.config.sitename;
<a title="git homepage" href="http://git-scm.org">
<img src="[% c.uri_for('/logo.png') %]" alt="git" class="logo">
</a>
- <a href="[% c.uri_for('/') %]">A Gitalist</a>
+ <a href="[% c.uri_for('/', {p=''}) %]">A Gitalist</a>
[%- IF Project %]
/ <a href="[% c.uri_for('summary') %]">[% Project.name %]</a>
[% IF action; " / " _ action; END;
<div class='actions'>
- <a href="[% c.uri_for('summary') %]">summary</a> •
- <a href="[% c.uri_for('shortlog', {h=object.sha1}) %]">shortlog</a> •
- <a href="[% c.uri_for('log', {h=object.sha1}) %]">log</a> •
- <a href="[% c.uri_for('commit', {h=object.sha1}) %]">commit</a> •
+ <a href="[% c.uri_for('summary') %]">summary</a> •
+ <a href="[% c.uri_for('shortlog', {h=object.sha1}) %]">shortlog</a> •
+ <a href="[% c.uri_for('log', {h=object.sha1}) %]">log</a> •
+ <a href="[% c.uri_for('commit', {h=object.sha1}) %]">commit</a> •
<a href="[% c.uri_for('commitdiff', {h=object.sha1}) %]">commitdiff</a>
- [% IF object.type == 'commit' %] •
+ [% IF object.type == 'commit' %] •
<a href="[% c.uri_for('tree', {h=object.tree_sha1, hb=object.sha1}) %]">tree</a>
[% END %]
[% IF filename %]
- §
- <a href="[% c.uri_for('blob', {h=object.sha1,f=filename}) %]">blob</a> •
- <a href="[% c.uri_for('blame', {h=object.sha1,f=filename}) %]">blame</a> •
- <a href="[% c.uri_for('shortlog', {h=object.sha1,f=filename}) %]">history</a> •
+ §
+ <a href="[% c.uri_for('blob', {h=object.sha1,f=filename}) %]">blob</a> •
+ <a href="[% c.uri_for('blob_plain', {h=object.sha1,f=filename}) %]">raw</a> •
+ <a href="[% c.uri_for('blame', {h=object.sha1,f=filename}) %]">blame</a> •
+ <a href="[% c.uri_for('shortlog', {h=object.sha1,f=filename}) %]">history</a> •
<a href="[% c.uri_for(action, {f=filename}) %]">HEAD</a>
[% END %]
<div class='chroma-hash'>[% INCLUDE '_chroma_hash.tt2' sha1 = object.sha1 %]</div>
--- /dev/null
+<div class='path'>
+ <a href="[% c.uri_for("tree", {hb=head.sha1}) %]">[% Project.name %]</a>
+ [% FOREACH part IN filename.split('/') %]
+ [% path = loop.first ? part : path _ '/' _ part %]
+ / <a href="[% c.uri_for(loop.last ? 'blob' : 'tree', {hb=head.sha1,f=path}) %]">[% part %]</a>
+ [% END %]
+</div>
<div id="page-search">
<form method="get" action="[% c.uri_for('search') %]" enctype="application/x-www-form-urlencoded">
- <input name="p" type="hidden" value="[% Project.name %]" />
- <input name="a" type="hidden" value="search" />
- <input name="h" type="hidden" value="[% commit.sha1 %]" />
- <input name="f" type="hidden" value="[% c.req.param('f') %]" />
- <select name="type" >
+ <input name="p" type="hidden" value="[% Project.name %]">
+ <input name="a" type="hidden" value="search">
+ <input name="h" type="hidden" value="[% commit.sha1 %]">
+ <input name="f" type="hidden" value="[% c.req.param('f') %]">
+ <select name="type">
<option value="commit">commit</option>
<option value="author">author</option>
<option value="committer">committer</option>
<option value="pickaxe">pickaxe</option>
-->
</select><sup><a href="[% c.uri_for('search_help') %]">?</a></sup> search:
- <input type="text" name="text" value="[% c.req.param('s') %]"/>
- <span title="Extended regular expression"><label><input type="checkbox" name="regexp" value="1" />re</label></span>
+ <input type="text" name="text" value="[% c.req.param('s') %]">
+ <span title="Extended regular expression"><label><input type="checkbox" name="regexp" value="1">re</label></span>
</form>
</div>
test('/', 'a=summary');
test('/', 'a=heads');
+test('/', 'a=tags');
test('/', 'a=blob;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
test('/', 'a=blob;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=HEAD');
test('/', 'a=rss;h=refs/heads/master;opt=--no-merges');
test('/', 'a=rss;opt=--no-merges');
-TODO: {
- local $TODO = 'The project_index action is yet to be implemented';
- test('/', 'a=project_index');
-}
+test('/', 'a=project_index');
+
TODO: {
local $TODO = 'The opml action is yet to be implemented';
test('/', 'a=opml');
}
-TODO: {
- local $TODO = 'The tags action is yet to be implemented';
- test('/', 'a=tags');
-}
-TODO: {
- local $TODO = 'The blame action is yet to be implemented';
- test('/', 'a=blame;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
- test('/', 'a=blame;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=HEAD');
- test('/', 'a=blame;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=master');
- test('/', 'a=blame;f=dir1/file2;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=refs/heads/master');
- test('/', 'a=blame;f=dir1/file2;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
- test('/', 'a=blame;f=file1;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99');
- test('/', 'a=blame;f=file1;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=257cc5642cb1a054f08cc83f2d943e56fd3ebe99');
- test('/', 'a=blame;f=file1;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=5716ca5987cbf97d6bb54920bea6adde242d87e6');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=HEAD');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=master');
- test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=refs/heads/master');
- test('/', 'a=blame;f=file1;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
- test('/', 'a=blame;f=file1;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
-}
+test('/', 'a=blame;f=dir1/file2;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
+test('/', 'a=blame;f=file1;h=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
+test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=HEAD');
+test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=master');
+test('/', 'a=blame;f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hb=refs/heads/master');
+test('/', 'a=blame;f=file1;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+test('/', 'a=blame;f=file1;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
done_testing;