requires 'Catalyst::View::Component::SubInclude' => '0.07';
requires 'Catalyst::View::TT';
requires 'Try::Tiny';
+requires 'Catalyst::Action::Serialize';
+
requires 'Template';
requires 'Template::Provider::Encoding';
requires 'Template::Plugin::Cycle';
requires 'Moose::Autobox';
requires 'MooseX::MultiMethods' => '0.10';
requires 'MooseX::Declare' => '0.32';
+requires 'MooseX::Types::DateTime';
+requires 'MooseX::Types::ISO8601';
requires 'MooseX::Types::Common';
requires 'MooseX::Types::Path::Class';
requires 'MooseX::Types';
+requires 'MooseX::Storage';
+requires 'JSON::Any';
+requires 'JSON::XS';
requires 'namespace::autoclean';
requires 'Git::PurePerl' => '0.46';
test_requires 'Test::More' => '0.88';
test_requires 'Test::utf8' => '0.02';
+test_requires 'HTTP::Request::Common';
resources bugtracker => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Gitalist';
resources repository => 'git://git.shadowcat.co.uk/catagits/Gitalist.git';
git_version => $git_version,
version => $Gitalist::VERSION,
+ # XXX Move these to a plugin!
time_since => sub {
return 'never' unless $_[0];
return age_string(time - $_[0]->epoch);
);
}
-sub search : Chained('base') Args(0) {}
-
-=head2 search_help
-
-Provides some help for the search form.
-
-=cut
-
-sub search_help : Chained('base') Args(0) {}
-
-sub end : ActionClass('RenderView') {}
+sub end : ActionClass('Serialize') {
+ my ($self, $c) = @_;
+ # Give repository views the current HEAD.
+ if ($c->stash->{Repository}) {
+ $c->stash->{HEAD} = $c->stash->{Repository}->head_hash;
+ }
+ if ($c->stash->{data} && blessed $c->stash->{data}) {
+ $c->stash->{rest} = $c->stash->{data}->pack;
+ }
+}
sub error_404 : Action {
my ($self, $c) = @_;
$c->response->body('Page not found');
}
+__PACKAGE__->config(
+ default => 'text/html',
+ map => {
+ 'text/html' => [qw/ View Default /],
+ 'application/json' => [qw/ JSON /],
+ }
+);
+
__PACKAGE__->meta->make_immutable;
__END__
use Moose::Autobox;
use aliased 'Gitalist::Git::Repository';
+ with 'Gitalist::Serializeable';
+
has repositories => (
is => 'ro',
isa => ArrayRef['Gitalist::Git::Repository'],
role Gitalist::Git::HasUtils {
use Gitalist::Git::Util;
+ use MooseX::Storage::Meta::Attribute::Trait::DoNotSerialize;
method BUILD {}
after BUILD {
get_gpp_object
gpp
/],
+ traits => [qw/ DoNotSerialize /],
);
method _build_util { confess(shift() . " cannot build _util") }
}
use MooseX::Declare;
use Moose::Autobox;
-class Gitalist::Git::Object {
+class Gitalist::Git::Object with Gitalist::Serializeable {
use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
# FIXME, use Types::Path::Class and coerce
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
- use MooseX::Types::Path::Class qw/Dir/;
use MooseX::Types::Moose qw/Str Maybe Bool HashRef ArrayRef/;
- use Gitalist::Git::Types qw/SHA1/;
use MooseX::MultiMethods;
+ use Gitalist::Git::Types qw/SHA1 DateTime Dir/;
use Moose::Autobox;
use List::MoreUtils qw/any zip/;
- use DateTime;
+ use aliased 'DateTime' => 'DT';
use Encode qw/decode/;
use I18N::Langinfo qw/langinfo CODESET/;
use Gitalist::Git::Object::Blob;
use Gitalist::Git::Object::Tree;
use Gitalist::Git::Object::Commit;
use Gitalist::Git::Object::Tag;
+
+ with 'Gitalist::Serializeable';
our $SHA1RE = qr/[0-9a-fA-F]{40}/;
is => 'ro', required => 1 );
has path => ( isa => Dir,
- is => 'ro', required => 1);
+ is => 'ro', required => 1,
+ traits => [qw/ DoNotSerialize /] );
has description => ( isa => Str,
is => 'ro',
lazy_build => 1,
);
- has last_change => ( isa => Maybe['DateTime'],
+ has last_change => ( isa => Maybe[DateTime],
is => 'ro',
lazy_build => 1,
);
is => 'ro',
lazy => 1,
default => sub {
- -d $_[0]->path->parent->subdir->($_[0]->name)
+ -d $_[0]->path->parent->subdir($_[0]->name)
? 1 : 0
},
);
has heads => ( isa => ArrayRef[HashRef],
is => 'ro',
- lazy_build => 1);
+ lazy_build => 1,
+ traits => [qw/ DoNotSerialize /],
+ );
has tags => ( isa => ArrayRef[HashRef],
is => 'ro',
lazy_build => 1);
--sort=-committerdate --count=1 refs/heads
});
if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
- my $dt = DateTime->from_epoch(epoch => $epoch);
+ my $dt = DT->from_epoch(epoch => $epoch);
$dt->set_time_zone($tz);
$last_change = $dt;
}
#FIXME: That isn't the time I'm looking for..
if (my ($epoch, $tz) = $line =~ /\s(\d+)\s+([+-]\d+)$/) {
- my $dt = DateTime->from_epoch(epoch => $epoch);
+ my $dt = DT->from_epoch(epoch => $epoch);
$dt->set_time_zone($tz);
$ret[-1]->{last_change} = $dt;
}
#FIXME: That isn't the time I'm looking for..
if($epoch and $tz) {
- my $dt = DateTime->from_epoch(epoch => $epoch);
+ my $dt = DT->from_epoch(epoch => $epoch);
$dt->set_time_zone($tz);
$ret[-1]->{last_change} = $dt;
}
package Gitalist::Git::Types;
use MooseX::Types
- -declare => [qw/SHA1/];
+ -declare => [qw/
+ SHA1
+ DateTime
+ Dir
+ /];
+use MooseX::Types::Path::Class;
+use MooseX::Types::ISO8601 qw/ISO8601DateTimeStr/;
+use MooseX::Types::DateTime ();
+use MooseX::Storage::Engine ();
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
subtype SHA1,
from NonEmptySimpleStr,
via { 1 };
+subtype DateTime,
+ as 'MooseX::Types::DateTime::DateTime',
+ where { 1 };
+
+MooseX::Storage::Engine->add_custom_type_handler(
+ DateTime,
+ expand => sub {
+ my $val = shift;
+ Carp::confess("Not implemented");
+ },
+ collapse => sub {
+ to_ISO8601DateTimeStr(shift);
+ },
+);
+
+subtype Dir,
+ as 'MooseX::Types::Path::Class::Dir',
+ where { 1 };
+
+MooseX::Storage::Engine->add_custom_type_handler(
+ Dir,
+ expand => sub {
+ my $val = shift;
+ Carp::confess("Not implemented");
+ },
+ collapse => sub {
+ shift() . '';
+ },
+);
+
1;
--- /dev/null
+package Gitalist::Serializeable;
+use Moose::Role;
+use namespace::autoclean;
+use MooseX::Storage;
+
+with Storage( traits => [qw|OnlyWhenBuilt|] );
+
+1;
+
+=head1 NAME
+
+Gitalist::Serializeable
+
+=head1 SYNOPSIS
+
+ class Gitalist::Git::Foo with Gitalist::Serializeable {
+ ...
+ }
+
+=head1 DESCRIPTION
+
+Role which applies a customised L<MooseX::Storage>.
+
+=head1 AUTHORS
+
+See L<Gitalist> for authors.
+
+=head1 LICENSE
+
+See L<Gitalist> for the license.
+
+=cut
is($proj->description, qq/some test repository/, 'repository description loaded');
isa_ok($proj->last_change, 'DateTime', 'last_change');
+is_deeply $proj->pack, {
+ '__CLASS__' => 'Gitalist::Git::Repository',
+ 'is_bare' => 1,
+ 'owner' => "T\x{e9}st",
+ 'last_change' => '2009-11-12T19:00:34Z',
+ 'name' => 'repo1',
+ 'description' => 'some test repository'
+};
+
my %references = %{$proj->references};
ok(keys %references >= 2, '->references hash has elements');
is($references{'36c6c6708b8360d7023e8a1649c45bcf9b3bd818'}->[0], 'heads/master', 'reference looks ok');
--- /dev/null
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+use HTTP::Request::Common;
+use FindBin qw/$Bin/;
+use JSON::Any;
+
+BEGIN {
+ $ENV{GITALIST_CONFIG} = $Bin;
+ $ENV{GITALIST_REPO_DIR} = '';
+ use_ok 'Catalyst::Test', 'Gitalist';
+}
+
+my $j = JSON::Any->new;
+
+my $res = request(GET 'http://localhost/summary?p=repo1', 'Content-Type' => 'application/json');
+is $res->code, 200;
+my $data = $j->decode($res->content);
+is ref($data), 'HASH';
+is_deeply $data, {
+ 'owner' => 'Tomas Doran',
+ 'is_bare' => 1,
+ '__CLASS__' => 'Gitalist::Git::Repository',
+ 'last_change' => '2009-11-12T19:00:34Z',
+ 'references' => {
+ '0710a7c8ee11c73e8098d08f9384c2a839c65e4e' => [
+ 'heads/branch1'
+ ],
+ '36c6c6708b8360d7023e8a1649c45bcf9b3bd818' => [
+ 'heads/master'
+ ]
+ },
+ 'name' => 'repo1',
+ 'description' => 'some test repository'
+ };
+
+done_testing;
+
+