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