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   31094 use strict;
  7         8  
  7         223  
4 7     7   30 use warnings;
  7         8  
  7         195  
5              
6 7     7   30 use Carp;
  7         8  
  7         414  
7 7     7   3596 use Data::Validate::Type;
  7         56393  
  7         3578  
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.4.0
18              
19             =cut
20              
21             our $VERSION = '1.4.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 6684 my ( $class, %args ) = @_;
88 10         22 my $repository = delete( $args{'repository'} );
89 10   100     52 my $blame_args = delete( $args{'blame_args'} ) || {};
90 10 50       31 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     74 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         16 my $serialized_blame_args = '';
100 9 100       52 if ( scalar( keys %$blame_args ) != 0 )
101             {
102 4         6 my @blame_args = ();
103 4         12 foreach my $blame_arg ( sort keys %$blame_args )
104             {
105             my $value = defined( $blame_args->{ $blame_arg } )
106 4 50       12 ? $blame_args->{ $blame_arg }
107             : '';
108 4         11 push( @blame_args, "$blame_arg=$value" );
109             }
110 4         12 $serialized_blame_args = join( ',', @blame_args );
111             }
112              
113             # If the cache element does not exist, create it.
114 9 100       33 if ( !defined( $CACHE->{ $repository }->{ $serialized_blame_args } ) )
115             {
116 7         41 $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         52 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 2 my ( $self ) = @_;
142              
143 1         5 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 1338 my ( $self, %args ) = @_;
170 8         15 my $file = delete( $args{'file'} );
171 8 50       22 croak 'The following arguments are not valid: ' . join( ',', keys %args )
172             if scalar( keys %args ) != 0;
173              
174 8 100 66     56 croak 'The "file" argument is mandatory'
175             if !defined( $file ) || ( $file eq '' );
176              
177 7         39 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 137 my ( $self, %args ) = @_;
209 7         14 my $file = delete( $args{'file'} );
210 7         10 my $blame_lines = delete( $args{'blame_lines'} );
211 7 50       23 croak 'The following arguments are not valid: ' . join( ',', keys %args )
212             if scalar( keys %args ) != 0;
213              
214 7 100 66     60 croak 'The "file" argument is mandatory'
215             if !defined( $file ) || $file eq '';
216 6 100       23 croak 'The "blame_lines" argument is mandatory'
217             if !defined( $blame_lines );
218 5 100       25 croak 'The "blame_lines" argument must be an arrayref'
219             if !Data::Validate::Type::is_arrayref( $blame_lines );
220              
221 4         106 $self->{'files'}->{ $file } = $blame_lines;
222              
223 4         16 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-2017 Guillaume Aubert.
274              
275             This code is free software; you can redistribute it and/or modify it under the
276             same terms as Perl 5 itself.
277              
278             This program is distributed in the hope that it will be useful, but WITHOUT ANY
279             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
280             PARTICULAR PURPOSE. See the LICENSE file for more details.
281              
282             =cut
283              
284             1;