File Coverage

blib/lib/Git/Database.pm
Criterion Covered Total %
statement 33 36 91.6
branch 9 12 75.0
condition 8 11 72.7
subroutine 8 8 100.0
pod 2 2 100.0
total 60 69 86.9


line stmt bran cond sub pod time code
1             package Git::Database;
2             $Git::Database::VERSION = '0.011';
3 6     6   1015516 use strict;
  6         33  
  6         177  
4 6     6   31 use warnings;
  6         14  
  6         181  
5              
6 6     6   2465 use Module::Runtime qw( use_module );
  6         8688  
  6         38  
7 6     6   309 use File::Spec;
  6         19  
  6         575  
8              
9             sub _absdir {
10             my ($dir) = @_;
11             return # coerce to an absolute path
12             File::Spec->file_name_is_absolute($dir) ? $dir
13             : ref $dir ? eval { ref($dir)->new( File::Spec->rel2abs($dir) ) }
14             || File::Spec->rel2abs($dir)
15             : File::Spec->rel2abs($dir);
16             }
17              
18 6     6   2512 use Moo::Object ();
  6         7752  
  6         136  
19 6     6   2732 use namespace::clean;
  6         80543  
  6         40  
20              
21             # all known backend stores
22             my @STORES = (
23              
24             # complete backends, fastest first
25             'Git::Raw::Repository',
26             'Git',
27             'Git::Repository',
28             'Git::Wrapper',
29             'Git::Sub',
30              
31             # incomplete backends (don't do the Git::Database::Role::RefWriter role)
32             'Cogit',
33             'Git::PurePerl',
34             );
35              
36             my %MIN_VERSION = (
37             'Git::Raw::Repository' => 0.74,
38             'Git::Repository' => 1.300,
39             'Git::Sub' => 0.163320,
40             );
41              
42             # all installed backend stores
43             my $STORES;
44              
45             sub available_stores {
46 1   100 1 1 115 $STORES ||= [ map eval { use_module( $_ => $MIN_VERSION{$_} || 0 ) }, @STORES ];
  7   50     1085727  
47 1         1265147 return @$STORES;
48             }
49              
50             # creating store from a standard set of paramaters
51             my %STORE_FOR = (
52             'Cogit' => sub {
53             my %args = (
54             ( directory => _absdir($_[0]->{work_tree}) )x!! $_[0]->{work_tree},
55             ( gitdir => _absdir($_[0]->{git_dir}) )x!! $_[0]->{git_dir},
56             );
57             return Cogit->new( %args ? %args : ( directory => _absdir('.') ) );
58             },
59             'Git' => sub {
60             return Git->repository(
61             ( WorkingCopy => _absdir($_[0]->{work_tree}) )x!! $_[0]->{work_tree},
62             ( Repository => _absdir($_[0]->{git_dir}) )x!! $_[0]->{git_dir},
63             );
64             },
65             'Git::PurePerl' => sub {
66             my %args;
67             $args{directory} = _absdir("$_[0]->{work_tree}") if $_[0]->{work_tree};
68             $args{gitdir} = _absdir("$_[0]->{git_dir}") if $_[0]->{git_dir};
69             return Git::PurePerl->new( %args ? %args : ( directory => _absdir('.') ) );
70             },
71             'Git::Raw::Repository' => sub {
72             return Git::Raw::Repository->open(
73             $_[0]->{work_tree} || $_[0]->{git_dir} || '.'
74             );
75             },
76             'Git::Repository' => sub {
77             return Git::Repository->new(
78             ( work_tree => $_[0]->{work_tree} )x!! $_[0]->{work_tree},
79             ( git_dir => $_[0]->{git_dir} )x!! $_[0]->{git_dir},
80             );
81             },
82             'Git::Sub' => sub { $_[0]->{work_tree} || $_[0]->{git_dir} || _absdir('.') },
83             'Git::Wrapper' => sub {
84             return Git::Wrapper->new(
85             { dir => _absdir( $_[0]->{work_tree} || $_[0]->{git_dir} || '.' ) }
86             );
87             },
88             );
89              
90             sub new {
91 236     236 1 9713025 my $args = Moo::Object::BUILDARGS(@_);
92              
93             # store: an object that gives actual access to a git repo
94 236         6647 my ( $backend, $store );
95 236 100       1378 if ( defined( $store = $args->{store} ) ) {
96 81 100 66     5621 if ( $store eq '' ) {
    100          
97 10         228 return use_module('Git::Database::Backend::None')->new;
98             }
99             elsif ( !ref $store || -d $store ) {
100 10         407 return use_module('Git::Database::Backend::Git::Sub')
101             ->new( store => $store );
102             }
103 61   50     968 $backend = ref($store) || 'Git::Sub';
104             }
105              
106             # build the store using: backend, work_tree, git_dir
107             else {
108 155 50       1253 if ( $backend = $args->{backend} ) {
109 155 100       952 return use_module('Git::Database::Backend::None')->new
110             if $backend eq 'None';
111 154   100     2526 use_module $backend, $MIN_VERSION{$backend} || 0
112             }
113             else {
114              
115             # build the list of all installed store classes
116 0         0 my @stores = available_stores();
117              
118             # some really basic default
119 0 0       0 return use_module('Git::Database::Backend::None')->new
120             if !@stores;
121              
122             # pick the best available
123 0         0 $backend = shift @stores;
124             }
125 154         16780 $store = $STORE_FOR{$backend}->($args);
126             }
127              
128 215         1815530 return use_module("Git::Database::Backend::$backend")->new( store => $store );
129             }
130              
131             1;
132              
133             __END__
134              
135             =pod
136              
137             =head1 NAME
138              
139             Git::Database - Provide access to the Git object database
140              
141             =head1 VERSION
142              
143             version 0.011
144              
145             =head1 SYNOPSIS
146              
147             # get a store
148             my $r = Git::Repository->new();
149              
150             # build a backend to access the store
151             my $db = Git::Database::Backend::Git::Repository->new( store => $r );
152              
153             # or let Git::Database figure it out by itself
154             my $db = Git::Database->new( store => $r );
155              
156             # or let Git::Database assemble the store from its parts
157             my $db = Git::Database->new(
158             backend => 'Git::Repository',
159             work_tree => $work_tree,
160             );
161              
162             my $db = Git::Database->new(
163             backend => 'Git::Repository',
164             git_dir => $git_dir,
165             );
166              
167             # work in the current directory
168             my $db = Git::Database->new( backend => 'Git::Repository' );
169              
170             # pick the best available backend
171             my $db = Git::Database->new;
172              
173             =head1 DESCRIPTION
174              
175             Git::Database provides access from Perl to the object database stored
176             in a Git repository. It can use any supported Git wrapper to access
177             the Git object database maintained by Git.
178              
179             Git::Database is actually a factory class: L</new> returns
180             L<backend|Git::Database::Tutorial/backend> instances.
181              
182             Check L<Git::Database::Tutorial> for details.
183              
184             =head1 METHODS
185              
186             =head2 new
187              
188             my $r = Git::Repository->new;
189              
190             # $db is-a Git::Database::Backend::Git::Repository
191             my $db = Git::Database->new( store => $r );
192              
193             Return a L<backend|Git::Database::Tutorial/backend> object, based on
194             the parameters passed to C<new()>.
195              
196             If the C<store> parameter is given, all other paramaters are ignored,
197             and the returned backend is of the class corresponding to the
198             L<store|Git::Database::Tutorial/store> object.
199              
200             If the C<store> parameter is missing, the backend class is selected
201             according to the C<backend> parameter, or picked automatically among the
202             L<available store classes|available_stores> (picking the fastest
203             and more feature-complete among them). The actual store object
204             is then instantiated using the C<work_tree> and C<git_dir> optional
205             parameters. If none is given, the repository is assumed to be in the
206             current directory.
207              
208             =head2 available_stores
209              
210             say for Git::Database->available_stores;
211              
212             This class methods returns the list of L<store|Git::Database::Tutorial/store>
213             classes that are available (i.e. installed with a version matching the
214             minimum version requirements).
215              
216             =head1 BACKEND METHODS
217              
218             The backend methods are split between several roles, and not all backends
219             do all the roles. Therefore not all backend objects support all the
220             following methods.
221              
222             =head2 From L<Git::Database::Role::Backend>
223              
224             This is the minimum required role to be a backend. Hence this method is
225             always available.
226              
227             =over 4
228              
229             =item L<hash_object|Git::Database::Role::Backend/hash_object>
230              
231             =back
232              
233             =head2 From L<Git::Database::Role::ObjectReader>
234              
235             =over 4
236              
237             =item L<has_object|Git::Database::Role::ObjectReader/has_object>
238              
239             =item L<get_object_meta|Git::Database::Role::ObjectReader/get_object_meta>
240              
241             =item L<get_object_attributes|Git::Database::Role::ObjectReader/get_object_attributes>
242              
243             =item L<get_object|Git::Database::Role::ObjectReader/get_object>
244              
245             =item L<all_digests|Git::Database::Role::ObjectReader/all_digests>
246              
247             =back
248              
249             =head2 From L<Git::Database::Role::ObjectWriter>
250              
251             =over 4
252              
253             =item L<put_object|Git::Database::Role::ObjectWriter/put_object>
254              
255             =back
256              
257             =head2 From L<Git::Database::Role::RefReader>
258              
259             =over 4
260              
261             =item L<refs|Git::Database::Role::RefReader/refs>
262              
263             =item L<ref_names|Git::Database::Role::RefReader/ref_names>
264              
265             =item L<ref_digest|Git::Database::Role::RefReader/ref_digest>
266              
267             =back
268              
269             =head2 From L<Git::Database::Role::RefWriter>
270              
271             =over 4
272              
273             =item L<put_ref|Git::Database::Role::RefWriter/put_ref>
274              
275             =item L<delete_ref|Git::Database::Role::RefWriter/delete_ref>
276              
277             =back
278              
279             =head1 SEE ALSO
280              
281             =over 4
282              
283             =item Objects
284              
285             L<Git::Database::Object::Blob>,
286             L<Git::Database::Object::Tree>,
287             L<Git::Database::Object::Commit>,
288             L<Git::Database::Object::Tag>.
289              
290             =item Backend roles
291              
292             L<Git::Database::Role::Backend>,
293             L<Git::Database::Role::ObjectReader>,
294             L<Git::Database::Role::ObjectWriter>,
295             L<Git::Database::Role::RefReader>,
296             L<Git::Database::Role::RefWriter>.
297              
298             =item Backends
299              
300             L<Git::Database::Backend::None>,
301             L<Git::Database::Backend::Git::Repository>,
302             L<Git::Database::Backend::Git::Sub>,
303             L<Git::Database::Backend::Git::PurePerl>,
304             L<Git::Database::Backend::Cogit>,
305             L<Git::Database::Backend::Git>,
306             L<Git::Database::Backend::Git::Wrapper>,
307             L<Git::Database::Backend::Git::Raw>.
308              
309             =back
310              
311             =head1 SUPPORT
312              
313             You can find documentation for this module with the perldoc command.
314              
315             perldoc Git::Database
316              
317             You can also look for information at:
318              
319             =over 4
320              
321             =item * RT: CPAN's request tracker
322              
323             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Git-Database>
324              
325             =item * MetaCPAN
326              
327             L<http://metacpan.org/release/Git-Database>
328              
329             =back
330              
331             =head1 AUTHOR
332              
333             Philippe Bruhat (BooK) <book@cpan.org>.
334              
335             =head1 COPYRIGHT
336              
337             Copyright 2013-2019 Philippe Bruhat (BooK), all rights reserved.
338              
339             =head1 LICENSE
340              
341             This program is free software; you can redistribute it and/or modify it
342             under the same terms as Perl itself.
343              
344             =cut