NAME
File::DirCompare - Perl module to compare two directories using callbacks.
SYNOPSIS
use
File::DirCompare;
# Simple diff -r --brief replacement
use
File::Basename;
File::DirCompare->compare(
$dir1
,
$dir2
,
sub
{
my
(
$a
,
$b
) =
@_
;
if
(!
$b
) {
printf
"Only in %s: %s\n"
, dirname(
$a
), basename(
$a
);
}
elsif
(!
$a
) {
printf
"Only in %s: %s\n"
, dirname(
$b
), basename(
$b
);
}
else
{
"Files $a and $b differ\n"
;
}
});
# Version-control like Deleted/Added/Modified listing
my
(
@listing
,
@modified
);
# use closure to collect results
File::DirCompare->compare(
'old_tree'
,
'new_tree'
,
sub
{
my
(
$a
,
$b
) =
@_
;
if
(!
$b
) {
push
@listing
,
"D $a"
;
}
elsif
(!
$a
) {
push
@listing
,
"A $b"
;
}
else
{
if
(-f
$a
&& -f
$b
) {
push
@listing
,
"M $b"
;
push
@modified
,
$b
;
}
else
{
# One file, one directory - treat as delete + add
push
@listing
,
"D $a"
;
push
@listing
,
"A $b"
;
}
}
});
DESCRIPTION
File::DirCompare is a perl module to compare two directories using a callback, invoked for all files that are 'different' between the two directories, and for any files that exist only in one or other directory ('unique' files).
File::DirCompare has a single public compare() method, with the following signature:
File::DirCompare->compare(
$dir1
,
$dir2
,
$sub
,
$opts
);
The first three arguments are required - $dir1 and $dir2 are paths to the two directories to be compared, and $sub is the subroutine reference called for all unique or different files. $opts is an optional hashref of options - see OPTIONS below.
The provided subroutine is called for all unique files, and for every pair of 'different' files encountered, with the following signature:
$sub
->(
$file1
,
$file2
)
where $file1 and $file2 are the paths to the two files. For 'unique' files i.e. where a file exists in only one directory, the subroutine is called with the other argument 'undef' i.e. for:
$sub
->(
$file1
,
undef
)
$sub
->(
undef
,
$file2
)
the first indicates $file1 exists only in the first directory given ($dir1), and the second indicates $file2 exists only in the second directory given ($dir2).
OPTIONS
The following optional arguments are supported, passed in using a hash reference after the three required arguments to compare() e.g.
File::DirCompare->compare(
$dir1
,
$dir2
,
$sub
, {
cmp
=>
$cmp_sub
,
ignore_cmp
=> 1,
ignore_unique
=> 1,
matches
=>
$matches_sub
,
});
- cmp
-
By default, two files are regarded as different if their contents do not match (tested with File::Compare::compare). That default behaviour can be overridden by providing a 'cmp' subroutine to do the file comparison, returning zero if the two files are equal, and non-zero if not.
E.g. to compare using modification times instead of file contents:
File::DirCompare->compare(
$dir1
,
$dir2
,
$sub
, {
cmp
=>
sub
{ -M
$_
[0] <=> -M
$_
[1] },
});
- ignore_cmp
-
If you want to see all corresponding files, not just 'different' ones, set the 'ignore_cmp' flag to tell File::DirCompare to skip its file comparison checks i.e.
File::DirCompare->compare(
$dir1
,
$dir2
,
$sub
,
{
ignore_cmp
=> 1 });
- ignore_unique
-
If you want to ignore files that only exist in one of the two directories, set the 'ignore_unique' flag i.e.
File::DirCompare->compare(
$dir1
,
$dir2
,
$sub
,
{
ignore_unique
=> 1 });
- matches
-
Subroutine to be called for file pairs that match, with the following signature:
$sub
->(
$file1
,
$file2
)
These pairs are ordinarily ignored (unless
ignore_cmp
is set).
SEE ALSO
File::Dircmp, which provides similar functionality (and whose directory walking code I've adapted for this module), but a simpler reporting-only interface, something like the first example in the SYNOPSIS above.
AUTHOR AND CREDITS
Gavin Carr <gavin@openfusion.com.au>
Thanks to Robin Barker for a bug report and fix for glob problems with whitespace.
COPYRIGHT AND LICENSE
Copyright 2006-2012 by Gavin Carr <gavin@openfusion.com.au>.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.