1package File::Find::Rule::VCS;
2
3=pod
4
5=head1 NAME
6
7File::Find::Rule::VCS - Exclude files/directories for Version Control Systems
8
9=head1 SYNOPSIS
10
11  use File::Find::Rule      ();
12  use File::Find::Rule::VCS ();
13
14  # Find all files smaller than 10k, ignoring version control files
15  my @files = File::Find::Rule->ignore_vcs
16                              ->file
17                              ->size('<10Ki')
18                              ->in( $dir );
19
20=head1 DESCRIPTION
21
22Many tools need to be equally useful both on ordinary files, and on code
23that has been checked out from revision control systems.
24
25B<File::Find::Rule::VCS> provides quick and convenient methods to
26exclude the version control directories of several major Version
27Control Systems (currently CVS, subversion, and Bazaar).
28
29B<File::Find::Rule::VCS> implements methods to ignore the following:
30
31=over 4
32
33=item B<CVS>
34
35=item B<Subversion>
36
37=item B<Bazaar>
38
39=back
40
41In addition, the following version control systems do not create
42directories in the checkout and do not require the use of any
43ignore methods
44
45=over 4
46
47=item B<SVK>
48
49=item B<Git>
50
51=back
52
53=head1 METHODS
54
55=cut
56
57use 5.00503;
58use strict;
59use Carp                  ();
60use Text::Glob       0.08 ();
61use File::Find::Rule 0.20 ();
62
63use vars qw{$VERSION @ISA @EXPORT};
64BEGIN {
65	$VERSION = '1.08';
66	@ISA     = 'File::Find::Rule';
67	@EXPORT  = @File::Find::Rule::EXPORT;
68}
69
70use constant FFR => 'File::Find::Rule';
71
72# In some Windows SVN implementations, it uses _svn instead of
73# .svn, so use both on Win32.
74my @svn = ($^O eq 'MSWin32') ? ('.svn', '_svn') : ('.svn');
75
76
77
78
79
80#####################################################################
81# File::Find::Rule Method Addition
82
83=pod
84
85=head2 ignore_vcs
86
87  # Ignore all common version control systems
88  $find->ignore_vcs;
89
90  # Ignore a specific named version control systems
91  $find->ignore_vcs($name);
92
93  # Ignore nothing (silent pass-through)
94  $find->ignore_vcs('');
95
96The C<ignore_vcs> method excludes the files for a named Version Control
97System from your L<File::Find::Rule> search.
98
99If passed, the name of the version control system is case in-sensitive.
100Names currently supported are 'cvs', 'svn', 'subversion', 'bzr', and
101'bazaar'.
102
103As a convenience for high-level APIs, if the VCS name is the defined
104null string B<''> then the call will be treated as a nullop.
105
106If no params at all are passed, this method will ignore all supported
107version control systems. If ignoring every version control system,
108please note that any legitimate directories called "CVS" or files
109starting with .# will be ignored, which is not always desirable.
110
111In widely-distributed code, you instead should try to detect the specific
112version control system used and call ignore_vcs with the specific name.
113
114Passing C<undef>, or an unsupported name, will throw an exception.
115
116=cut
117
118sub File::Find::Rule::ignore_vcs {
119	my $find = $_[0]->_force_object;
120
121	# Handle special cases
122	if( 1 == scalar( @_ ) ) {
123		# Logically combine all the ignores. This will be much
124		# faster than just calling them all one after the other.
125		return $find->or(
126			FFR->name(@svn, '.bzr', '.git', '.hg', 'CVS', 'RCS')
127			    ->directory->prune->discard,
128			FFR->name(qr/^\.\#/, qr/,v$/)->file->discard,
129			FFR->new,
130			);
131	}
132	unless ( defined $_[1] ) {
133		Carp::croak("->ignore_vcs: No version control system name provided");
134	}
135
136        # As a convenience for higher-level APIs
137        # we treat a defined null string as a nullop
138	my $vcs = lc $_[1];
139        return $find if $vcs eq '';
140
141	# Hand off to the rules for each VCS
142	return $find->ignore_cvs if $vcs eq 'cvs';
143	return $find->ignore_rcs if $vcs eq 'rcs';
144	return $find->ignore_svn if $vcs eq 'svn';
145	return $find->ignore_svn if $vcs eq 'subversion';
146	return $find->ignore_bzr if $vcs eq 'bzr';
147	return $find->ignore_bzr if $vcs eq 'bazaar';
148	return $find->ignore_git if $vcs eq 'git';
149	return $find->ignore_hg  if $vcs eq 'hg';
150	return $find->ignore_hg  if $vcs eq 'mercurial';
151	Carp::croak("->ignore_vcs: '$vcs' is not supported");
152}
153
154=pod
155
156=head2 ignore_cvs
157
158The C<ignore_cvs> method excluding all CVS directories from your
159L<File::Find::Rule> search.
160
161It will also exclude all the files left around by CVS after an
162automated merge that start with C<'.#'> (dot-hash).
163
164=cut
165
166sub File::Find::Rule::ignore_cvs {
167	my $find = $_[0]->_force_object;
168	return $find->or(
169		FFR->name('CVS')->directory->prune->discard,
170		FFR->name(qr/^\.\#/)->file->discard,
171		FFR->new,
172		);
173}
174
175=pod
176
177=head2 ignore_rcs
178
179The C<ignore_rcs> method excluding all RCS directories from your
180L<File::Find::Rule> search.
181
182It will also exclude all the files used by RCS to store the revisions
183(end with C<',v'>).
184
185=cut
186
187sub File::Find::Rule::ignore_rcs {
188	my $find = $_[0]->_force_object;
189	return $find->or(
190		FFR->name('RCS')->directory->prune->discard,
191		FFR->name(qr/,v$/)->file->discard,
192		FFR->new,
193		);
194}
195
196=pod
197
198=head2 ignore_svn
199
200The C<ignore_svn> method excluding all Subversion (C<.svn>) directories
201from your L<File::Find::Rule> search.
202
203=cut
204
205sub File::Find::Rule::ignore_svn {
206	my $find = $_[0]->_force_object;
207	return $find->or(
208		FFR->name(@svn)->directory->prune->discard,
209		FFR->new,
210		);
211}
212
213=pod
214
215=head2 ignore_bzr
216
217The C<ignore_bzr> method excluding all Bazaar (C<.bzr>) directories
218from your L<File::Find::Rule> search.
219
220=cut
221
222sub File::Find::Rule::ignore_bzr {
223	my $find = $_[0]->_force_object;
224	return $find->or(
225		FFR->name('.bzr')->directory->prune->discard,
226		FFR->new,
227		);
228}
229
230=pod
231
232=head2 ignore_git
233
234The C<ignore_git> method excluding all Git (C<.git>) directories
235from your L<File::Find::Rule> search.
236
237=cut
238
239sub File::Find::Rule::ignore_git {
240	my $find = $_[0]->_force_object;
241	return $find->or(
242		FFR->name('.git')->directory->prune->discard,
243		FFR->new,
244		);
245}
246
247=pod
248
249=head2 ignore_hg
250
251The C<ignore_hg> method excluding all Mercurial/Hg (C<.hg>) directories
252from your L<File::Find::Rule> search.
253
254=cut
255
256sub File::Find::Rule::ignore_hg {
257	my $find = $_[0]->_force_object;
258	return $find->or(
259		FFR->name('.hg')->directory->prune->discard,
260		FFR->new,
261		);
262}
263
2641;
265
266=pod
267
268=head1 TO DO
269
270- Add support for other version control systems.
271
272- Add other useful VCS-related methods
273
274=head1 SUPPORT
275
276Bugs should always be submitted via the CPAN bug tracker
277
278L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=File-Find-Rule-VCS>
279
280For other issues, contact the maintainer
281
282=head1 AUTHOR
283
284Adam Kennedy E<lt>adamk@cpan.orgE<gt>
285
286=head1 SEE ALSO
287
288L<http://ali.as/>, L<File::Find::Rule>
289
290=head1 COPYRIGHT
291
292Copyright 2005 - 2010 Adam Kennedy.
293
294This program is free software; you can redistribute
295it and/or modify it under the same terms as Perl itself.
296
297The full text of the license can be found in the
298LICENSE file included with this module.
299
300=cut
301