File Coverage

blib/lib/Perl/Signature/Set.pm
Criterion Covered Total %
statement 63 67 94.0
branch 21 30 70.0
condition 2 3 66.6
subroutine 13 16 81.2
pod 10 10 100.0
total 109 126 86.5


line stmt bran cond sub pod time code
1             package Perl::Signature::Set;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Perl::Signature::Set - Create, store and check groups of signatures
8              
9             =head1 DESCRIPTION
10              
11             There are a number of cases where you might want to create and look after
12             a whole bunch of signatures.
13              
14             The most common of these is:
15              
16             1. Generate signatures
17             2. Do some process that shouldn't change the files functionally
18             3. Test to make sure it didn't
19              
20             Examples for 2. could be things like applying L, merging in
21             documentation-only patches from external sources, and other similar
22             things.
23              
24             Perl::Signature::Set lets you create an object that can store a while
25             bunch of file signatures, save the set to a file, load it in again,
26             and test the lot to check for changes.
27              
28             =head2 Saving and Loading
29              
30             For simplicity and easy of creation, Perl::Signature::Set has been
31             implemented as a subclass of L.
32              
33             =head1 METHODS
34              
35             =cut
36              
37 2     2   1709 use strict;
  2         3  
  2         131  
38 2     2   1640 use Config::Tiny ();
  2         3067  
  2         48  
39 2     2   18 use Perl::Signature ();
  2         4  
  2         43  
40              
41 2     2   14 use vars qw{$VERSION @ISA $errstr};
  2         5  
  2         213  
