$Util::Medley::Spawn::VERSION = '0.040';
###############################################################################
use Moose;
use Data::Printer alias => 'pdump';
use Carp;
use IPC::Run3 'run3';
use Kavorka '-all';
=head1 NAME
Util::Medley::Spawn - utility methods for system commands
=head1 VERSION
version 0.040
=head1 SYNOPSIS
...
=cut
###############################################################################
=head1 ATTRIBUTES
=head2 confessOnError (optional)
Toggle for to enable/disable confess on error. Default is 1.
=cut
has confessOnError => (
is => 'rw',
isa => 'Bool',
default => 1,
);
###############################################################################
=head1 METHODS
=head2 capture
Executes system command and returns the stdout, stderr, and exit values. Will
write to log if enabled.
=over
=item usage:
($stdout, $stderr, $exit) = $util->capture($cmd, [$stdin], [$wantArrayRef])
($stdout, $stderr, $exit) = $util->capture(cmd => $cmd,
[stdin => $stdin],
[wantArrayRefs => $wantArrayRef])
=item args:
=over
=item cmd [ArrayRef|Str]
System command to invoke. Can be an arrayref or a string.
=item stdin [ArrayRef|Str] (optional)
Stdin to pass to the command.
=item wantArrayRef [Bool]
If true, returns stdout and stderr as array refs instead of strings. Default
is 0.
=back
=back
=cut
multi method capture(
ArrayRef|Str :$cmd !,
ArrayRef|Str :$stdin,
Bool :$wantArrayRef
)
{
my $cmdStr;
if ( ref($cmd) eq 'ARRAY' ) {
$cmdStr = join( ' ', @$cmd );
}
else {
$cmdStr = $cmd;
}
$self->Logger->verbose($cmdStr);
my ( $stdout, $stderr, $exit );
my $rc = run3 $cmd, \$stdin, \$stdout, \$stderr;
$exit = $? >> 8;
if ( !$rc or $exit ) {
if ( $self->confessOnError ) {
my $msg =
sprintf
"run3 failed for cmd: exit=%s cmd='%s' stdout='%s' stderr='%s'",
$exit, $cmdStr, $stdout, $stderr;
confess $msg;
}
}
chomp $stdout;
chomp $stderr;
if ($wantArrayRef) {
return ( [ split( /\n/, $stdout ) ], [ split( /\n/, $stderr ) ],
$exit );
}
return ( $stdout, $stderr, $exit );
}
multi method capture(ArrayRef|Str $cmd,
ArrayRef|Str $stdin
? )
{
my %a;
$a{cmd} = $cmd;
$a{stdin} = $stdin if $stdin;
return $self->capture(%a);
}
=head2 spawn
Executes system command and returns the exit value. Will write to log
if enabled.
=over
=item usage:
$exit = $util->spawn($cmd);
$exit = $util->spawn(cmd => $cmd);
=item args:
=over
=item cmd [ArrayRef|Str]
System command to invoke. Can be an arrayref or a string.
=back
=back
=cut
multi method spawn(ArrayRef|Str :$cmd! ) {
if ( ref($cmd) eq 'ARRAY' ) {
$self->Logger->verbose( join( ' ', @$cmd ) );
system(@$cmd);
}
else {
$self->Logger->verbose($cmd);
system($cmd);
}
my $exit = $? >> 8;
if ($exit) {
if ( $self->confessOnError ) {
confess "last command failed with exit code $exit";
}
}
return $exit;
}
multi method spawn(ArrayRef|Str $cmd) {
return $self->spawn( cmd => $cmd );
}
##############################################
1;