Added commit object serialization.
[catagits/Gitalist.git] / lib / Gitalist / Git / Object.pm
1 use MooseX::Declare;
2 use Moose::Autobox;
3
4 class Gitalist::Git::Object {
5     use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
6     use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
7
8     with 'Gitalist::Serializeable';
9
10     # repository and sha1 are required initargs
11     has repository => ( isa => 'Gitalist::Git::Repository',
12                      required => 1,
13                      is => 'ro',
14                      weak_ref => 1,
15                      handles => {
16                          _run_cmd => 'run_cmd',
17                          _run_cmd_fh => 'run_cmd_fh',
18                          _run_cmd_list => 'run_cmd_list',
19                          _get_gpp_object => 'get_gpp_object',
20                      },
21                  );
22     has sha1 => ( isa => NonEmptySimpleStr,
23                   required => 1,
24                   is => 'ro' );
25
26     has type => ( isa => NonEmptySimpleStr,
27                   is => 'ro',
28                   required => 1 );
29
30     has $_ => ( isa => NonEmptySimpleStr,
31                 required => 1,
32                 is => 'ro',
33                 lazy_build => 1 )
34         for qw/modestr size/;
35
36     has _gpp_obj => ( isa => 'Git::PurePerl::Object',
37                       required => 1,
38                       is => 'ro',
39                       lazy_build => 1,
40                       handles => [ 'content' ],
41                       traits => [qw/ DoNotSerialize /],
42                   );
43
44     # objects can't determine their mode or filename
45     has file => ( isa => NonEmptySimpleStr,
46                   required => 0,
47                   is => 'ro' );
48     has mode => ( isa => Int,
49                   required => 1,
50                   default => 0,
51                   is => 'ro' );
52
53     method BUILD { $self->$_() for qw/_gpp_obj size modestr/ }
54
55 ## Private methods
56
57 ## Builders
58     method _build__gpp_obj {
59         return $self->_get_gpp_object($self->sha1)
60     }
61
62     method "_build_size" {
63         my $v = $self->_cat_file_with_flag('s');
64         chomp($v);
65         return $v;
66     }
67
68     method _cat_file_with_flag ($flag) {
69         $self->_run_cmd('cat-file', '-' . $flag, $self->{sha1})
70     }
71
72     method _build_modestr {
73         return _mode_str($self->mode);
74     }
75
76     # via gitweb.pm circa line 1305
77     use Fcntl ':mode';
78     use constant {
79         S_IFINVALID => 0030000,
80         S_IFGITLINK => 0160000,
81     };
82
83     # submodule/subrepository, a commit object reference
84     sub S_ISGITLINK($) {
85         return (($_[0] & S_IFMT) == S_IFGITLINK)
86     }
87
88     # convert file mode in octal to symbolic file mode string
89     sub _mode_str {
90         my $mode = shift;
91
92         if (S_ISGITLINK($mode)) {
93             return 'm---------';
94         } elsif (S_ISDIR($mode & S_IFMT)) {
95             return 'drwxr-xr-x';
96         } elsif (S_ISLNK($mode)) {
97             return 'lrwxrwxrwx';
98         } elsif (S_ISREG($mode)) {
99             # git cares only about the executable bit
100             if ($mode & S_IXUSR) {
101                 return '-rwxr-xr-x';
102             } else {
103                 return '-rw-r--r--';
104             }
105         } else {
106             return '----------';
107         }
108     }
109
110 } # end class
111
112 __END__
113
114 =head1 NAME
115
116 Gitalist::Git::Object - Model of a git object.
117
118 =head1 SYNOPSIS
119
120     my $object = Repository->get_object($sha1);
121
122 =head1 DESCRIPTION
123
124 Abstract base class for git objects.
125
126
127 =head1 ATTRIBUTES
128
129
130 =head1 METHODS
131
132
133 =head1 AUTHORS
134
135 See L<Gitalist> for authors.
136
137 =head1 LICENSE
138
139 See L<Gitalist> for the license.
140
141 =cut