File Coverage

blib/lib/IO/BlockSync/App.pm
Criterion Covered Total %
statement 29 53 54.7
branch 0 14 0.0
condition 0 6 0.0
subroutine 10 13 76.9
pod 1 1 100.0
total 40 87 45.9


line stmt bran cond sub pod time code
1             package IO::BlockSync::App;
2              
3             # Basic
4 1     1   1033 use 5.010;
  1         4  
5 1     1   4 use strict;
  1         3  
  1         23  
6 1     1   4 use warnings FATAL => 'all';
  1         4  
  1         57  
7              
8             # Build in
9 1     1   506 use English qw( -no_match_vars );
  1         2909  
  1         5  
10 1     1   340 use Scalar::Util qw(blessed);
  1         1  
  1         60  
11              
12             # CPAN
13 1     1   6 use Moo;
  1         2  
  1         4  
14 1     1   722 use MooX::Options;
  1         3188  
  1         4  
15 1     1   73161 use Log::Log4perl;
  1         2  
  1         8  
16 1     1   54 use Log::Log4perl::Level;
  1         2  
  1         6  
17              
18             # This bundle
19 1     1   121 use IO::BlockSync;
  1         2  
  1         536  
20              
21             ################################################################
22              
23             =head1 NAME
24              
25             IO::BlockSync::App (Perl module) or blocksync (command)
26              
27             =head1 VERSION
28              
29             Version 0.001
30              
31             =cut
32              
33             our $VERSION = '0.001';
34              
35             ################################################################
36              
37             =head1 SYNOPSIS
38              
39             BlockSync can some of the same stuff that bigsync (by Egor Egorov) can
40             - it's just written in perl.
41              
42             BlockSync copies data from source file to destination file (can be a block
43             device) and calculates checksum on each block it copies.
44             On all runs after the first only the changed blocks will be copied.
45              
46             blocksync -S -s /source/path -d /destination/path
47              
48             =cut
49              
50             ################################################################
51              
52             =head1 COMMAND LINE OPTIONS
53              
54             =cut
55              
56             ################################################################
57              
58             =head2 -V --version
59              
60             Print version and exit
61              
62             =cut
63              
64             option 'version' => (
65             is => 'ro',
66             short => 'V',
67             doc => 'print version and exit',
68             );
69              
70             ################################################################
71              
72             =head2 -v --verbose
73              
74             Print version and exit
75              
76             =cut
77              
78             option 'verbose' => (
79             is => 'ro',
80             short => 'v',
81             repeatable => 1,
82             doc => 'be verbose',
83             );
84              
85             ################################################################
86              
87             =head2 -s --src
88              
89             Path to source file.
90              
91             mandatory - string (containing path)
92              
93             =cut
94              
95             option 'src' => (
96             is => 'ro',
97             format => 's',
98             short => 's',
99             doc => 'source file path',
100             );
101              
102             ################################################################
103              
104             =head2 -d --dst
105              
106             Destination file. If not set, then only checksum file will be updated.
107              
108             optional - string (containing path)
109              
110             =cut
111              
112             option 'dst' => (
113             is => 'ro',
114             format => 's',
115             short => 'd',
116             doc => 'destination file path',
117             );
118              
119             ################################################################
120              
121             =head2 -c --chk
122              
123             Path to checksum file.
124              
125             mandatory - string (containing path)
126              
127             =cut
128              
129             option 'chk' => (
130             is => 'rwp',
131             format => 's',
132             short => 'c',
133             doc => 'checksum file path',
134             );
135              
136             ################################################################
137              
138             =head2 -b --bs
139              
140             Block size to use in bytes.
141              
142             optional - integer - defaults to 1_048_576 B (1 MB)
143              
144             =cut
145              
146             option 'bs' => (
147             is => 'ro',
148             format => 'i',
149             short => 'b',
150             default => 1_048_576,
151             doc => 'block size',
152             );
153              
154             ################################################################
155              
156             =head2 -S --sparse
157              
158             Seek in dst file, instead of writing blocks only containing \0
159              
160             optional - boolean - defaults to 0 (false)
161              
162             =cut
163              
164             option 'sparse' => (
165             is => 'ro',
166             short => 'S',
167             default => 0,
168             ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
169             doc => 'seek in dst file, instead of writing blocks only containing \0',
170             ## use critic
171             );
172              
173             ################################################################
174              
175             =head2 -t --truncate
176              
177             Truncate the destination file to same size as source file. Does not work on block devices. Will only be tried if C<data> has default value (whole file is copied).
178              
179             optional - boolean - defaults to 0 (false)
180              
181             =cut
182              
183             option 'truncate' => (
184             is => 'ro',
185             short => 't',
186             default => 0,
187             doc => 'truncate destination file',
188             );
189              
190             ################################################################
191              
192             =head1 METHODS
193              
194             =cut
195              
196             ################################################################
197              
198             =head2 run
199              
200             C<bin/blocksync> calls C<IO::BlockSync::App::run> to start the program.
201              
202             If you just run C<blocksync> command then ignore this method.
203              
204             =cut
205              
206             sub run {
207 0     0 1   my ($self) = @_;
208              
209             # Create object with data from command line and run this function again
210 0 0         if ( !blessed $self) {
211 0           return $self->new_with_options->run;
212             }
213              
214 0 0         if ( $self->version ) {
215 0           say "blocksync version $VERSION";
216 0           exit;
217             }
218              
219 0 0         if ( !$self->src ) {
220 0           $self->options_usage( 1, '<src> must be set' );
221             }
222              
223 0 0 0       if ( $self->dst && !$self->chk ) {
    0 0        
224 0           $self->_set_chk( $self->dst . '.chk' );
225             }
226             elsif ( !$self->dst && !$self->chk ) {
227 0           $self->options_usage( 1, 'at least one of <chk> or <dst> must be set' );
228             }
229              
230 0           my $status;
231 0 0         if ( $self->verbose ) {
232             $status = sub {
233 0     0     printf
234             "Copying block=<%s> type=<%s> start=<%s> end=<%s> size=<%s>\n",
235             @_, $_[3] - $_[2];
236 0           };
237 0 0         if ( $self->verbose > 1 ) {
238 0           Log::Log4perl->init( \<<"EOF");
239             log4perl.logger = DEBUG, Screen
240             log4perl.appender.Screen = Log::Log4perl::Appender::Screen
241             log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
242             log4perl.appender.Screen.layout.ConversionPattern = %d %p %M %m%n
243             EOF
244             }
245             }
246             else {
247             $status = sub {
248 0     0     $OUTPUT_AUTOFLUSH++;
249 0           print( "\rCopying block " . shift );
250             }
251 0           }
252              
253 0           BlockSync( %{$self}, 'status' => $status, );
  0            
254              
255 0           say '';
256              
257             # Make Perl::Critic happy
258 0           return;
259             }
260              
261             ################################################################
262              
263             =head1 LICENSE AND COPYRIGHT
264              
265             This software is copyright (c) 2019 by Thor Dreier-Hansen.
266              
267             This is free software; you can redistribute it and/or modify it under
268             the same terms as the Perl 5 programming language system itself.
269              
270             Terms of the Perl programming language system itself:
271              
272             =over
273              
274             =item * the
275             L<GNU General Public License|http://dev.perl.org/licenses/gpl1.html>
276             as published by the Free Software Foundation; either
277             L<version 1|http://dev.perl.org/licenses/gpl1.html>,
278             or (at your option) any later version, or
279              
280             =item * the L<"Artistic License"|http://dev.perl.org/licenses/artistic.html>
281              
282             =back
283              
284             See L<http://dev.perl.org/licenses/> for more information.
285              
286             =cut
287              
288             1; # End of IO::BlockSync::App