File Coverage

blib/lib/Git/Repository/Plugin/Blame/Cache.pm
Criterion Covered Total %
statement 43 43 100.0
branch 18 22 81.8
condition 8 11 72.7
subroutine 8 8 100.0
pod 4 4 100.0
total 81 88 92.0


line stmt bran cond sub pod time code
1             package Git::Repository::Plugin::Blame::Cache;
2              
3 7     7   28743 use strict;
  7         16  
  7         253  
4 7     7   35 use warnings;
  7         11  
  7         191  
5              
6 7     7   38 use Carp;
  7         9  
  7         485  
7 7     7   4028 use Data::Validate::Type;
  7         62588  
  7         3521  
8              
9              
10             =head1 NAME
11              
12             Git::Repository::Plugin::Blame::Cache - Cache the output of C<< Git::Repository->blame() >>.
13              
14              
15             =head1 VERSION
16              
17             Version 1.3.0
18              
19             =cut
20              
21             our $VERSION = '1.3.0';
22              
23             my $CACHE = {};
24              
25              
26             =head1 SYNOPSIS
27              
28             use Git::Repository::Plugin::Blame::Cache;
29              
30             # Instantiate the cache for a given repository.
31             my $cache = Git::Repository::Plugin::Blame::Cache->new(
32             repository => $repository,
33             );
34              
35             my $repository = $cache->get_repository();
36              
37             # Cache blame lines.
38             $cache->set_blame_lines(
39             file => $file,
40             blame_lines => $blame_lines,
41             );
42              
43             # Retrieve blame lines from the cache.
44             my $blame_lines = $cache->get_blame_lines(
45             file => $file,
46             );
47              
48              
49             =head1 DESCRIPTION
50              
51             Cache the output of C<< Git::Repository::Plugin::Blame->blame() >> and
52             C<< Git::Repository->blame() >> by extension.
53              
54              
55             =head1 METHODS
56              
57             =head2 new()
58              
59             Return a cache object for the specified repository.
60              
61             my $cache = Git::Repository::Plugin::Blame::Cache->new(
62             repository => $repository,
63             options => $options,
64             );
65              
66             Arguments:
67              
68             =over 4
69              
70             =item * repository I<(mandatory)>
71              
72             A unique way to identify a repository. Typically, the root path of the
73             repository.
74              
75             =item * blame_args I<(optional)>
76              
77             A hashref of arguments used to generate the C output, if applicable.
78             This avoids caching the same output for C and C, for
79             example.
80              
81             =back
82              
83             =cut
84              
85             sub new
86             {
87 10     10 1 7769 my ( $class, %args ) = @_;
88 10         30 my $repository = delete( $args{'repository'} );
89 10   100     59 my $blame_args = delete( $args{'blame_args'} ) || {};
90 10 50       44 croak 'The following arguments are not valid: ' . join( ',', keys %args )
91             if scalar( keys %args ) != 0;
92              
93             # Verify mandatory arguments.
94 10 100 66     97 croak 'The "repository" argument is mandatory'
95             if !defined( $repository ) || $repository eq '';
96              
97             # Serialize the options passed, to hold a separate cache entry for each set
98             # of options.
99 9         20 my $serialized_blame_args = '';
100 9 100       45 if ( scalar( keys %$blame_args ) != 0 )
101             {
102 4         6 my @blame_args = ();
103 4         15 foreach my $blame_arg ( sort keys %$blame_args )
104             {
105 4 50       15 my $value = defined( $blame_args->{ $blame_arg } )
106             ? $blame_args->{ $blame_arg }
107             : '';
108 4         17 push( @blame_args, "$blame_arg=$value" );
109             }
110 4         13 $serialized_blame_args = join( ',', @blame_args );
111             }
112              
113             # If the cache element does not exist, create it.
114 9 100       44 if ( !defined( $CACHE->{ $repository }->{ $serialized_blame_args } ) )
115             {
116 7         62 $CACHE->{ $repository }->{ $serialized_blame_args } = bless(
117             {
118             repository => $repository,
119             files => {},
120             serialized_blame_args => $serialized_blame_args,
121             },
122             $class,
123             );
124             }
125              
126             # Return the corresponding cache element.
127 9         62 return $CACHE->{ $repository }->{ $serialized_blame_args };
128             }
129              
130              
131             =head2 get_repository()
132              
133             Return the unique identifier for the repository.
134              
135             my $repository = $cache->get_repository();
136              
137             =cut
138              
139             sub get_repository
140             {
141 1     1 1 3 my ( $self ) = @_;
142              
143 1         6 return $self->{'repository'};
144             }
145              
146              
147             =head2 get_blame_lines()
148              
149             Retrieve git blame lines from the cache (if they exist) for a given file.
150              
151             my $blame_lines = $cache->get_blame_lines(
152             file => $file,
153             );
154              
155             Arguments:
156              
157             =over 4
158              
159             =item * file (mandatory)
160              
161             The file for which you want the cached C output.
162              
163             =back
164              
165             =cut
166              
167             sub get_blame_lines
168             {
169 8     8 1 1391 my ( $self, %args ) = @_;
170 8         16 my $file = delete( $args{'file'} );
171 8 50       26 croak 'The following arguments are not valid: ' . join( ',', keys %args )
172             if scalar( keys %args ) != 0;
173              
174 8 100 66     63 croak 'The "file" argument is mandatory'
175             if !defined( $file ) || ( $file eq '' );
176              
177 7         46 return $self->{'files'}->{ $file };
178             }
179              
180              
181             =head2 set_blame_lines()
182              
183             Store in the cache the output of C for a given file.
184              
185             $cache->set_blame_lines(
186             file => $file,
187             blame_lines => $blame_lines,
188             );
189              
190             Arguments:
191              
192             =over 4
193              
194             =item * file (mandatory)
195              
196             The file for which you are caching the C output.
197              
198             =item * blame_lines (mandatory)
199              
200             The output of C<< Git::Repository::Plugin::Blame->blame() >>.
201              
202             =back
203              
204             =cut
205              
206             sub set_blame_lines
207             {
208 7     7 1 192 my ( $self, %args ) = @_;
209 7         28 my $file = delete( $args{'file'} );
210 7         16 my $blame_lines = delete( $args{'blame_lines'} );
211 7 50       27 croak 'The following arguments are not valid: ' . join( ',', keys %args )
212             if scalar( keys %args ) != 0;
213              
214 7 100 66     71 croak 'The "file" argument is mandatory'
215             if !defined( $file ) || $file eq '';
216 6 100       30 croak 'The "blame_lines" argument is mandatory'
217             if !defined( $blame_lines );
218 5 100       31 croak 'The "blame_lines" argument must be an arrayref'
219             if !Data::Validate::Type::is_arrayref( $blame_lines );
220              
221 4         112 $self->{'files'}->{ $file } = $blame_lines;
222              
223 4         14 return;
224             }
225              
226              
227             =head1 BUGS
228              
229             Please report any bugs or feature requests through the web interface at
230             L.
231             I will be notified, and then you'll automatically be notified of progress on
232             your bug as I make changes.
233              
234              
235             =head1 SUPPORT
236              
237             You can find documentation for this module with the perldoc command.
238              
239             perldoc Git::Repository::Plugin::Blame
240              
241              
242             You can also look for information at:
243              
244             =over 4
245              
246             =item * GitHub (report bugs there)
247              
248             L
249              
250             =item * AnnoCPAN: Annotated CPAN documentation
251              
252             L
253              
254             =item * CPAN Ratings
255              
256             L
257              
258             =item * MetaCPAN
259              
260             L
261              
262             =back
263              
264              
265             =head1 AUTHOR
266              
267             L,
268             C<< >>.
269              
270              
271             =head1 COPYRIGHT & LICENSE
272              
273             Copyright 2012-2015 Guillaume Aubert.
274              
275             This program is free software: you can redistribute it and/or modify it under
276             the terms of the GNU General Public License version 3 as published by the Free
277             Software Foundation.
278              
279             This program is distributed in the hope that it will be useful, but WITHOUT ANY
280             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
281             PARTICULAR PURPOSE. See the GNU General Public License for more details.
282              
283             You should have received a copy of the GNU General Public License along with
284             this program. If not, see http://www.gnu.org/licenses/
285              
286             =cut
287              
288             1;