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