42             BEGIN {
43 2     2   7 $VERSION = '1.09';
44 2         42 @ISA = 'Config::Tiny';
45 2         1818 $errstr = '';
46             }
47              
48              
49              
50              
51              
52             #####################################################################
53             # Constructor and Accessors
54              
55             =pod
56              
57             =head2 new
58              
59             Creates a new Perl::Signature::Set object. Takes as an optional argument
60             the normalization layer you wish to use.
61              
62             Returns a new Perl::Signature::Set object.
63              
64             =cut
65              
66             sub new {
67 4 50   4 1 820 my $class = ref $_[0] ? ref shift : shift;
68 4 100 66     25 my $layer = @_ ? (defined $_[0] and $_[0] =~ /^[12]$/) ? shift : return undef : 1;
    100          
69              
70             # Create the basic object
71 3         16 my $self = bless {
72             signature => {
73             layer => $layer,
74             },
75             files => {},
76             }, $class;
77              
78 3         7 $self;
79             }
80              
81             =pod
82              
83             =head2 layer
84              
85             The C accessor returns the normalization layer that was used for
86             all of the signatures in the object.
87              
88             =cut
89              
90 0     0 1 0 sub layer { $_[0]->{signature}->{layer} }
91              
92              
93              
94              
95              
96             #####################################################################
97             # Perl::Signature Methods
98              
99             =pod
100              
101             =head2 add $file
102              
103             The C method takes the name of a file to generate a signature for
104             and add to the set.
105              
106             Returns the actual L object created as a convenience,
107             or C if the file has already been added, or on error.
108              
109             =cut
110              
111             sub add {
112 3     3 1 820 my $self = shift;
113 3 50       69 my $file = -f $_[0] ? shift : return undef;
114 3 100       13 return undef if $self->{files}->{$file};
115              
116             # Create the Signature object, and add it
117 2 50       11 my $Signature = Perl::Signature->new( $file ) or return undef;
118 2         13 $self->{files}->{$file} = $Signature;
119             }
120              
121             =pod
122              
123             =head2 files
124              
125             The C method provides all of the names of the files contained
126             in the set, in default sorted order.
127              
128             Returns a list of file names, or the null list if the set contains no
129             files.
130              
131             =cut
132              
133             sub files {
134 5     5 1 1449 my $self = shift;
135 5         8 my @files = sort keys %{$self->{files}};
  5         30  
136 5         16 @files;
137             }
138              
139             =pod
140              
141             =head2 file $filename
142              
143             The C method is used to get the L object for a
144             single named file.
145              
146             Returns a L object, or C if the file is not in
147             the set.
148              
149             =cut
150              
151             sub file {
152 8     8 1 1167 my $self = shift;
153 8 100       26 my $file = defined $_[0] ? shift : return undef;
154 6         29 $self->{files}->{$file};
155             }
156              
157             =pod
158              
159             =head2 signatures
160              
161             The C method returns all of the Signature objects from
162             the Set, in filename-sorted order.
163              
164             Returns a list of L objects, or the null list if
165             the set does not contain any Signature objects.
166              
167             =cut
168              
169             sub signatures {
170 5     5 1 2692 my $self = shift;
171 5         8 my $files = $self->{files};
172 5         15 map { $files->{$_} } sort keys %$files;
  4         12  
173             }
174              
175             =pod
176              
177             =head2 changes
178              
179             The C method checks the signatures for each file and provides
180             a hash listing the files that have changed as the key,
181             and either "changed" or "removed" as the value.
182              
183             Returns a HASH reference, false (C<''>) if there are no changes, or
184             C on error.
185              
186             =cut
187              
188             sub changes {
189 5     5 1 96632 my $self = shift;
190              
191             # Iterate of the files and check each one
192 5         15 my %results = ();
193 5         9 foreach my $file ( keys %{$self->{files}} ) {
  5         27  
194 10 100       1768 if ( -f $file ) {
195 7         48 my $changed = $self->{files}->{$file}->changed;
196 7 50       21 return undef unless defined $changed;
197 7 100       31 $results{$file} = 'changed' if $changed;
198             } else {
199 3         12 $results{$file} = 'removed';
200             }
201             }
202              
203 5 50       34 keys %results ? \%results : '';
204             }
205              
206              
207              
208              
209              
210             #####################################################################
211             # Config::Tiny Methods
212              
213             sub read_string {
214 2     2 1 2247 my $class = shift;
215              
216             # Create the basic object using the parent method
217 2         17 my $self = $class->SUPER::read_string(@_);
218              
219             # Check and clean up
220 2 50       753 $self->{signature} or return undef;
221 2 50       12 $self->{signature}->{layer} or return undef;
222 2 50       8 $self->{files} or return undef;
223              
224             # Manually bless a signature object for each file entry
225 2         4 my $files = $self->{files};
226 2         7 foreach my $file ( keys %$files ) {
227 4         6 my $signature = $files->{$file};
228 4 50       15 $signature =~ /^[a-f0-9]{32}$/ or return undef;
229 4         20 $files->{$file} = bless {
230             file => $file,
231             signature => $signature,
232             }, 'Perl::Signature';
233             }
234              
235 2         10 $self;
236             }
237              
238             sub write_string {
239 2     2 1 3228 my $self = shift;
240              
241             # Create the equivalent Config::Tiny object
242 2         19 my $save = Config::Tiny->new;
243 2         21 $save->{signature}->{layer} = $self->{signature}->{layer};
244 2         4 foreach my $file ( keys %{$self->{files}} ) {
  2         10  
245 4         15 $save->{files}->{$file} = $self->{files}->{$file}->original;
246             }
247              
248 2         158 $save->write_string;
249             }
250              
251 0     0 1   sub errstr { $errstr }
252 0     0     sub _error { $errstr = $_[1]; undef }
  0            
253              
254             1;
255              
256             =pod
257              
258             =head1 SUPPORT
259              
260             All bugs should be filed via the CPAN bug tracker at
261              
262             L
263              
264             For other issues, or commercial enhancement or support, contact the author.
265              
266             =head1 AUTHORS
267              
268             Adam Kennedy Eadamk@cpan.orgE
269              
270             =head1 SEE ALSO
271              
272             L, L, L, L
273              
274             =head1 COPYRIGHT
275              
276             Copyright 2005 - 2008 Adam Kennedy.
277              
278             This program is free software; you can redistribute
279             it and/or modify it under the same terms as Perl itself.
280              
281             The full text of the license can be found in the
282             LICENSE file included with this module.
283              
284             =cut