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