File Coverage

lib/PatchReader/FixPatchRoot.pm
Criterion Covered Total %
statement 40 68 58.8
branch 12 32 37.5
condition 2 6 33.3
subroutine 9 10 90.0
pod 0 7 0.0
total 63 123 51.2


line stmt bran cond sub pod time code
1             package PatchReader::FixPatchRoot;
2            
3 4     4   3865 use PatchReader::FilterPatch;
  4         9  
  4         104  
4 4     4   1086 use PatchReader::CVSClient;
  4         9  
  4         94  
5            
6 4     4   21 use strict;
  4         6  
  4         3117  
7            
8             @PatchReader::FixPatchRoot::ISA = qw(PatchReader::FilterPatch);
9            
10             sub new {
11 4     4 0 481 my $class = shift;
12 4   33     26 $class = ref($class) || $class;
13 4         25 my $this = $class->SUPER::new();
14 4         16 bless $this, $class;
15            
16 4         26 my %parsed = PatchReader::CVSClient::parse_cvsroot($_[0]);
17 4         37 $this->{REPOSITORY_ROOT} = $parsed{rootdir};
18 4 50       26 $this->{REPOSITORY_ROOT} .= "/" if substr($this->{REPOSITORY_ROOT}, -1) ne "/";
19            
20 4         17 return $this;
21             }
22            
23             sub diff_root {
24 0     0 0 0 my $this = shift;
25 0 0       0 if (@_) {
26 0         0 $this->{DIFF_ROOT} = $_[0];
27             } else {
28 0         0 return $this->{DIFF_ROOT};
29             }
30             }
31            
32             sub flush_delayed_commands {
33 6     6 0 11 my $this = shift;
34 6 50       21 return if ! $this->{DELAYED_COMMANDS};
35            
36 0         0 my $commands = $this->{DELAYED_COMMANDS};
37 0         0 delete $this->{DELAYED_COMMANDS};
38 0         0 $this->{FORCE_COMMANDS} = 1;
39 0         0 foreach my $command_arr (@{$commands}) {
  0         0  
40 0         0 my $command = $command_arr->[0];
41 0         0 my $arg = $command_arr->[1];
42 0 0       0 if ($command eq "start_file") {
    0          
    0          
43 0         0 $this->start_file($arg);
44             } elsif ($command eq "end_file") {
45 0         0 $this->end_file($arg);
46             } elsif ($command eq "section") {
47 0         0 $this->next_section($arg);
48             }
49             }
50             }
51            
52             sub end_patch {
53 3     3 0 6 my $this = shift;
54 3         8 $this->flush_delayed_commands();
55 3 50       34 $this->{TARGET}->end_patch(@_) if $this->{TARGET};
56             }
57            
58             sub start_file {
59 3     3 0 8 my $this = shift;
60 3         5 my ($file) = @_;
61             # If the file is new, it will not have a filename that fits the repository
62             # root and therefore needs to be fixed up to have the same root as everyone
63             # else. At the same time we need to fix DIFF_ROOT too.
64 3 50 33     50 if (exists($this->{DIFF_ROOT})) {
    50          
65             # XXX Return error if there are multiple roots in the patch by verifying
66             # that the DIFF_ROOT is not different from the calculated diff root on this
67             # filename
68            
69 0         0 $file->{filename} = $this->{DIFF_ROOT} . $file->{filename};
70            
71 0         0 $file->{canonical} = 1;
72             } elsif ($file->{rcs_filename} &&
73             substr($file->{rcs_filename}, 0, length($this->{REPOSITORY_ROOT})) eq
74             $this->{REPOSITORY_ROOT}) {
75             # Since we know the repository we can determine where the user was in the
76             # repository when they did the diff by chopping off the repository root
77             # from the rcs filename
78 3         11 $this->{DIFF_ROOT} = substr($file->{rcs_filename},
79             length($this->{REPOSITORY_ROOT}));
80 3         16 $this->{DIFF_ROOT} =~ s/,v$//;
81             # If the RCS file exists in the Attic then we need to correct for
82             # this, stripping off the '/Attic' suffix in order to reduce the name
83             # to just the CVS root.
84 3 100       17 if ($this->{DIFF_ROOT} =~ m/Attic/) {
85 1         4 $this->{DIFF_ROOT} = substr($this->{DIFF_ROOT}, 0, -6);
86             }
87             # XXX More error checking--that filename exists and that it is in fact
88             # part of the rcs filename
89 3         11 $this->{DIFF_ROOT} = substr($this->{DIFF_ROOT}, 0,
90             -length($file->{filename}));
91 3         15 $this->flush_delayed_commands();
92            
93 3         9 $file->{filename} = $this->{DIFF_ROOT} . $file->{filename};
94            
95 3         7 $file->{canonical} = 1;
96             } else {
97             # DANGER Will Robinson. The first file in the patch is new. We will try
98             # "delayed command mode"
99             #
100             # (if force commands is on we are already in delayed command mode, and sadly
101             # this means the entire patch was unintelligible to us, so we just output
102             # whatever the hell was in the patch)
103            
104 0 0       0 if (!$this->{FORCE_COMMANDS}) {
105 0         0 push @{$this->{DELAYED_COMMANDS}}, [ "start_file", { %{$file} } ];
  0         0  
  0         0  
106 0         0 return;
107             }
108             }
109 3 50       20 $this->{TARGET}->start_file($file) if $this->{TARGET};
110             }
111            
112             sub end_file {
113 3     3 0 5 my $this = shift;
114 3 50       13 if (exists($this->{DELAYED_COMMANDS})) {
115 0         0 push @{$this->{DELAYED_COMMANDS}}, [ "end_file", { %{$_[0]} } ];
  0         0  
  0         0  
116             } else {
117 3 50       38 $this->{TARGET}->end_file(@_) if $this->{TARGET};
118             }
119             }
120            
121             sub next_section {
122 3     3 0 6 my $this = shift;
123 3 50       12 if (exists($this->{DELAYED_COMMANDS})) {
124 0         0 push @{$this->{DELAYED_COMMANDS}}, [ "section", { %{$_[0]} } ];
  0         0  
  0         0  
125             } else {
126 3 50       22 $this->{TARGET}->next_section(@_) if $this->{TARGET};
127             }
128             }
129            
130             1