File Coverage

blib/lib/Catmandu/Fix/cmd.pm
Criterion Covered Total %
statement 15 32 46.8
branch 0 2 0.0
condition n/a
subroutine 5 8 62.5
pod 0 1 0.0
total 20 43 46.5


line stmt bran cond sub pod time code
1             package Catmandu::Fix::cmd;
2              
3 1     1   21075 use namespace::clean;
  1         18575  
  1         9  
4 1     1   1208 use Catmandu::Sane;
  1         95802  
  1         9  
5 1     1   1138 use IO::Pty::Easy;
  1         17941  
  1         70  
6 1     1   1015 use JSON::XS;
  1         6555  
  1         77  
7 1     1   9 use Moo;
  1         2  
  1         9  
8              
9             =head1 NAME
10              
11             Catmandu::Fix::cmd - pipe data to be fixed through an external process
12              
13             =head1 VERSION
14              
15             Version 0.0201
16              
17             =cut
18              
19             our $VERSION = '0.0201';
20              
21             =head1 DESCRIPTION
22              
23             This fix passes data as a JSON object to an external process over stdin and
24             reads a JSON object from it's stdout.
25              
26             =head1 SYNOPSIS
27              
28             my $fixer = Catmandu::Fix->new(fixes => [
29             # pipe data through the jq command-line json processor
30             # keeping only the title field
31             'cmd("jq -c -M {title}")',
32             # ...
33             ]);
34              
35             # a canonical external program in perl
36             use JSON;
37             while () {
38             my $data = decode_json($_);
39             # ...
40             print encode_json($data);
41             }
42              
43             =cut
44              
45             has cmd => (is => 'ro');
46             has pty => (is => 'ro', lazy => 1, builder => 1, predicate => 1);
47             has json => (is => 'ro', lazy => 1, builder => 1);
48              
49             around BUILDARGS => sub {
50             my ($orig, $class, @cmd) = @_;
51             $orig->($class,
52             cmd => [@cmd],
53             );
54             };
55              
56             sub _build_json {
57 0     0     JSON::XS->new->utf8(1);
58             }
59              
60             sub _build_pty {
61 0     0     my ($self) = @_;
62 0           my $cmd = $self->cmd;
63 0           my $pty = IO::Pty::Easy->new;
64 0           $pty->spawn(@$cmd);
65 0           $pty;
66             }
67              
68             sub fix {
69 0     0 0   my ($self, $data) = @_;
70 0           my $json = $self->json;
71 0           my $line = $json->encode($data)."\n";
72 0           $self->pty->write($line);
73 0           for (;;) {
74 0 0         if ($data = $json->incr_parse) {
75 0           last;
76             }
77 0           $line = $self->pty->read;
78 0           chomp $line;
79 0           $json->incr_parse($line);
80             }
81 0           $data;
82             }
83              
84             =head1 SEE ALSO
85              
86             L
87              
88             =head1 AUTHOR
89              
90             Nicolas Steenlant, C<< >>
91              
92             =head1 LICENSE AND COPYRIGHT
93              
94             This program is free software; you can redistribute it and/or modify it
95             under the terms of either: the GNU General Public License as published
96             by the Free Software Foundation; or the Artistic License.
97              
98             See http://dev.perl.org/licenses/ for more information.
99              
100             =cut
101              
102             1;