File Coverage

blib/lib/File/Versions.pm
Criterion Covered Total %
statement 57 68 83.8
branch 16 28 57.1
condition 5 12 41.6
subroutine 11 12 91.6
pod 2 8 25.0
total 91 128 71.0


line stmt bran cond sub pod time code
1             package File::Versions;
2 1     1   14374 use warnings;
  1         1  
  1         30  
3 1     1   3 use strict;
  1         1  
  1         61  
4             require Exporter;
5             our @ISA = qw(Exporter);
6             our @EXPORT_OK = qw/backup_name make_backup/;
7             our %EXPORT_TAGS = ('all' => \@EXPORT_OK);
8 1     1   3 use Carp;
  1         5  
  1         44  
9 1     1   3 use List::Util qw/max/;
  1         1  
  1         952  
10              
11             our $VERSION = '0.08';
12              
13             # Get the type of version control. Not exported.
14              
15             sub get_version_control
16             {
17 5     5 0 8 return $ENV{VERSION_CONTROL};
18             }
19              
20             sub get_file_max_version_number
21             {
22 3     3 0 2 my ($file, $options) = @_;
23              
24             # The list of files which look like backups of this file.
25              
26 3         3 my @backup_files;
27              
28             # The version numbers of the files.
29              
30             my @version_numbers;
31              
32             # Get a list of candidate files using "glob".
33              
34 3         119 @backup_files = <$file.~*~>;
35              
36 3         7 for my $backup_file (@backup_files) {
37 1 50       20 if ($backup_file =~ /^$file.~(\d+)~$/) {
38 1         2 my $version_number = $1;
39 1         3 push @version_numbers, $version_number;
40             }
41             }
42 3         2 my $max;
43 3 100       7 if (@version_numbers) {
44 1         8 $max = max @version_numbers;
45             }
46 3         26 return $max;
47             }
48              
49             # Look at the files in the current directory and find the next
50             # possible file. Not exported.
51              
52             sub find_next_numbered
53             {
54 3     3 0 4 my ($file, $options) = @_;
55              
56 3         5 my $max_version_number = get_file_max_version_number ($file, $options);
57 3         4 my $next = 1;
58 3 100       6 if ($max_version_number) {
59 1         2 $next = $max_version_number + 1;
60             }
61 3         7 my $next_file = "$file.~$next~";
62              
63             # Test that this file really does not exist.
64              
65 3 50       26 if (-f $next_file) {
66 0         0 die "There is a bug in this program. A file exists which is not supposed to.";
67             }
68 3         6 return $next_file;
69             }
70              
71             # Find out what to use for the value of the suffix for simple backups.
72              
73             sub simple_backup_suffix
74             {
75 2     2 0 1 my $suffix;
76 2         3 $suffix = $ENV{SIMPLE_BACKUP_SUFFIX};
77 2 50       4 if (! $suffix) {
78 2         6 $suffix = '~';
79             }
80 2         4 return $suffix;
81             }
82              
83             # Make a simple backup of the file, copy it to a file with the same
84             # name plus the extension '~' or the value of SIMPLE_BACKUP_SUFFIX.
85              
86             sub simple_backup
87             {
88 2     2 0 3 my ($file, $options) = @_;
89 2         3 my $suffix = simple_backup_suffix ($options);
90 2         4 my $backup = "$file$suffix";
91 2         2 return $backup;
92             }
93              
94             # Make numbered backups of files that already have them, otherwise
95             # simple backups.
96              
97             sub default_backup
98             {
99 0     0 0 0 my ($file, $options) = @_;
100 0         0 my $backup;
101 0         0 my $max_version_number = get_file_max_version_number ($file, $options);
102 0 0       0 if ($max_version_number) {
103 0         0 $backup = find_next_numbered ($file, $options);
104             }
105             else {
106 0         0 $backup = simple_backup ($file, $options);
107             }
108             }
109              
110              
111             sub backup_name
112             {
113 6     6 1 1774 my ($file, $options) = @_;
114              
115 6         6 my $backup_file;
116              
117 6 100       38 if (! -f $file) {
118 1         2 $backup_file = $file;
119             }
120             else {
121 5         9 my $version_control = get_version_control ($options);
122              
123 5 50 33     36 if (! $version_control ||
      33        
124             $version_control eq 'existing' ||
125             $version_control eq 'nil') {
126 0         0 $backup_file = default_backup
127             }
128 5 100 66     19 if ($version_control eq 'numbered' ||
    50 33        
129             $version_control eq 't') {
130 3         5 $backup_file = find_next_numbered ($file, $options);
131             }
132             elsif ($version_control eq 'simple' ||
133             $version_control eq 'never') {
134 2         4 $backup_file = simple_backup ($file, $options);
135             }
136             else {
137 0         0 croak __PACKAGE__, ": I don't know how to do the type of version control '$version_control' in your environment.\n";
138             }
139             }
140 6         10 return $backup_file;
141             }
142              
143             sub make_backup
144             {
145 3     3 1 1172 my ($file, $options) = @_;
146 3 50       30 if (! -f $file) {
147 0         0 croak "Asked to make a backup of a file '$file' which does not exist";
148             }
149 3         6 my $backup_file = backup_name ($file);
150 3 50       15 if (-f $backup_file) {
151 0 0       0 unlink $backup_file or croak "unlink $backup_file failed: $!";
152             }
153 3 50       78 rename $file, $backup_file or croak "rename $file, $backup_file failed: $!";
154 3         7 return $backup_file;
155             }
156              
157             1;
158