File Coverage

blib/lib/IPC/PrettyPipe/Execute/IPC/Run.pm
Criterion Covered Total %
statement 36 45 80.0
branch 5 12 41.6
condition n/a
subroutine 8 10 80.0
pod 2 2 100.0
total 51 69 73.9


line stmt bran cond sub pod time code
1             package IPC::PrettyPipe::Execute::IPC::Run;
2              
3             # ABSTRACT: execution backend using IPC::Run
4              
5 3     3   1902 use 5.10.0;
  3         13  
6              
7 3     3   19 use Types::Standard qw[ InstanceOf ];
  3         7  
  3         71  
8              
9              
10 3     3   2292 use Try::Tiny;
  3         8  
  3         174  
11 3     3   945 use IPC::Run ();
  3         26330  
  3         76  
12 3     3   19 use Carp ();
  3         8  
  3         49  
13              
14 3     3   25 use Moo;
  3         9  
  3         38  
15             our $VERSION = '0.13';
16              
17 3     3   1422 use namespace::clean;
  3         9  
  3         41  
18              
19             # This attribute encapsulates an IPC::Run harness, tieing its creation
20             # to an IO::ReStoreFH object to ensure that filehandles are stored &
21             # restored properly. The IPC::Run harness is created on-demand just
22             # before it is used.
23              
24             has _harness => (
25             is => 'rwp',
26             clearer => 1,
27             predicate => 1,
28             init_arg => undef,
29             );
30              
31             # store the IO::Restore object; created on demand by _harness.default
32             # don't create it otherwise!
33             has _storefh => (
34             is => 'rwp',
35             predicate => 1,
36             init_arg => undef,
37             clearer => 1
38             );
39              
40             sub _create_harness {
41 6     6   18 my ( $self, $pipe ) = @_;
42              
43             # While the harness is instantiated, we store the current fh's
44 6         29 $self->_set__storefh( $pipe->_storefh);
45              
46 6         14 my @harness;
47              
48 6         15 my @cmds = @{ $pipe->cmds->elements };
  6         38  
49              
50 6         25 while ( @cmds ) {
51              
52 8         32 my $cmd = shift @cmds;
53              
54 8 50       40 if ( $cmd->isa( 'IPC::PrettyPipe::Cmd' ) ) {
    0          
55              
56 8 100       29 push @harness, '|' if @harness;
57              
58             push @harness,
59             [
60             $cmd->cmd,
61 8         26 map { $_->render( flatten => 1 ) } @{ $cmd->args->elements },
  76         177  
  8         36  
62             ];
63              
64             push @harness,
65 13 100       268 map { $_->spec, $_->has_file ? $_->file : () }
66 8         24 @{ $cmd->streams->elements };
  8         38  
67             }
68             elsif ( $cmd->isa( 'IPC::PrettyPipe' ) ) {
69              
70 0 0       0 croak( "cannot chain sub-pipes which have streams" )
71             unless $cmd->streams->empty;
72 0         0 unshift @cmds, @{ $cmd->cmds->elements };
  0         0  
73             }
74             }
75              
76 6         106 $self->_set__harness( IPC::Run::harness(@harness) );
77             }
78              
79              
80              
81              
82              
83              
84              
85              
86              
87              
88              
89             sub run {
90             my ( $self, $pipe ) = @_;
91             $self->_create_harness( $pipe);
92             $self->_harness->run;
93             }
94              
95              
96              
97              
98              
99              
100              
101              
102              
103              
104             sub start {
105 0     0 1   my ( $self, $pipe ) = @_;
106 0           $self->_create_harness( $pipe );
107 0           $self->_harness->start;
108             }
109              
110              
111              
112              
113              
114              
115              
116              
117             sub pump {
118 0     0 1   my $self = shift;
119 0 0         Carp::croak( "must call run method to create harness\n" )
120             unless $self->_has_harness;
121 0           $self->_harness->pump;
122             }
123              
124              
125              
126              
127              
128              
129              
130             sub finish {
131             my $self = shift;
132             Carp::croak( "must call run method to create harness\n" )
133             unless $self->_has_harness;
134             $self->_harness->finish;
135             }
136              
137             # the IO::ReStoreFH object lives only as long as the
138             # IPC::Run harness object, and that lives only
139             # as long as necessary.
140             after 'run', 'finish' => sub {
141              
142             my $self = shift;
143              
144             try {
145             # get rid of harness first to avoid possible closing of file
146             # handles while the child is running. of course the child
147             # shouldn't be running at this point, but what the heck
148             $self->_clear_harness;
149             }
150              
151             catch {
152             Carp::croak $_;
153             }
154              
155             finally {
156             $self->_clear_storefh;
157             };
158              
159             };
160              
161             # this needs to go here 'cause this just defines the interface
162             with 'IPC::PrettyPipe::Executor';
163              
164             1;
165              
166             #
167             # This file is part of IPC-PrettyPipe
168             #
169             # This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
170             #
171             # This is free software, licensed under:
172             #
173             # The GNU General Public License, Version 3, June 2007
174             #
175              
176             __END__