App-Pfind
view release on metacpan or search on metacpan
lib/App/Pfind.pm view on Meta::CPAN
$Data::Dumper::Terse = 1; # Don't output variable names.
$Data::Dumper::Sortkeys = 1; # Sort the content of the hash variables.
$Data::Dumper::Useqq = 1; # Use double quote for string (better escaping).
{
# A simple way to make a scalar be read-only.
package App::Pfind::ReadOnlyVar;
sub TIESCALAR {
my ($class, $value) = @_;
return bless \$value, $class;
}
sub FETCH {
my ($self) = @_;
return $$self;
}
# Does nothing. We could warn_or_die, but it does not play well with the fact
# that we are inside the safe.
sub STORE {}
# Secret hidden methods for our usage only. These methods can't be used
# through the tie-ed variable, but only through the object returned by the
# call to tie.
sub set {
my ($self, $value) = @_;
$$self = $value;
}
}
# These two variables are shared with the user code. They have this name as a
# localized copy is passed to the code.
our ($internal_pfind_dir, $internal_pfind_name);
my $dir_setter = tie $internal_pfind_dir, 'App::Pfind::ReadOnlyVar';
my $name_setter = tie $internal_pfind_name, 'App::Pfind::ReadOnlyVar';
# A Safe object, created in reset_options.
my $safe;
# This hash contains options that are global for the whole program.
my %options;
# Methods that are shared with the safe:
sub prune {
die "The prune command cannot be used when --depth-first is set.\n" if $options{depth_first};
$File::Find::prune = 1;
}
# The prototype means that $_ will be used if nothing else is passed.
sub mkdir(_;@) {
my $err;
make_path(@_, { error => \$err });
# make_path sets $! on success (as it test the existance of the file).
undef $!;
$! = join(', ', @$err) if @$err;
}
sub rmdir(_;@) {
for my $d (@_) {
CORE::rmdir($d);
}
}
# A safe 'rm' that does not recurse into directories.
sub rm(_;@) {
for my $f (@_) {
if (-d $f) {
CORE::rmdir($f);
return if $!;
} else {
my $err;
remove_tree($f, { error => \$err });
undef $!;
$! = join(', ', @$err) if @$err;
}
}
}
sub rmtree(_;@) {
my $err;
remove_tree(@_, { error => \$err });
undef $!;
$! = join(', ', @$err) if @$err;
}
sub reset_options {
$safe = Safe->new();
$safe->deny_only(':ownprocess', ':others', ':dangerous');
$safe->reval('use File::Spec::Functions qw(:ALL);');
$safe->reval('use File::Copy qw(cp mv)');
$safe->share('$internal_pfind_dir', '$internal_pfind_name', 'prune', 'mkdir',
'rmdir', 'rm', 'rmtree');
$safe->share_from('main', ['*STDERR']);
# Whether to process the content of a directory before the directory itself.
$options{depth_first} = 0;
# Whether to follow the symlinks.
$options{follow} = 0;
# Whether to follow the symlinks using a fast method that may process some files twice.
$options{follow_fast} = 0;
# Whether to recurse in directories.
$options{recurse} = 1;
# Blocks of code to execute before the main loop
$options{begin} = [];
# Blocks of code to execute after the main loop
$options{end} = [];
# Blocks of code to execute for each file and directory encountered
$options{exec} = [];
# Blocks of code to execute at the beginning of the processing of each directory
$options{pre} = [];
# Blocks of code to execute at the end of the processing of each directory
$options{post} = [];
# Type of files that are processed. Note that after the reading of the option, this is concatenated in a string.
$options{type} = [];
# Whether to chdir in the crawled directories
$options{chdir} = 1;
# Whether to catch errors returned in $! in user code
$options{catch_errors} = 1; # non-modifiable for now.
# Add this string after each print statement
$options{print} = "\n";
# If true, debug message are printed on STDERR
$options{verbose} = 0;
}
sub all_options {(
'help|h' => sub { pod2usage(-exitval => 0, -verbose => 2) },
( run in 2.432 seconds using v1.01-cache-2.11-cpan-302cb4679cc )