File Coverage

blib/lib/P4/C4/Ignore.pm
Criterion Covered Total %
statement 78 85 91.7
branch 18 28 64.2
condition 3 14 21.4
subroutine 13 14 92.8
pod 1 2 50.0
total 113 143 79.0


line stmt bran cond sub pod time code
1             # $Revision: 709 $$Date: 2005-05-03 17:32:07 -0400 (Tue, 03 May 2005) $$Author: wsnyder $
2             # Author: Wilson Snyder
3             ######################################################################
4             #
5             # Copyright 2002-2005 by Wilson Snyder. This program is free software;
6             # you can redistribute it and/or modify it under the terms of either the GNU
7             # General Public License or the Perl Artistic License.
8             #
9             # This program is distributed in the hope that it will be useful,
10             # but WITHOUT ANY WARRANTY; without even the implied warranty of
11             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12             # GNU General Public License for more details.
13             #
14             ######################################################################
15              
16             package P4::C4::Ignore;
17             require 5.006_001;
18              
19 1     1   29290 use strict;
  1         2  
  1         46  
20 1     1   5 use vars qw($VERSION $Debug);
  1         2  
  1         187  
21 1     1   7 use Carp;
  1         2  
  1         77  
22 1     1   6 use File::Spec;
  1         3  
  1         22  
23 1     1   1474 use File::Spec::Functions;
  1         1494  
  1         105  
24 1     1   6 use IO::File;
  1         2  
  1         371  
25 1     1   6 use Cwd qw(getcwd);
  1         3  
  1         2001  
26              
27             ######################################################################
28             #### Configuration Section
29              
30             our $VERSION = '2.041';
31              
32             #######################################################################
33             #######################################################################
34             #######################################################################
35              
36             sub new {
37 2 50   2 1 1938 @_ >= 1 or croak 'usage: P4::C4::Ignore->new ({options})';
38 2   50     8 my $class = shift || __PACKAGE__; # Class (Getopt Element)
39 2         14 my $self = {filename=>'.cvsignore',
40             _files=>{}, # Cache by filename of raw text ignores
41             _regexp=>{}, # Cache by filename of parsed ignores
42             @_,
43             };
44 2         6 bless $self, $class;
45 2         22 $self->_addIgnore ('GLOBAL',(
46             '*~', '#*', '.#*', ',*', '_$*', '*$',
47             '*.old', '*.bak', '*.BAK', '*.orig', '*.rej', '.del-*',
48             '*.a', '*.olb', '*.o', '*.obj', '*.so', '*.exe',
49             '*.Z', '*.elc', '*.ln',
50             'tags', 'TAGS',
51             '.make.state', '.nse_depinfo',
52             'core',
53             # Not in CVS
54             '.dependency-info',
55             # Our own temp files
56             '.c4cache', '.p4config',));
57            
58             # Read user's .cvsignore into global list
59 2 50       30 $self->_readIgnore("GLOBAL",catfile($ENV{HOME},".cvsignore")) if defined $ENV{HOME};
60              
61             # Read CVSIGNORE environment
62 2 100       16 $self->_addIgnore ("GLOBAL", (split /\s+/, $ENV{CVSIGNORE})) if defined $ENV{CVSIGNORE};
63              
64 2         33 return $self;
65             }
66              
67             #######################################################################
68             # User methods
69              
70             sub isIgnored {
71 9     9 0 621 my $self = shift;
72 9         44 my $filename = shift;
73              
74 9         271 $filename = File::Spec->rel2abs($filename);
75 9         65 my @dirlist = File::Spec->splitdir($filename);
76 9         32 while ($#dirlist > 0) {
77 15         24 $filename = pop @dirlist;
78 15 100       73 return 1 if _checkOneDir($self,catdir(@dirlist),$filename);
79             }
80 2         15 return 0;
81             }
82              
83             #######################################################################
84             # Checking function
85              
86             sub _checkOneDir {
87 15     15   23 my $self = shift;
88 15         18 my $dirname = shift;
89 15         19 my $filename = shift;
90              
91 15 100       47 if (!$self->{_regexp}{$dirname}) {
92 8         48 $self->_readIgnore($dirname, catfile($dirname,$self->{filename}));
93             }
94              
95 15         257 my $basename = (File::Spec->splitpath($filename))[2];
96             #print "CK1 $dirname $basename\n";
97 15         29 foreach my $re (@{$self->{_regexp}{$dirname}}) {
  15         42  
98             #print "CK1b $dirname $basename $re\n";
99 259 100       1490 return 1 if ($basename =~ /$re/);
100             }
101 8         44 return 0;
102             }
103              
104             #######################################################################
105             # Reading functions
106              
107             sub _readIgnore {
108 10     10   18 my $self = shift;
109 10         11 my $dirname = shift;
110 10         13 my $filename = shift;
111              
112 10 50 66     44 return if $self->{_files}{$dirname} && $dirname ne 'GLOBAL'; # Cached
113 10         74 my $fh = IO::File->new($filename,"r");
114 10 100       1012 $self->_addIgnore ($dirname, @{$self->{_files}{GLOBAL}}) if $dirname ne 'GLOBAL';
  8         32  
115 10 100       40 if ($fh) {
116 2         11 local $/; undef $/; my $wholefile = <$fh>;
  2         5  
  2         111  
117 2         14 $self->_addIgnore ($dirname, (split /\s+/, $wholefile));
118             }
119             }
120              
121             sub _addIgnore {
122 13     13   22 my $self = shift;
123 13         19 my $dirname = shift;
124 13         26 foreach my $re (@_) {
125 199 50       356 print " Ignore in $dirname: $re\n" if $Debug;
126 199 100       787 if ($re eq "!") {
127 1         6 $self->{_files}{$dirname} = [];
128             } else {
129 198         196 push @{$self->{_files}{$dirname}}, $re;
  198         564  
130             }
131             }
132              
133             # Convert patterns to regexp, for faster parsing
134 229         343 my @relist = map { my $regexp = quotemeta $_;
  13         33  
135 229         464 $regexp =~ s%\\\*%.*%g;
136 229         276 $regexp =~ s%\\\?%.%g;
137 229         388 $regexp = "^".$regexp."\$";
138 229         3150 qr/$regexp/;
139 13         24 } @{$self->{_files}{$dirname}};
140 13         96 $self->{_regexp}{$dirname} = \@relist;
141             }
142              
143             ######################################################################
144             ######################################################################
145             ######################################################################
146             ######################################################################
147             # Overrides
148              
149             package P4::C4;
150 1     1   10 use strict;
  1         2  
  1         249  
151              
152             sub ignoredFiles {
153 0     0     my $self = shift;
154              
155 0 0         $self->{_ignore} = new P4::C4::Ignore() if !$self->{_ignore};
156 0           foreach my $fref (values %{$self->{_files}}) {
  0            
157 0 0 0       if ($fref->{clientMtime}
      0        
      0        
158             && !($fref->{headAction} && $fref->{headAction} ne 'delete')
159             && !$fref->{ignore}) {
160             #use Data::Dumper; print "check",Dumper($fref) if $fref->{filename} =~ /c4cache/;
161 0           $fref->{ignore} = $self->{_ignore}->isIgnored($fref->{filename});
162 0 0         $fref->{unknown} = 1 if !$fref->{ignore};
163             }
164             }
165             }
166              
167             ######################################################################
168             ### Package return
169             1;
170             __END__