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