Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita31aaec

Browse files
committed
Add filter capability to RecursiveCopy::copypath
This allows skipping copying certain files and subdirectories in tests.This is useful in some circumstances such as copying a data directory;future tests want this feature.Also POD-ify the module.Authors: Craig Ringer, Pallavi SontakkeReviewed-By: Álvaro Herrera
1 parenta298a1e commita31aaec

File tree

1 file changed

+96
-11
lines changed

1 file changed

+96
-11
lines changed

‎src/test/perl/RecursiveCopy.pm

Lines changed: 96 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
# RecursiveCopy, a simple recursive copy implementation
1+
2+
=pod
3+
4+
=head1NAME
5+
6+
RecursiveCopy - simple recursive copy implementation
7+
8+
=head1SYNOPSIS
9+
10+
use RecursiveCopy;
11+
12+
RecursiveCopy::copypath($from, $to, filterfn => sub { return 1; });
13+
RecursiveCopy::copypath($from, $to);
14+
15+
=cut
16+
217
packageRecursiveCopy;
318

419
use strict;
@@ -7,35 +22,105 @@ use warnings;
722
use File::Basename;
823
use File::Copy;
924

25+
=pod
26+
27+
=head1DESCRIPTION
28+
29+
=head2copypath($from, $to, %params)
30+
31+
Recursively copy all files and directories from $from to $to.
32+
33+
Only regular files and subdirectories are copied. Trying to copy other types
34+
of directory entries raises an exception.
35+
36+
Raises an exception if a file would be overwritten, the source directory can't
37+
be read, or any I/O operation fails. Always returns true.
38+
39+
If theB<filterfn> parameter is given, it must be a subroutine reference.
40+
This subroutine will be called for each entry in the source directory with its
41+
relative path as only parameter; if the subroutine returns true the entry is
42+
copied, otherwise the file is skipped.
43+
44+
On failure the target directory may be in some incomplete state; no cleanup is
45+
attempted.
46+
47+
=head1EXAMPLES
48+
49+
RecursiveCopy::copypath('/some/path', '/empty/dir',
50+
filterfn => sub {
51+
# omit pg_log and contents
52+
my $src = shift;
53+
return $src ne 'pg_log';
54+
}
55+
);
56+
57+
=cut
58+
1059
subcopypath
1160
{
12-
my$srcpath =shift;
13-
my$destpath =shift;
61+
my($base_src_dir,$base_dest_dir,%params) =@_;
62+
my$filterfn;
1463

15-
die"Cannot operate on symlinks"if-l$srcpathor-l$destpath;
64+
if (defined$params{filterfn})
65+
{
66+
die"if specified, filterfn must be a subroutine reference"
67+
unlessdefined(ref$params{filterfn})
68+
and (ref$params{filterfn}eq'CODE');
1669

17-
# This source path is a file, simply copy it to destination with the
18-
# same name.
19-
die"Destination path$destpath exists as file"if-f$destpath;
70+
$filterfn =$params{filterfn};
71+
}
72+
else
73+
{
74+
$filterfn =sub {return 1; };
75+
}
76+
77+
# Start recursive copy from current directory
78+
return _copypath_recurse($base_src_dir,$base_dest_dir,"",$filterfn);
79+
}
80+
81+
# Recursive private guts of copypath
82+
sub_copypath_recurse
83+
{
84+
my ($base_src_dir,$base_dest_dir,$curr_path,$filterfn) =@_;
85+
my$srcpath ="$base_src_dir/$curr_path";
86+
my$destpath ="$base_dest_dir/$curr_path";
87+
88+
# invoke the filter and skip all further operation if it returns false
89+
return 1unless &$filterfn($curr_path);
90+
91+
# Check for symlink -- needed only on source dir
92+
die"Cannot operate on symlinks"if-l$srcpath;
93+
94+
# Can't handle symlinks or other weird things
95+
die"Source path\"$srcpath\" is not a regular file or directory"
96+
unless-f$srcpathor-d$srcpath;
97+
98+
# Abort if destination path already exists. Should we allow directories
99+
# to exist already?
100+
die"Destination path\"$destpath\" already exists"if-e$destpath;
101+
102+
# If this source path is a file, simply copy it to destination with the
103+
# same name and we're done.
20104
if (-f$srcpath)
21105
{
22106
copy($srcpath,$destpath)
23107
ordie"copy$srcpath ->$destpath failed:$!";
24108
return 1;
25109
}
26110

27-
die"Destination needs to be a directory"unless-d$srcpath;
111+
# Otherwise this is directory: create it on dest and recurse onto it.
28112
mkdir($destpath)ordie"mkdir($destpath) failed:$!";
29113

30-
# Scan existing source directory and recursively copy everything.
31114
opendir(my$directory,$srcpath)ordie"could not opendir($srcpath):$!";
32115
while (my$entry =readdir($directory))
33116
{
34-
nextif ($entryeq'.' ||$entryeq'..');
35-
RecursiveCopy::copypath("$srcpath/$entry","$destpath/$entry")
117+
nextif ($entryeq'.'or$entryeq'..');
118+
_copypath_recurse($base_src_dir,$base_dest_dir,
119+
$curr_patheq'' ?$entry :"$curr_path/$entry",$filterfn)
36120
ordie"copypath$srcpath/$entry ->$destpath/$entry failed";
37121
}
38122
closedir($directory);
123+
39124
return 1;
40125
}
41126

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp