File Coverage

blib/lib/IPC/Open3/Callback/CommandRunner.pm
Criterion Covered Total %
statement 58 63 92.0
branch 8 12 66.6
condition n/a
subroutine 15 16 93.7
pod 5 5 100.0
total 86 96 89.5


line stmt bran cond sub pod time code
1 1     1   95151 use strict;
  1         2  
  1         32  
2 1     1   8 use warnings;
  1         3  
  1         72  
3              
4             package IPC::Open3::Callback::CommandRunner;
5             $IPC::Open3::Callback::CommandRunner::VERSION = '1.19';
6             # ABSTRACT: A utility class that wraps IPC::Open3::Callback with available output buffers and an option to die on failure instead of returning exit code.
7              
8 1     1   335 use Hash::Util qw(lock_keys);
  1         2214  
  1         6  
9 1     1   332 use IPC::Open3::Callback;
  1         4  
  1         59  
10 1     1   362 use IPC::Open3::Callback::CommandFailedException;
  1         2  
  1         6  
11              
12             sub new {
13 1     1 1 3128 return bless( {}, shift )->_init(@_);
14             }
15              
16             sub _build_callback {
17 6     6   20 my ( $self, $out_or_err, $options ) = @_;
18              
19 6 50       43 if ( defined( $options->{ $out_or_err . '_callback' } ) ) {
    100          
20 0         0 return $options->{ $out_or_err . '_callback' };
21             }
22             elsif ( $options->{ $out_or_err . '_buffer' } ) {
23 3         16 $self->{ $out_or_err . '_buffer' } = ();
24             return sub {
25 6     6   14 push( @{ $self->{ $out_or_err . '_buffer' } }, shift );
  6         47  
26 3         33 };
27             }
28 3         11 return;
29             }
30              
31             sub _clear_buffers {
32 4     4   12 my ($self) = @_;
33 4         14 delete( $self->{out_buffer} );
34 4         12 delete( $self->{err_buffer} );
35             }
36              
37             sub _condense {
38 3     3   58 my ( $self, $buffer ) = @_;
39              
40 3 50       83 if ( $self->{$buffer} ) {
41 3         12 $self->{$buffer} = [ join( '', @{ $self->{$buffer} } ) ];
  3         24  
42 3         81 return $self->{$buffer}[0];
43             }
44              
45 0         0 return;
46             }
47              
48             sub get_err_buffer {
49 0     0 1 0 return $_[0]->_condense('err_buffer');
50             }
51              
52             sub _init {
53 1     1   4 my ( $self, @options ) = @_;
54              
55 1         8 $self->{command_runner} = IPC::Open3::Callback->new(@options);
56              
57 1         2 lock_keys( %{$self}, keys( %{$self} ), 'out_buffer', 'err_buffer' );
  1         3  
  1         7  
58              
59 1         44 return $self;
60             }
61              
62             sub _options {
63 3     3   17 my ( $self, %options ) = @_;
64              
65 3         20 $options{out_callback} = $self->_build_callback( 'out', \%options );
66 3         13 $options{err_callback} = $self->_build_callback( 'err', \%options );
67              
68 3         17 return %options;
69             }
70              
71             sub get_out_buffer {
72 3     3 1 2154 return $_[0]->_condense('out_buffer');
73             }
74              
75             sub run {
76 1     1 1 10 my ( $self, @command ) = @_;
77 1         3 my %options = ();
78              
79             # if last arg is hashref, its command options not arg...
80 1 50       5 if ( ref( $command[-1] ) eq 'HASH' ) {
81 1         46 %options = $self->_options( %{ pop(@command) } );
  1         7  
82             }
83              
84 1         5 $self->_clear_buffers();
85              
86 1         7 return $self->{command_runner}->run_command( @command, \%options );
87             }
88              
89             sub run_or_die {
90 3     3 1 219 my ( $self, @command ) = @_;
91 3         11 my %options = ();
92              
93             # if last arg is hashref, its command options not arg...
94 3 100       15 if ( ref( $command[-1] ) eq 'HASH' ) {
95 2         7 %options = $self->_options( %{ pop(@command) } );
  2         12  
96             }
97              
98 3         20 $self->_clear_buffers();
99              
100 3         24 my $exit_code = $self->{command_runner}->run_command( @command, \%options );
101 2 50       16 if ($exit_code) {
102 0         0 my $exception = IPC::Open3::Callback::CommandFailedException->new(
103             \@command, $exit_code,
104             scalar( $self->get_out_buffer() ),
105             scalar( $self->get_err_buffer() )
106             );
107 0         0 die($exception);
108             }
109              
110 2         54 return $self->get_out_buffer();
111             }
112              
113             1;
114              
115             __END__