File Coverage

blib/lib/IPC/PrettyPipe/Execute/IPC/Run.pm
Criterion Covered Total %
statement 20 20 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 27 27 100.0


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   1701 use 5.10.0;
  3         13  
6              
7 3     3   21 use Types::Standard qw[ InstanceOf ];
  3         6  
  3         61  
8              
9              
10 3     3   2889 use Try::Tiny;
  3         8  
  3         172  
11 3     3   921 use IPC::Run ();
  3         25370  
  3         96  
12 3     3   18 use Carp ();
  3         6  
  3         59  
13              
14 3     3   16 use Moo;
  3         7  
  3         26  
15             our $VERSION = '0.11'; # TRIAL
16              
17 3     3   1241 use namespace::clean;
  3         7  
  3         37  
18              
19              
20              
21              
22              
23              
24              
25              
26             has pipe => (
27             is => 'ro',
28             isa => InstanceOf ['IPC::PrettyPipe'],
29             required => 1,
30             );
31              
32             # This attribute encapsulates an IPC::Run harness, tieing its creation
33             # to an IO::ReStoreFH object to ensure that filehandles are stored &
34             # restored properly. The IPC::Run harness is created on-demand just
35             # before it is used. A separate object could be used, but then
36             # IPC::PrettyPipe:Execute::IPC::Run turns into a *really* thin shell
37             # around it. no need for an extra layer.
38              
39              
40             has _harness => (
41             is => 'ro',
42             lazy => 1,
43             handles => [qw[ run start pump finish ]],
44             clearer => 1,
45              
46             default => sub {
47              
48             my $self = shift;
49              
50             # While the harness is instantiated, we store the current fh's
51             $self->_storefh;
52              
53             my @harness;
54              
55             my @cmds = @{ $self->pipe->cmds->elements };
56              
57             while ( @cmds ) {
58              
59             my $cmd = shift @cmds;
60              
61             if ( $cmd->isa( 'IPC::PrettyPipe::Cmd' ) ) {
62              
63             push @harness, '|' if @harness;
64              
65             push @harness,
66             [
67             $cmd->cmd,
68             map { $_->render( flatten => 1 ) } @{ $cmd->args->elements },
69             ];
70              
71             push @harness,
72             map { $_->spec, $_->has_file ? $_->file : () }
73             @{ $cmd->streams->elements };
74             }
75             elsif ( $cmd->isa( 'IPC::PrettyPipe' ) ) {
76              
77             croak( "cannot chain sub-pipes which have streams" )
78             unless $cmd->streams->empty;
79             unshift @cmds, @{ $cmd->cmds->elements };
80             }
81             }
82              
83             return IPC::Run::harness( @harness );
84             },
85              
86             );
87              
88             # store the IO::Restore object; created on demand by _harness.default
89             # don't create it otherwise!
90             has _storefh => (
91             is => 'ro',
92             lazy => 1,
93             default => sub { $_[0]->pipe->_storefh },
94             clearer => 1
95             );
96              
97             # the IO::ReStoreFH object lives only as long as the
98             # IPC::Run harness object, and that lives only
99             # as long as necessary.
100             after 'run', 'finish' => sub {
101              
102             my $self = shift;
103              
104             try {
105              
106             # get rid of harness first to avoid possible closing of file
107             # handles while the child is running. of course the child
108             # shouldn't be running at this point, but what the heck
109             $self->_clear_harness;
110              
111             }
112              
113             catch {
114              
115             Carp::croak $_;
116              
117             }
118              
119             finally {
120              
121             $self->_clear_storefh;
122              
123             };
124              
125             };
126              
127             # this needs to go here 'cause this just defines the interface
128             with 'IPC::PrettyPipe::Executor';
129              
130             1;
131              
132             #
133             # This file is part of IPC-PrettyPipe
134             #
135             # This software is Copyright (c) 2018 by Smithsonian Astrophysical Observatory.
136             #
137             # This is free software, licensed under:
138             #
139             # The GNU General Public License, Version 3, June 2007
140             #
141              
142             __END__