X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FGitalist%2FController%2FRoot.pm;h=9ec74e1c133e781f1f98fac04115c1bab674b111;hb=14664e1c094097ee454e254d2b40128c240a6e2e;hp=75f5e5f9ed10ae82a960fde77ecf138159c37610;hpb=1feb3d6b09a8499205be3e71b928c9828ab3fbf1;p=catagits%2FGitalist.git diff --git a/lib/Gitalist/Controller/Root.pm b/lib/Gitalist/Controller/Root.pm index 75f5e5f..9ec74e1 100644 --- a/lib/Gitalist/Controller/Root.pm +++ b/lib/Gitalist/Controller/Root.pm @@ -27,7 +27,12 @@ Gitalist::Controller::Root - Root Controller for Gitalist =cut use IO::Capture::Stdout; -use File::Slurp qw(slurp); + +=head2 run_gitweb + +The main shim around C. + +=cut sub run_gitweb { my ( $self, $c ) = @_; @@ -52,6 +57,34 @@ sub run_gitweb { } } +sub _get_commit { + my($self, $c) = @_; + + my $h = $c->req->param('h'); + my $f = $c->req->param('f'); + my $m = $c->model('Git'); + + # Either use the provided h(ash) parameter, the f(ile) parameter or just use HEAD. + my $hash = ($h =~ /[^a-f0-9]/ ? $m->head_hash($h) : $h) + || ($f && $m->hash_by_path($f)) + || $m->head_hash + # XXX This could definitely use more context. + || Carp::croak("Couldn't find a hash for the commit object!"); + + + (my $pd = $m->project_dir( $m->project )) =~ s{/\.git$}(); + my $commit = $m->get_object($hash) + or Carp::croak("Couldn't find a commit object for '$hash' in '$pd'!"); + + return $commit; +} + +=head2 index + +Provides the project listing. + +=cut + sub index :Path :Args(0) { my ( $self, $c ) = @_; @@ -71,15 +104,214 @@ sub index :Path :Args(0) { ); } +=head2 summary + +A summary of what's happening in the repo. + +=cut + +sub summary : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + $c->stash( + commit => $commit, + info => $c->model('Git')->project_info($c->model('Git')->project), + log_lines => [$c->model('Git')->list_revs( + sha1 => $commit->sha1, count => Gitalist->config->{paging}{summary} + )], + refs => $c->model('Git')->references, + heads => [$c->model('Git')->heads], + action => 'summary', + ); +} + +=head2 heads + +The current list of heads (aka branches) in the repo. + +=cut + +sub heads : Local { + my ( $self, $c ) = @_; + + $c->stash( + commit => $self->_get_commit($c), + heads => [$c->model('Git')->heads], + action => 'heads', + ); +} + +=head2 blob + +The blob action i.e the contents of a file. + +=cut + sub blob : Local { my ( $self, $c ) = @_; + my $h = $c->req->param('h') + || $c->model('Git')->hash_by_path($c->req->param('f')) + || die "No file or sha1 provided."; + my $hb = $c->req->param('hb') + || $c->model('Git')->head_hash + || die "Couldn't discern the corresponding head."; + + my $filename = $c->req->param('f') || ''; + + $c->stash( + blob => $c->model('Git')->get_object($h)->content, + head => $c->model('Git')->get_object($hb), + filename => $filename, + # XXX Hack hack hack, see View::SyntaxHighlight + language => ($filename =~ /\.p[lm]$/ ? 'Perl' : ''), + action => 'blob', + ); + + $c->forward('View::SyntaxHighlight'); +} + +=head2 blobdiff + +Exposes a given diff of a blob. + +=cut + +sub blobdiff : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + my $filename = $c->req->param('f') + || croak("No file specified!"); + my($tree, $patch) = $c->model('Git')->diff( + commit => $commit, + parent => $c->req->param('hp') || '', + file => $filename, + patch => 1, + ); $c->stash( - blob => $c->model('GPP')->get_object($c->req->param('h'))->content, - action => 'blob', + commit => $commit, + diff => $patch, + # XXX Hack hack hack, see View::SyntaxHighlight + blobs => [$patch->[0]->{diff}], + language => 'Diff', + action => 'blobdiff', ); + + $c->forward('View::SyntaxHighlight'); } +=head2 commit + +Exposes a given commit. + +=cut + +sub commit : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + $c->stash( + commit => $commit, + diff_tree => ($c->model('Git')->diff(commit => $commit))[0], + branches_on => [$c->model('Git')->refs_for($commit->sha1)], + action => 'commit', + ); +} + +=head2 commitdiff + +Exposes a given diff of a commit. + +=cut + +sub commitdiff : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + my($tree, $patch) = $c->model('Git')->diff( + commit => $commit, + parent => $c->req->param('hp') || '', + patch => 1, + ); + $c->stash( + commit => $commit, + diff_tree => $tree, + diff => $patch, + # XXX Hack hack hack, see View::SyntaxHighlight + blobs => [map $_->{diff}, @$patch], + language => 'Diff', + action => 'commitdiff', + ); + + $c->forward('View::SyntaxHighlight'); +} + +=head2 shortlog + +Expose an abbreviated log of a given sha1. + +=cut + +sub shortlog : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + my %logargs = ( + sha1 => $commit->sha1, + count => Gitalist->config->{paging}{log}, + ($c->req->param('f') ? (file => $c->req->param('f')) : ()) + ); + + my $page = $c->req->param('pg') || 0; + $logargs{skip} = $c->req->param('pg') * $logargs{count} + if $c->req->param('pg'); + + $c->stash( + commit => $commit, + log_lines => [$c->model('Git')->list_revs(%logargs)], + refs => $c->model('Git')->references, + action => 'shortlog', + page => $page + 1, + ); +} + +=head2 log + +Calls shortlog internally. Perhaps that should be reversed ... + +=cut +sub log : Local { + $_[0]->shortlog($_[1]); + $_[1]->stash->{action} = 'log'; +} + +=head2 tree + +The tree of a given commit. + +=cut + +sub tree : Local { + my ( $self, $c ) = @_; + + my $commit = $self->_get_commit($c); + $c->stash( + # XXX Useful defaults needed ... + commit => $commit, + tree => $c->model('Git')->get_object($c->req->param('hb')), + tree_list => [$c->model('Git')->list_tree($commit->sha1)], + action => 'tree', + ); +} + +=head2 reflog + +Expose the local reflog. This may go away. + +=cut + sub reflog : Local { my ( $self, $c ) = @_; @@ -93,15 +325,20 @@ sub reflog : Local { ); } -sub commit : Local { - my ( $self, $c ) = @_; +sub search : Local { + Carp::croak "Not implemented."; +} - $c->stash( - commit => $c->model('GPP')->get_object($c->req->param('h')), - action => 'commit', - ); +sub search_help : Local { + Carp::croak "Not implemented."; } +=head2 auto + +Populate the header and footer. Perhaps not the best location. + +=cut + sub auto : Private { my($self, $c) = @_; @@ -193,7 +430,7 @@ sub header { if(defined $project) { $c->stash( - search_text => ( $c->req->param('s') || $c->req->param('searchtext') ), + search_text => ( $c->req->param('s') || $c->req->param('searchtext') || ''), search_hash => ( $c->req->param('hb') || $c->req->param('hashbase') || $c->req->param('h') || $c->req->param('hash') || 'HEAD' ), @@ -292,7 +529,10 @@ Attempt to render a view, if needed. =cut -sub end : ActionClass('RenderView') {} +sub end : ActionClass('RenderView') { + # Give every view the current HEAD. + $_[1]->stash->{HEAD} = $_[1]->model('Git')->head_hash; +} =head1 AUTHOR