Merge branch 'action-blame' of git://github.com/broquaint/Gitalist
Tomas Doran [Sat, 21 Nov 2009 09:36:19 +0000 (09:36 +0000)]
* 'action-blame' of git://github.com/broquaint/Gitalist:
  Fix the path in the /blob & /blame header.
  Made /blob & /blob_plain actions a little more robust.
  Added /project_index action.
  Switch from latin1 chars to the HTML escape char equivalents.

lib/Gitalist/Controller/Root.pm
root/_log_pager.tt2
root/_shortlog.tt2
root/blame.tt2
root/blob.tt2
root/blob_plain.tt2 [deleted file]
root/default.tt2
root/nav/actions.tt2
root/nav/path.tt2 [new file with mode: 0644]
root/nav/search.tt2
t/03legacy_uri.t

index 8d36844..12701c2 100644 (file)
@@ -76,6 +76,20 @@ sub index :Path :Args(0) {
   );
 }
 
+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.
@@ -153,13 +167,7 @@ sub blame : Local {
   
 }
 
-=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')
@@ -171,9 +179,27 @@ sub blob : Local {
 
   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' : ''),
@@ -184,15 +210,27 @@ sub blob : Local {
     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) = @_;
 
@@ -200,7 +238,6 @@ sub blobdiff_plain : Local {
   $c->response->content_type('text/plain; charset=utf-8');
 
   $c->forward('blobdiff');
-
 }
 
 =head2 blobdiff
@@ -576,7 +613,7 @@ sub auto : Private {
     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 {
@@ -585,10 +622,6 @@ sub auto : Private {
   );
 }
 
-sub project_index : Local {
-    # FIXME - implement snapshot
-    Carp::croak "Not implemented.";
-}
 sub opml : Local {
     # FIXME - implement snapshot
     Carp::croak "Not implemented.";
index 7243c9a..8d1401c 100644 (file)
@@ -1,9 +1,9 @@
 <div class='pager'>
- <a href='[% c.uri_for(action, {h=HEAD}) %]'>HEAD</a> §
+ <a href='[% c.uri_for(action, {h=HEAD}) %]'>HEAD</a> &sect;
  [% 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}) %]'>&laquo; 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 &raquo;</a>
  [% END %]
 </div>
index 19caaf1..fc39b11 100644 (file)
@@ -26,7 +26,7 @@
    <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'>
index 23c7769..edd4a46 100644 (file)
@@ -5,7 +5,7 @@
 </div>
 [% END %]
 
-<h3>BLOB PATH</h3>
+[% INCLUDE 'nav/path.tt2' %]
 
 <div id='blame'>
 <table>
index 3a49fed..5f8299d 100644 (file)
@@ -1,18 +1,12 @@
 <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>
diff --git a/root/blob_plain.tt2 b/root/blob_plain.tt2
deleted file mode 100644 (file)
index 592f8c5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[% blob %]
index af0ed15..7ab9716 100644 (file)
@@ -5,8 +5,8 @@
   <!-- 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;
@@ -35,7 +35,7 @@
   <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;
index 0fe60b2..dd51adf 100644 (file)
@@ -1,17 +1,18 @@
 <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> &bull;
+    <a href="[% c.uri_for('shortlog', {h=object.sha1}) %]">shortlog</a> &bull;
+    <a href="[% c.uri_for('log', {h=object.sha1}) %]">log</a> &bull;
+    <a href="[% c.uri_for('commit', {h=object.sha1}) %]">commit</a> &bull;
     <a href="[% c.uri_for('commitdiff', {h=object.sha1}) %]">commitdiff</a>
-    [% IF object.type == 'commit' %] •
+    [% IF object.type == 'commit' %] &bull;
     <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> •
+    &sect;
+    <a href="[% c.uri_for('blob', {h=object.sha1,f=filename}) %]">blob</a> &bull;
+    <a href="[% c.uri_for('blob_plain', {h=object.sha1,f=filename}) %]">raw</a> &bull;
+    <a href="[% c.uri_for('blame', {h=object.sha1,f=filename}) %]">blame</a> &bull;
+    <a href="[% c.uri_for('shortlog', {h=object.sha1,f=filename}) %]">history</a> &bull;
     <a href="[% c.uri_for(action, {f=filename}) %]">HEAD</a>
     [% END %]
     <div class='chroma-hash'>[% INCLUDE '_chroma_hash.tt2' sha1 = object.sha1 %]</div>
diff --git a/root/nav/path.tt2 b/root/nav/path.tt2
new file mode 100644 (file)
index 0000000..c6df728
--- /dev/null
@@ -0,0 +1,7 @@
+<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>
index 42aeaea..330a17a 100644 (file)
@@ -1,10 +1,10 @@
 <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>
@@ -13,7 +13,7 @@
       <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>
index a895bda..b638fde 100644 (file)
@@ -16,6 +16,7 @@ local *test = curry_test_uri('repo1');
 
 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');
@@ -229,38 +230,22 @@ test('/', 'a=rss;h=refs/heads/master');
 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;