File Coverage

blib/lib/Git/Database/Backend/Git/Wrapper.pm
Criterion Covered Total %
statement 53 57 92.9
branch 11 16 68.7
condition n/a
subroutine 14 14 100.0
pod 0 8 0.0
total 78 95 82.1


line stmt bran cond sub pod time code
1             package Git::Database::Backend::Git::Wrapper;
2             $Git::Database::Backend::Git::Wrapper::VERSION = '0.011';
3 7     7   220570 use Cwd qw( cwd );
  7         77  
  7         1106  
4 7     7   214 use Git::Wrapper;
  7         66  
  7         605  
5 7     7   109 use Git::Version::Compare qw( ge_git );
  7         63  
  7         816  
6 7     7   110 use Sub::Quote;
  7         64  
  7         1218  
7              
8 7     7   112 use Moo;
  7         72  
  7         204  
9 7     7   27323 use namespace::clean;
  7         38  
  7         207  
10              
11             with
12             'Git::Database::Role::Backend',
13             'Git::Database::Role::ObjectReader',
14             'Git::Database::Role::ObjectWriter',
15             'Git::Database::Role::RefReader',
16             'Git::Database::Role::RefWriter',
17             ;
18              
19             has '+store' => (
20             isa => quote_sub( q{
21             die 'store is not a Git::Wrapper object'
22             if !eval { $_[0]->isa('Git::Wrapper') }
23             } ),
24             default => sub { Git::Wrapper->new( cwd() ) },
25             );
26              
27             # Git::Database::Role::Backend
28             sub hash_object {
29 95     95 0 29804 my ( $self, $object ) = @_;
30 95         2780 my @out = $self->store->hash_object( { -STDIN => $object->content },
31             '--stdin', '-t', $object->kind );
32 95         914337 return shift @out;
33             }
34              
35             # Git::Database::Role::ObjectReader
36             sub get_object_meta {
37 57     57 0 428 my ( $self, $digest ) = @_;
38 57         1599 my ($meta) =
39             $self->store->cat_file( { -STDIN => "$digest\n" }, '--batch-check' );
40 57 50       538874 warn join $/, @{ $self->store->ERR }, '' if @{ $self->store->ERR };
  0         0  
  57         888  
41              
42             # protect against weird cases like if $digest contains a space
43 57         2056 my @parts = split / /, $meta;
44 57 100       2319 return ( $digest, 'missing', undef ) if $parts[-1] eq 'missing';
45              
46 24         544 my ( $kind, $size ) = splice @parts, -2;
47 24         1435 return join( ' ', @parts ), $kind, $size;
48             }
49              
50             sub get_object_attributes {
51 156     156 0 1440 my ( $self, $digest ) = @_;
52              
53 156         3781 my @out = $self->store->cat_file( { -STDIN => "$digest\n" }, '--batch' );
54 156         1528520 my $meta = shift @out;
55 156 100       1124 warn join $/, @{ $self->store->ERR }, '' if @{ $self->store->ERR };
  1         65  
  156         1643  
56              
57             # protect against weird cases like if $digest contains a space
58 156         5189 my ( $sha1, $kind, $size ) = my @parts = split / /, $meta;
59              
60             # git versions >= 2.11.0.rc0 throw more verbose errors
61 156 50       3272 return undef if $parts[0] =~ /^(?:symlink|dangling|loop|notdir)$/;
62              
63             # object does not exist in the git object database
64 156 100       3179 return undef if $parts[-1] eq 'missing';
65              
66             return {
67 96         4493 kind => $kind,
68             size => $size,
69             content => join( $/, @out ), # I expect this to break on binary data
70             digest => $sha1
71             };
72             }
73              
74             sub all_digests {
75 11     11 0 230183 my ( $self, $kind ) = @_;
76 11         153 my $store = $self->store;
77 11 100       538 my $re = $kind ? qr/ \Q$kind\E / : qr/ /;
78              
79             # the --batch-all-objects option appeared in v2.6.0-rc0
80 11 50       205 if ( ge_git( $store->version, '2.6.0.rc0' ) ) {
81 11         91279 return map +( split / / )[0],
82             grep /$re/,
83             $store->cat_file(qw( --batch-check --batch-all-objects ));
84             }
85             else { # this won't return unreachable objects
86 0         0 my $revs = join "\n", map +( split / / )[0],
87             sort $store->rev_list(qw( --all --objects ));
88 0 0       0 return if !length $revs;
89 0         0 return map +( split / / )[0], grep /$re/,
90             $store->cat_file( qw( --batch-check ), { -STDIN => "$revs\n" } );
91             }
92             }
93              
94             # Git::Database::Role::ObjectWriter
95             sub put_object {
96 13     13 0 206 my ( $self, $object ) = @_;
97 13         205 my ($hash) = $self->store->hash_object( '-t', $object->kind, '-w',
98             { stdin => 1, -STDIN => $object->content } );
99 13         138404 return $hash;
100             }
101              
102             # Git::Database::Role::RefReader
103             sub refs {
104 20     20 0 66424 my ($self) = @_;
105             return {
106 20         444 reverse map +( split / / ),
107             $self->store->show_ref( { head => 1 } )
108             };
109             }
110              
111             # Git::Database::Role::RefWriter
112             sub put_ref {
113 2     2 0 16456 my ($self, $refname, $digest ) = @_;
114 2         77 $self->store->update_ref( $refname, $digest );
115             }
116              
117             sub delete_ref {
118 2     2 0 40 my ($self, $refname ) = @_;
119 2         70 $self->store->update_ref( '-d', $refname );
120             }
121              
122             1;
123              
124             __END__
125              
126             =pod
127              
128             =for Pod::Coverage
129             hash_object
130             get_object_attributes
131             get_object_meta
132             all_digests
133             put_object
134             refs
135             put_ref
136             delete_ref
137              
138             =head1 NAME
139              
140             Git::Database::Backend::Git::Wrapper - A Git::Database backend based on Git::Wrapper
141              
142             =head1 VERSION
143              
144             version 0.011
145              
146             =head1 SYNOPSIS
147              
148             # get a store
149             my $r = Git::Wrapper->new('/var/foo');
150              
151             # let Git::Database produce the backend
152             my $db = Git::Database->new( store => $r );
153              
154             =head1 DESCRIPTION
155              
156             This backend reads and writes data from a Git repository using the
157             L<Git::Wrapper> module.
158              
159             =head2 Git Database Roles
160              
161             This backend does the following roles
162             (check their documentation for a list of supported methods):
163             L<Git::Database::Role::Backend>,
164             L<Git::Database::Role::ObjectReader>,
165             L<Git::Database::Role::ObjectWriter>,
166             L<Git::Database::Role::RefReader>,
167             L<Git::Database::Role::RefWriter>.
168              
169             =head1 AUTHORS
170              
171             Philippe Bruhat (BooK) <book@cpan.org>
172              
173             Sergey Romanov provided the code to support the
174             L<Git::Database::Role::ObjectWriter>, L<Git::Database::Role::RefReader>,
175             and L<Git::Database::Role::RefWriter> roles.
176              
177             =head1 COPYRIGHT
178              
179             Copyright 2016-2017 Philippe Bruhat (BooK), all rights reserved.
180              
181             =head1 LICENSE
182              
183             This program is free software; you can redistribute it and/or modify it
184             under the same terms as Perl itself.
185              
186             =cut