App-Env
view release on metacpan or search on metacpan
lib/App/Env.pm view on Meta::CPAN
my ( @res, $res );
my $wantarray = wantarray; ## no critic (Community::Wantarray)
eval {
if ( $wantarray ) {
@res = IPC::System::Simple::capture( @_ );
}
else {
$res = IPC::System::Simple::capture( @_ );
}
1;
} // do {
App::Env::_Util::croak( $@ ) if $self->_opt->{SysFatal};
# should return false, but need to keep API backwards compat
return undef;
};
return $wantarray ? @res : $res;
}
#-------------------------------------------------------
sub capture {
my $self = shift;
my @args = @_;
my $redirect;
$redirect = pop @args if 'HASH' eq ref $args[-1];
local %ENV = %{$self};
my $wantarray = wantarray; ## no critic (Community::Wantarray)
require Capture::Tiny;
require IPC::System::Simple;
my $exit;
my $sub
= $self->_opt->{SysFatal}
? sub { $exit = IPC::System::Simple::system( @args ) }
: sub { $exit = CORE::system( @args ) };
# Capture::Tiny::capture is prototyped as (&;@). App::Env
# lazy-loads Capture::Tiny and thus nominally avoids the prototype
# check. However, if Capture::Tiny is explicitly loaded prior to
# App::Env, the prototype check will be performed when App::Env is
# compiled. In that case the following calls to capture are
# singled out, as while the calls are correct, the prototype
# requires an explicit block or sub{}. So, explicitly
# ignore prototypes.
my @return;
eval {
## no critic (AmpersandSigils,AmpersandSubCalls )
if ( $redirect ) {
my %redirect;
for my $stream ( 'stdout', 'stderr' ) {
next unless exists $redirect->{$stream};
my $handle = $redirect->{$stream};
$handle = IO::File->new( $handle, '>' )
if ref $handle eq q{};
$redirect{$stream} = $handle;
}
&Capture::Tiny::capture( $sub, %redirect );
$return[0] = $exit;
}
elsif ( $wantarray ) {
@return = &Capture::Tiny::capture( $sub );
}
else {
$return[0] = &Capture::Tiny::capture( $sub );
}
1;
} // App::Env::_Util::croak( $@ );
## no critic (EmptyReturn)
return if !defined $wantarray;
return $wantarray ? @return : $return[0];
}
#-------------------------------------------------------
sub exec { ## no critic (Subroutines::ProhibitBuiltinHomonyms)
my $self = shift;
local %ENV = %{$self};
exec( @_ );
}
#-------------------------------------------------------
sub which {
require File::Which;
my $self = shift;
{
local %ENV = %{$self};
return File::Which::which( @_ );
}
}
1;
#
# This file is part of App-Env
#
# This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
#
# This is free software, licensed under:
#
# The GNU General Public License, Version 3, June 2007
#
__END__
=pod
lib/App/Env.pm view on Meta::CPAN
Not all variable names may be set with a shell command, but may be
inherited from the parent environment. This option controls whether
such variables are returned by L</str>. It defaults to false.
=back
=item system
$env->system( $command, @args );
This runs the passed command in the environment defined by B<$env>.
It has the same argument and returned value convention as the core
Perl B<system> command.
If the B<SysFatal> flag is set for this environment,
B<IPC::System::Simple::system> is called, which will cause this method
to throw an exception if the command returned a non-zero exit value.
It also avoid invoking a shell to run the command if possible.
=item exec
$env->exec( $command, @args );
This execs the passed command in the environment defined by B<$env>.
It has the same argument and returned value convention as the core
Perl B<exec> command.
=item qexec
$output = $env->qexec( $command, @args );
@lines = $env->qexec( $command, @args );
This acts like the B<qx{}> Perl operator. It executes the passed
command in the environment defined by B<$env> and returns its
(standard) output. If called in a list context the output is
split into lines.
If the B<SysFatal> flag is set for this environment,
B<IPC::System::Simple::capture> is called, which will cause this
method to throw an exception if the command returned a non-zero exit
value. It also avoid invoking a shell to run the command if possible.
=item capture
Execute a command in the environment defined by B<$env> and returns or
redirects the content of its standard output and error streams.
Check the C<$?> variable for the exit value of the command.
=over
=item *
Return the standard output stream
$stdout = $env->capture( $command, @args );
=item *
Return output, error and command exit value.
($stdout, $stderro, $exit) = $env->capture( $command, @args );
=item *
Return exit value and redirect standard output or error streams.
$exit = $env->capture( $command, @args,
{ stdout => $out, stderr => $err }
);
C<$out> and C<$err> may either by filehandles (e.g. L<IO::File>
objects) or file names.
=back
For even more control of the output streams, consider calling
L<Capture::Tiny/capture> directly, e.g.
my $exit;
capture { $exit = $env->system( $command, @args ) }
If the B<SysFatal> flag is set for this environment,
B<IPC::System::Simple::capture> is called, which will cause this
method to throw an exception if the command returned a non-zero exit
value. It also avoids invoking a shell to run the command if possible.
=item which
$path = $env->which( $command );
@paths = $env->which( $command );
Return the path (or paths in list mode) of the passed command using
L<File::Which>. It returns C<undef> or an empty list if the command
is not found.
=back
=head2 Changing Default Option Values
Default values for some options may be changed via any of the
following:
=over
=item *
Passing a hashref as the only argument when initially importing the
package:
use App::Env \%Default;
=item *
Calling the B<config> function:
App::Env::config( %Default );
=back
The following options may have their default values changed:
Force Cache Site SysFatal
=head1 EXAMPLE USAGE
=head2 A single application
This is the simplest case. If you don't care if you "pollute" the
( run in 3.061 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )