First cut at reintroducing object serialization.
[catagits/Gitalist.git] / lib / Gitalist / Git / Head.pm
1 package Gitalist::Git::Head;
2
3 use Moose;
4 use namespace::autoclean;
5
6 with 'Gitalist::Git::Serializable';
7
8 use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
9 use MooseX::Types::Moose          qw/Maybe/;
10 use Gitalist::Git::Types          qw/SHA1 DateTime/;
11
12 use aliased 'DateTime' => 'DT';
13
14 has sha1        => ( isa      => SHA1,
15                      is       => 'ro',
16                      required => 1,
17                  );
18 has name        => ( isa      => NonEmptySimpleStr,
19                      is       => 'ro',
20                      required => 1,
21                  );
22 has committer   => ( isa      => NonEmptySimpleStr,
23                      is       => 'ro',
24                      required => 1,
25                  );
26 has last_change => ( isa      => Maybe[DateTime],
27                      is       => 'ro',
28                      required => 1,
29 );
30
31 around BUILDARGS => sub {
32     my $orig = shift;
33     my $class = shift;
34
35     if ( @_ == 1 && ! ref $_[0] ) {
36         my $line = $_[0];
37         # expects $line to match the output from
38         # for-each-ref --format=%(objectname)%00%(refname)%00%(committer)
39         my ($sha1, $name, $commitinfo) = split /\0/, $line, 3;
40         $name =~ s!^refs/heads/!!;
41
42         my ($committer, $epoch, $tz) =
43             $commitinfo =~ /(.*)\s(\d+)\s+([+-]\d+)$/;
44         my $dt = DT->from_epoch(
45             epoch => $epoch,
46             time_zone => $tz,
47         );
48
49         return $class->$orig(
50             sha1 => $sha1,
51             name => $name,
52             committer => $committer,
53             last_change => $dt,
54         );
55     } else {
56         return $class->$orig(@_);
57     }
58 };
59
60 1;