1
package File::LocalizeNewlines;
7
File::LocalizeNewlines - Localize the newlines for one or more files
11
For people that routinely work with a mixture of different platforms
12
that have conflicting newline formats (mainly *NIX and Win32) there
13
are a number of different situations that can result in files having
14
their newlines get corrupted.
16
File::LocalizeNewlines provides a mechanism for one off or bulk
17
detection and conversion of these files to the newline style for the
20
The module implements the conversion using a standard "universal line
21
seperator" regex, which ensures that files with any of the different
22
newlines, plus a couple of common "broken" newlines, including
23
multiple different types mixed in the same file, are all converted to
24
the local platform's newline style.
32
use Class::Default ();
33
use File::Find::Rule ();
36
use Params::Util '_INSTANCE';
38
use vars qw{$VERSION @ISA};
41
@ISA = 'Class::Default';
48
#####################################################################
49
# Constructor and Accessors
53
=head2 new param => value, ...
55
The C<new> constructor creates a new conversion object.
57
By default, the conversion object will process all files and convert
58
them to the local platform's newline format.
60
Takes some optional parameters
64
=item filter =E<gt> File::Find::Rule
66
The C<filter> param allows you to provide an instantiate
67
L<File::Find::Rule> object, that will used to determine the list of
68
files to check or process.
70
=item newline =E<gt> $newline
72
The C<newline> option allows you to provide an alternative newline
73
format to the local one. The newline format should be provided as a
76
For example, to force Win32 newlines, you would use
78
my $Object = File::LocalizeNewlines->new( newline => "\015\012" );
80
=item verbose =E<gt> 1
82
The C<verbose> option will cause the C<File::LocalizeNewlines> object to
83
print status information to C<STDOUT> as it runs.
87
Returns a new C<File::LocalizeNewlines> object.
92
my $class = ref $_[0] ? ref shift : shift;
95
# Create the basic object
96
my $self = bless { }, $class;
98
# Check the file filter
99
if ( _INSTANCE($args{filter}, 'File::Find::Rule') ) {
100
$self->{Find} = $args{filter};
101
$self->{Find}->file->relative;
104
# Allow for a custom platform
105
$self->{newline} = $args{newline} if $args{newline};
107
# Check the verbose mode
108
if ( _CAN($args{verbose}, 'print') ) {
109
$self->{verbose} = $args{verbose};
110
} elsif ( $args{verbose} ) {
111
$self->{verbose} = 1;
121
The C<Find> accessor returns the L<File::Find::Rule> object that will be
122
used for the file search.
127
my $self = $_[0]->_self;
128
$self->{Find} or File::Find::Rule->file->relative;
135
The C<newline> accessor returns the newline format that will be used in
136
the localisation process.
141
$_[0]->_self->{newline} or "\n";
148
#####################################################################
153
=head2 localized $file
155
The C<localized> method takes an argument of a single file name or
156
file handle and tests it to see it is localized correctly.
158
Returns true if localized correctly, false if not, or C<undef> on error.
163
my $self = shift->_self;
164
my $file = (defined $_[0] and ref $_[0]) ? shift
165
: (defined $_[0] and -f $_[0]) ? shift
167
my $newline = $self->newline;
168
my $content = File::Slurp::read_file( $file );
170
# Create the localized version of the file
171
my $localized = $content;
172
$localized =~ s/(?:\015{1,2}\012|\015|\012)/$newline/sg;
174
$localized eq $content;
181
The C<find> method takes the path for a dir (or file) and returns a list
182
of relative files names for all of the files that do B<not> have their
183
newlines correctly localized.
185
Returns a list of file names, or the null list if there are no files,
186
or if an incorrect path was provided.
191
my $self = shift->_self;
192
my $path = _DIRECTORY(shift) or return ();
194
# Find all the files to test
195
my @files = $self->Find->in( $path );
198
File::Spec->catfile( $path, $_ )
207
=head2 localize $file | $dir
209
The C<localize> method takes a file, file handle or directory as argument
210
and localizes the newlines of the file, or all files within the directory
211
(that match the filter if one was provided).
213
Returns the number of files that were localized, zero if no files needed to
214
be localized, or C<undef> on error.
219
my $self = shift->_self;
220
my $path = (defined $_[0] and ref $_[0]) ? shift
221
: (defined $_[0] and -e $_[0]) ? shift
224
# Switch on file or dir
225
(-f $path or ref $_[0])
226
? $self->_localize_file( $path )
227
: $self->_localize_dir( $path );
231
my $self = shift->_self;
232
my $path = _DIRECTORY(shift) or return undef;
234
# Find the files to localise
235
my @files = $self->Find->in( $path );
239
my $newline = $self->newline;
241
my $file = File::Spec->catfile( $path, $_ );
242
my $content = File::Slurp::read_file( $file );
243
my $localized = $content;
244
$localized =~ s/(?:\015{1,2}\012|\015|\012)/$newline/sg;
245
next if $localized eq $content;
246
File::Slurp::write_file( $file, $localized ) or return undef;
247
$self->_message( "Localized $file\n" );
255
my $self = shift->_self;
256
my $file = (defined $_[0] and ref $_[0]) ? shift
257
: (defined $_[0] and -f $_[0]) ? shift
260
# Does the file need to be localised
261
my $newline = $self->newline;
262
my $content = File::Slurp::read_file( $file );
263
my $localized = $content;
264
$localized =~ s/(?:\015{1,2}\012|\015|\012)/$newline/sg;
265
return 0 if $content eq $localized;
267
# Save the localised version
268
File::Slurp::write_file( $file, $content ) or return undef;
269
$self->_message( "Localized $file\n" ) unless ref $file;
276
return 1 unless defined $self->{verbose};
278
$message .= "\n" unless $message =~ /\n$/;
279
if ( _CAN( $self->{verbose}, 'print' ) ) {
280
$self->{verbose}->print( $message );
282
print STDOUT $message;
287
(_INSTANCE($_[0], 'UNIVERSAL') and $_[0]->can($_[1])) ? shift : undef;
291
(defined $_[0] and -d $_[0]) ? shift : undef;
300
Bugs should always be submitted via the CPAN bug tracker
302
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=File-LocalizeNewlines>
304
For other issues, contact the maintainer.
308
Adam Kennedy E<lt>adamk@cpan.orgE<gt>
310
=head1 ACKNOWLEDGEMENTS
312
Thank you to Phase N (L<http://phase-n.com/>) for permitting
313
the open sourcing and release of this distribution.
315
L<FileHandle> support added by David Dick E<lt>ddick@cpan.orgE<gt>
319
Copyright 2005 - 2008 Adam Kennedy.
321
This program is free software; you can redistribute
322
it and/or modify it under the same terms as Perl itself.
324
The full text of the license can be found in the
325
LICENSE file included with this module.