File Coverage

blib/lib/Git/Database/Object/Tree.pm
Criterion Covered Total %
statement 43 47 91.4
branch 13 18 72.2
condition 6 6 100.0
subroutine 8 8 100.0
pod 2 3 66.6
total 72 82 87.8


line stmt bran cond sub pod time code
1             package Git::Database::Object::Tree;
2             $Git::Database::Object::Tree::VERSION = '0.012';
3 8     8   4186 use Moo;
  8         21  
  8         40  
4 8     8   2384 use namespace::clean;
  8         19  
  8         75  
5              
6             with 'Git::Database::Role::Object';
7              
8 8     8   5787 use Git::Database::DirectoryEntry;
  8         21  
  8         4805  
9              
10 945     945 1 176495 sub kind {'tree'}
11              
12             has directory_entries => (
13             is => 'rwp',
14             required => 0,
15             predicate => 1,
16             lazy => 1,
17             builder => 1,
18             );
19              
20             sub BUILD {
21 610     610 0 368156 my ($self) = @_;
22              
23 610 100 100     6398 die "One of 'digest' or 'content' or 'directory_entries' is required"
      100        
24             if !$self->has_digest
25             && !$self->has_content
26             && !$self->has_directory_entries;
27              
28             # sort directory entries
29             $self->_set_directory_entries(
30 120         4453 [ sort { $a->filename cmp $b->filename }
31 603 100       10257 @{ $self->directory_entries }
  200         4097  
32             ]
33             ) if $self->has_directory_entries;
34             }
35              
36             sub _build_content {
37 298     298   4354 my ($self) = @_;
38              
39 298 100       1597 if ( !$self->has_directory_entries ) {
40 98         780 my $attr = $self->_get_object_attributes();
41 84 50       2421 return $attr->{content} if exists $attr->{content};
42              
43 0 0       0 if ( exists $attr->{directory_entries} ) {
44 0         0 $self->_set_directory_entries( $attr->{directory_entries} );
45             }
46             else {
47 0         0 die "Can't build content from these attributes: "
48             . join( ', ', sort keys %$attr );
49             }
50             }
51              
52 200         684 return join '', map $_->as_content, @{ $self->directory_entries };
  200         3976  
53             }
54              
55             # assumes content is set
56             sub _build_directory_entries {
57 239     239   15138 my ($self) = @_;
58              
59 239 100       2049 if ( !$self->has_content ) {
60 35         179 my $attr = $self->_get_object_attributes();
61 28 50       289 return $attr->{directory_entries} if exists $attr->{directory_entries};
62              
63 28 50       161 if ( exists $attr->{content} ) {
64 28         207 $self->_set_content( $attr->{content} );
65             }
66             else {
67 0         0 die "Can't build content from these attributes: "
68             . join( ', ', sort keys %$attr );
69             }
70             }
71              
72 232         4987 my $content = $self->content;
73 232 100       3473 return [] unless $content;
74              
75 208         560 my @directory_entries;
76 208         800 while ($content) {
77 364         12140 my $space_index = index( $content, ' ' );
78 364         1284 my $mode = substr( $content, 0, $space_index );
79 364         1359 $content = substr( $content, $space_index + 1 );
80 364         1018 my $null_index = index( $content, "\0" );
81 364         1009 my $filename = substr( $content, 0, $null_index );
82 364         893 $content = substr( $content, $null_index + 1 );
83 364         1540 my $digest = unpack( 'H*', substr( $content, 0, 20 ) );
84 364         978 $content = substr( $content, 20 );
85 364         9827 push @directory_entries,
86             Git::Database::DirectoryEntry->new(
87             mode => $mode,
88             filename => $filename,
89             digest => $digest,
90             );
91             }
92 208         11919 return \@directory_entries;
93             }
94              
95             sub as_string {
96 244     244 1 302397 return join '', map $_->as_string, @{ $_[0]->directory_entries };
  244         8112  
97             }
98              
99             1;
100              
101             =pod
102              
103             =for Pod::Coverage
104             BUILD
105             has_directory_entries
106              
107             =head1 NAME
108              
109             Git::Database::Object::Tree - A tree object in the Git object database
110              
111             =head1 VERSION
112              
113             version 0.012
114              
115             =head1 SYNOPSIS
116              
117             my $r = Git::Database->new(); # current Git repository
118             my $tree = $r->get_object('b52168'); # abbreviated digest
119              
120             # attributes
121             $tree->kind; # tree
122             $tree->digest; # b52168be5ea341e918a9cbbb76012375170a439f
123             ...; # etc., see below
124              
125             =head1 DESCRIPTION
126              
127             Git::Database::Object::Tree represents a C<tree> object
128             obtained via L<Git::Database> from a Git object database.
129              
130             =head1 ATTRIBUTES
131              
132             All attributes have a predicate method.
133              
134             =head2 kind
135              
136             The object kind: C<tree>.
137              
138             =head2 digest
139              
140             The SHA-1 digest of the tree object.
141              
142             =head2 content
143              
144             The object's actual content.
145              
146             =head2 size
147              
148             The size (in bytes) of the object content.
149              
150             =head2 directory_entries
151              
152             An array reference containing a list of L<Git::Database::DirectoryEntry>
153             objects representing the content of the tree.
154              
155             =head1 METHODS
156              
157             =head2 new()
158              
159             Create a new Git::Object::Database::Commit object.
160              
161             One (and only one) of the C<content> or C<directory_entries> arguments
162             is required.
163              
164             C<directory_entires> is an array reference containing a list of
165             L<Git::Database::DirectoryEntry> objects representing the content
166             of the tree.
167              
168             =head2 as_string()
169              
170             The content of the tree object, in the format returned by C<git ls-tree>.
171              
172             =head1 SEE ALSO
173              
174             L<Git::Database>,
175             L<Git::Database::Role::Object>.
176              
177             =head1 AUTHOR
178              
179             Philippe Bruhat (BooK) <book@cpan.org>.
180              
181             =head1 COPYRIGHT
182              
183             Copyright 2013-2016 Philippe Bruhat (BooK), all rights reserved.
184              
185             =head1 LICENSE
186              
187             This program is free software; you can redistribute it and/or modify it
188             under the same terms as Perl itself.
189              
190             =cut