File Coverage

blib/lib/SVN/Notify/Mirror.pm
Criterion Covered Total %
statement 19 74 25.6
branch 0 26 0.0
condition 1 8 12.5
subroutine 5 8 62.5
pod 2 2 100.0
total 27 118 22.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package SVN::Notify::Mirror;
4 1     1   620 use base qw/SVN::Notify/;
  1         3  
  1         1190  
5 1     1   29453 use strict;
  1         3  
  1         33  
6              
7 1     1   5 use vars qw ($VERSION);
  1         2  
  1         233  
8             $VERSION = '0.040';
9             $VERSION = eval $VERSION;
10              
11             __PACKAGE__->register_attributes(
12             'ssh_host' => 'ssh-host=s',
13             'ssh_user' => 'ssh-user:s',
14             'ssh_tunnel' => 'ssh-tunnel:s',
15             'ssh_identity' => 'ssh-identity:s',
16             'svn_binary' => 'svn-binary:s',
17             'tag_regex' => 'tag-regex:s',
18             'minimal' => 'minimal',
19             );
20              
21             sub prepare {
22 0     0 1 0 my $self = shift;
23 0         0 $self->prepare_recipients;
24 0         0 $self->prepare_files;
25             }
26              
27             sub execute {
28 0     0 1 0 my ($self) = @_;
29 0 0       0 return unless defined $self->to;
30 0 0 0     0 $self->svn_binary( $ENV{SVN} || SVN::Notify->find_exe('svn') )
31             unless $self->svn_binary;
32              
33 0         0 foreach my $to ( $self->to ) {
34 0         0 my $command = 'update';
35 0         0 my @args = (
36             -r => $self->revision,
37             );
38              
39             # need to swap function calls for backwards compatibility for now
40 0 0 0     0 if ( defined $self->ssh_host
41             and not $self->isa('SVN::Notify::Mirror::SSH') )
42             {
43 1     1   5 no warnings 'redefine';
  1         2  
  1         828  
44 0         0 warn "Deprecated - please use SVN::Notify::Mirror::SSH directly";
45 0         0 require SVN::Notify::Mirror::SSH;
46 0         0 *_cd_run = \&SVN::Notify::Mirror::SSH::_cd_run;
47             }
48              
49             # deal with the possible switch case
50 0 0       0 if ( defined $self->tag_regex ) {
51 0         0 $DB::single = 1;
52 0         0 $command = 'switch';
53 0         0 my $regex = $self->tag_regex;
54 0         0 my ($tag) = grep /$regex/, @{$self->{'files'}->{'A'}};
  0         0  
55 0         0 $tag =~ s/^.+\/tags\/(.+)/$1/;
56 0 0       0 return unless $tag;
57 0         0 my @message = $self->_cd_run(
58             $to,
59             $self->svn_binary,
60             'info',
61             );
62 0         0 my $URL = (split ": ", $message[1], 2)[1];
63 0 0       0 if ( $URL =~ m/^(.+\/tags\/).+$/m ) {
64 0         0 my $url = $1;
65 0         0 $tag = $url.$tag;
66             }
67 0         0 push @args, $tag;
68             }
69              
70 0 0       0 if ( $self->minimal ) {
71             # perform minimal update only
72 0         0 my @paths;
73 0         0 my $prefix = $self->{'handle_path'}; # simple case
74 0 0       0 unless ( $prefix ) {
75             # hard case
76 0         0 $DB::single = 1;
77 0         0 my @message = $self->_cd_run($to, $self->svn_binary, 'info');
78 0         0 my $URL = (split ": ", $message[1], 2)[1];
79 0         0 my $ROOT = (split ": ", $message[2], 2)[1];
80 0 0       0 $ROOT .= '/' unless $ROOT =~ m:/$:;
81 0         0 ($prefix = $URL) =~ s/$ROOT//;
82             }
83              
84 0         0 foreach my $files ( values %{ $self->files } ) {
  0         0  
85 0 0       0 push @paths, map { s/$prefix// && $_ } @{ $files };
  0         0  
  0         0  
86             }
87 0         0 $to .= '/'. _shortest_path(@paths);
88             }
89              
90 0         0 print join("\n",
91             $self->_cd_run(
92             $to,
93             $self->svn_binary,
94             $command,
95             @args,
96             )
97             );
98             }
99             }
100              
101             sub _cd_run {
102 0     0   0 my ($self, $path, $binary, $command, @args) = @_;
103 0         0 my @message;
104 0         0 my $cmd ="$binary $command " . join(" ",@args);
105 0 0       0 $self->_dbpnt("running 'cd $path; $cmd'") if $self->{verbose} > 1;
106              
107 0 0       0 chdir ($path) or die "Couldn't CD to $path: $!";
108              
109 0 0       0 open my $RUN, '-|', $cmd
110             or die "Running [$cmd] failed with $?: $!";
111 0         0 while (<$RUN>) {
112 0         0 chomp;
113 0         0 push @message, $_;
114             }
115 0         0 close $RUN;
116 0         0 return (@message);
117             }
118              
119             sub _shortest_path {
120 12     12   1609 my @dirs = grep { /\S/ } @_;
  28         93  
121              
122             # Set shortest_path to first dir
123 12   50     31 my $shortest_path = shift(@dirs) || '';
124              
125             # Find common prefix between each dir and shortest_path
126 12         24 foreach my $dir (@dirs) {
127 12         71 chop $shortest_path while (index($dir, $shortest_path) != 0);
128             }
129              
130             # Remove final / and anything after
131 12         49 $shortest_path =~ s{/[^/]*?$}{};
132              
133 12         47 return $shortest_path;
134             }
135              
136             1;
137              
138             __END__