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