File Coverage

blib/lib/App/NDTools/NDProc/Module/Pipe.pm
Criterion Covered Total %
statement 55 55 100.0
branch 11 14 78.5
condition n/a
subroutine 13 13 100.0
pod 0 4 0.0
total 79 86 91.8


line stmt bran cond sub pod time code
1             package App::NDTools::NDProc::Module::Pipe;
2              
3 4     4   70068 use strict;
  4         17  
  4         144  
4 4     4   20 use warnings FATAL => 'all';
  4         9  
  4         165  
5 4     4   474 use parent 'App::NDTools::NDProc::Module';
  4         318  
  4         24  
6              
7 4     4   2468 use IPC::Run3;
  4         70943  
  4         249  
8 4     4   34 use Log::Log4Cli;
  4         9  
  4         347  
9 4     4   33 use App::NDTools::Slurp qw(s_decode s_encode);
  4         10  
  4         246  
10 4     4   30 use Struct::Path 0.80 qw(path);
  4         85  
  4         223  
11 4     4   35 use Struct::Path::PerlStyle 0.80 qw(str2path);
  4         66  
  4         2142  
12              
13             our $VERSION = '0.06';
14              
15 1     1 0 6 sub MODINFO { "Modify structure using external process" }
16              
17             sub arg_opts {
18 8     8 0 16 my $self = shift;
19              
20             return (
21             $self->SUPER::arg_opts(),
22             'command|cmd=s' => \$self->{OPTS}->{command},
23             'strict' => \$self->{OPTS}->{strict},
24             )
25 8         34 }
26              
27             sub check_rule {
28 8     8 0 19 my ($self, $rule) = @_;
29 8         14 my $out = $self;
30              
31             # process full source if no paths defined # FIXME: move it to parent and make common for all mods
32 8 100       16 push @{$rule->{path}}, '' unless (@{$rule->{path}});
  3         16  
  8         29  
33              
34 8 100       28 unless (defined $rule->{command}) {
35 1     1   36 log_error { 'Command to run should be defined' };
  1         127  
36 1         6 $out = undef;
37             }
38              
39 8         41 return $out;
40             }
41              
42             sub process_path {
43 7     7 0 27 my ($self, $data, $path, $opts) = @_;
44              
45 7         17 my $spath = eval { str2path($path) };
  7         84  
46 7 50       10094 die_fatal "Failed to parse path ($@)", 4 if ($@);
47              
48 7         18 my @refs = eval { path(${$data}, $spath, strict => $opts->{strict}) };
  7         13  
  7         70  
49 7 100       944 die_fatal "Failed to lookup path '$path'", 4 if ($@);
50              
51 6         16 for my $r (@refs) {
52 6         11 my $in = s_encode(${$r}, 'JSON', { pretty => 1 });
  6         32  
53              
54 6         29 my ($out, $err);
55 6         48 run3($opts->{command}, \$in, \$out, \$err, { return_if_system_error => 1});
56 6 50       46334 die_fatal "Failed to run '$opts->{command}' ($!)", 2
57             if ($? == -1); # run3 specific
58 6 100       77 unless ($? == 0) {
59 1 50       61 die_fatal "'$opts->{command}' exited with " . ($? >> 8) .
60             ($err ? " (" . join(" ", split("\n", $err)) . ")" : ""), 16;
61             }
62              
63 5         136 ${$r} = s_decode($out, 'JSON');
  4         235  
64             }
65             }
66              
67             1; # End of App::NDTools::NDProc::Module::Pipe
68              
69             __END__