File Coverage

blib/lib/MMM/Sync.pm
Criterion Covered Total %
statement 56 76 73.6
branch 7 26 26.9
condition n/a
subroutine 12 17 70.5
pod 4 4 100.0
total 79 123 64.2


line stmt bran cond sub pod time code
1             package MMM::Sync;
2              
3 5     5   1688 use strict;
  5         11  
  5         179  
4 5     5   27 use warnings;
  5         7  
  5         492  
5 5     5   5869 use IPC::Open3;
  5         24552  
  5         372  
6 5     5   2495 use IO::Select;
  5         4611  
  5         239  
7              
8 5     5   2090 use URI;
  5         9603  
  5         4196  
9              
10             =head1 NAME
11              
12             MMM::Sync - A module to run application
13              
14             =head1 FUNCTIONS
15              
16             =head2 new($source, $dest, %options)
17              
18             Create a new MMM::Sync object where $source is the url to sync,
19             $dest the local directory, and %options options to pass to sync tool.
20              
21             =cut
22              
23             sub new {
24 6     6 1 2555 my ($class, $source, $dest, %options) = @_;
25 6 50       28 $source =~ m:/$: or $source .= '/';
26 6 50       19 $dest =~ m:/$: or $dest .= '/';
27              
28 6         34 my $sync = {
29             source => $source,
30             dest => $dest,
31             options => { %options },
32             };
33            
34 6 50       30 my $uri = URI->new($source) or return;
35 6         26796 my $type = ucfirst(lc($uri->scheme()));
36 6     2   757 eval "use MMM::Sync::$type";
  2     1   473  
  1     1   1  
  1     1   16  
  1     1   8  
  1         2  
  1         15  
  1         6  
  1         2  
  1         12  
  1         6  
  1         2  
  1         28  
  1         6  
  1         1  
  1         11  
37 6         89 bless($sync, "MMM::Sync::$type");
38             }
39              
40             =head2 get_output
41              
42             Return the log resulting of sync()
43              
44             =cut
45              
46             sub get_output {
47 0     0 1 0 my ($self) = @_;
48 0         0 $self->{output}
49             }
50              
51             =head2 reset_output
52              
53             Reset internal log
54              
55             =cut
56              
57             sub reset_output {
58 0     0 1 0 my ($self) = @_;
59 0         0 $self->{output} = undef;
60             }
61              
62             =head2 buildcmd
63              
64             Return the command to run to sync the tree
65              
66             =head2 sync
67              
68             Run the synchronzation process.
69             Return 0 on success, 1 when retry is suggest, 2 for unccorectable error.
70              
71             =cut
72              
73             sub sync {
74 2     2 1 9 my ($self) = @_;
75              
76 2 50       11 my @command = $self->buildcmd() or return 2;
77 2         2 my $pid;
78 2 0   0   9 my $call_exit = sub { kill(15, $pid) if ($pid); };
  0         0  
79 2         42 local $SIG{'TERM'} = $call_exit;
80 2         22 local $SIG{'KILL'} = $call_exit;
81 2         22 local $SIG{'PIPE'} = $call_exit;
82 2 50       11 if ( $pid = open3( my $in, my $out, my $err, @command ) ) {
83 2         7761 close($in);
84 2         53 my $ios = IO::Select->new( $out, $err );
85 2         190 while ( my @handle = $ios->can_read() ) {
86 2         492 foreach my $h (@handle) {
87 2         36 my $l = <$h>;
88 2 50       21 if ($l) {
89 0         0 chomp($l);
90 0         0 my $err_src = undef;
91 0 0       0 if ($h eq $out) { $err_src = 'STDOUT'; }
  0 0       0  
92 0         0 elsif ($h eq $err) { $err_src = 'STDERR'; }
93 0         0 my $aline = $self->_analyze_output($err_src, $l);
94 0 0       0 push(@{ $self->{output} }, $aline) if ($aline);
  0         0  
95             }
96 2 50       33 $ios->remove($h) if ( eof($h) );
97             }
98             }
99              
100 2         131 waitpid( $pid, 0 );
101 2         17 my $exitstatus = $? >> 8;
102 2         17 return $self->_exitcode($exitstatus);
103             } else {
104 0         0 return ( 2 );
105             }
106             }
107              
108             sub _analyze_output {
109 0     0   0 my ($self, $src, $line) = @_;
110 0 0       0 if ($src eq 'STDERR') {
111 0         0 return $line;
112             } else {
113 0         0 return;
114             }
115             }
116              
117             sub _exitcode {
118 0     0   0 my ($self, $exitcode) = @_;
119 0 0       0 return ($exitcode == 0 ? 0 : 1);
120             }
121              
122             =head2 AUTHOR
123              
124             Olivier Thauvin
125              
126             =cut
127              
128             1;