EnvDir
view release on metacpan or search on metacpan
lib/EnvDir.pm view on Meta::CPAN
package EnvDir;
use 5.008005;
use strict;
use warnings;
use Carp ();
use File::Spec;
use Storable ();
our $VERSION = "0.08";
our $DEFAULT_ENVDIR = File::Spec->catdir( File::Spec->curdir, 'env' );
use constant MARK_DELETE => '__MARK_DELETE__';
sub new {
my $class = shift;
my %args = @_;
bless {
clean => 0,
depth => 0,
cache => [],
stack => [],
map { $_ => $args{$_} } qw(clean)
}, $class;
}
my $GLOBAL_INSTANCE;
my @GLOBAL_GUARD;
sub _instance {
my $class = shift;
$GLOBAL_INSTANCE ||= $class->new;
$GLOBAL_INSTANCE;
}
sub import {
my $class = shift;
my @args = @_;
my $autoload = 0;
my $dir = 0;
my $clean = 0;
my $self;
while ( defined( my $arg = shift @args ) ) {
if ( $arg eq '-autoload' ) {
$self = $class->_instance;
$autoload = 1;
$dir = shift @args;
if ( $dir and $dir eq '-clean' ) {
push @_, $dir;
$dir = $DEFAULT_ENVDIR;
}
}
elsif ( $arg eq 'envdir' ) {
my $package = (caller)[0];
no strict 'refs';
*{"$package\::envdir"} = \&envdir;
}
elsif ( $arg eq '-clean' ) {
$self = $class->_instance;
$self->{clean} = 1;
}
}
if ($autoload) {
push @GLOBAL_GUARD, $self->envdir($dir);
}
}
sub envdir {
my ( $self, $envdir ) = @_;
unless ( ref $self and ref $self eq 'EnvDir' ) {
$envdir = $self;
$self = EnvDir->_instance;
}
$self->{depth} = scalar @{ $self->{stack} };
$envdir ||= $DEFAULT_ENVDIR;
my $depth = $self->{depth};
# from cache
my @keys = keys %{ $self->{cache}->[$depth] };
if ( scalar @keys ) {
$self->_push_stack;
$self->_clean_env if $self->{clean};
$self->_update_env;
return EnvDir::Guard->new( sub { $self->_revert if $self } );
}
# from dir
opendir my $dh, $envdir or Carp::croak "Cannot open $envdir: $!";
for my $key ( grep !/^\./, readdir($dh) ) {
my $path = File::Spec->catfile( $envdir, $key );
next if -d $path;
if ( -s $path == 0 ) {
$self->{cache}->[$depth]->{ uc $key } = MARK_DELETE;
}
else {
my $value = $self->_slurp($path);
$self->{cache}->[$depth]->{ uc $key } = $value;
}
}
$self->_push_stack;
$self->_clean_env if $self->{clean};
$self->_update_env;
closedir $dh or Carp::carp "Cannot close $envdir: $!";
return EnvDir::Guard->new( sub { $self->_revert if $self } );
}
( run in 1.045 second using v1.01-cache-2.11-cpan-ff9377addf4 )