Unfuck DateTime type with newer MX::Types
[catagits/Gitalist.git] / lib / Gitalist / Git / Tag.pm
1 package Gitalist::Git::Tag;
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/;
11 use MooseX::Types::DateTime       qw/ DateTime /;
12
13 use aliased 'DateTime' => 'DT';
14
15 has sha1        => ( isa      => SHA1,
16                      is       => 'ro',
17                      required => 1,
18                  );
19 has name        => ( isa      => NonEmptySimpleStr,
20                      is       => 'ro',
21                      required => 1,
22                  );
23
24 has type        => ( isa      => NonEmptySimpleStr,
25                      is       => 'ro',
26                      required => 1,
27                  );
28
29 has ref_sha1    => ( isa      => Maybe[SHA1],
30                      is       => 'ro',
31                      required => 0,
32                  );
33 has ref_type    => ( isa      => Maybe[NonEmptySimpleStr],
34                      is       => 'ro',
35                      required => 0,
36                  );
37 has committer   => ( isa      => NonEmptySimpleStr,
38                      is       => 'ro',
39                      required => 1,
40                  );
41 has last_change => ( isa      => Maybe[DateTime],
42                      is       => 'ro',
43                      required => 1,
44 );
45
46 around BUILDARGS => sub {
47     my $orig = shift;
48     my $class = shift;
49
50     if ( @_ == 1 && ! ref $_[0] ) {
51         my $line = $_[0];
52         # expects $line to match the output from
53         # --format=%(objectname) %(objecttype) %(refname) %(*objectname) %(*objecttype) %(subject)%00%(creator)
54         my ($sha1, $type, $name, $ref_sha1, $ref_type, $rest) = split / /, $line, 6;
55         $name =~ s!^refs/tags/!!;
56
57         unless ($ref_sha1) {
58             ($ref_sha1, $ref_type) = (undef, undef);
59         }
60         my ($subject, $commitinfo) = split /\0/, $rest, 2;
61         my ($committer, $epoch, $tz) =
62             $commitinfo =~ /(.*)\s(\d+)\s+([+-]\d+)$/;
63         my $dt = DT->from_epoch(
64             epoch => $epoch,
65             time_zone => $tz,
66         );
67
68         return $class->$orig(
69             sha1 => $sha1,
70             name => $name,
71             type => $type,
72             committer => $committer,
73             last_change => $dt,
74             ref_sha1 => $ref_sha1,
75             ref_type => $ref_type,
76         );
77     } else {
78         return $class->$orig(@_);
79     }
80 };
81
82 sub is_valid_tag {
83     local $_ = pop;
84     # Ignore tags like - http://git.kernel.org/?p=git/git.git;a=tag;h=d6602ec
85     return /^\S+ \S+ \S+ (?:\S+)? (?:\S+)?[^\0]+\0.*\s\d+\s+[+-]\d+$/;
86 }
87
88 1;