File Coverage

blib/lib/ETL/Yertl/Command/yq.pm
Criterion Covered Total %
statement 56 60 93.3
branch 18 22 81.8
condition 1 3 33.3
subroutine 10 10 100.0
pod 0 4 0.0
total 85 99 85.8


line stmt bran cond sub pod time code
1             package ETL::Yertl::Command::yq;
2             our $VERSION = '0.037';
3             # ABSTRACT: Filter and construct documents using a mini-language
4              
5 9     9   593219 use ETL::Yertl;
  9         20  
  9         55  
6 9     9   2356 use ETL::Yertl::Util qw( load_module );
  9         20  
  9         414  
7 9     9   53 use boolean qw( :all );
  9         16  
  9         46  
8 9     9   974 use Module::Runtime qw( use_module );
  9         19  
  9         91  
9             our $VERBOSE = $ENV{YERTL_VERBOSE} // 0;
10              
11             sub is_empty {
12 13   33 13 0 91 return !$_[0] || ref $_[0] eq 'empty';
13             }
14              
15             sub main {
16 10     10 0 1164 my $class = shift;
17              
18 10         22 my %opt;
19 10 100       38 if ( ref $_[-1] eq 'HASH' ) {
20 9         18 %opt = %{ pop @_ };
  9         33  
21             }
22              
23 10         31 my ( $filter, @files ) = @_;
24              
25 10 100       33 die "Must give a filter\n" unless $filter;
26              
27 9 100       33 push @files, "-" unless @files;
28 9         23 for my $file ( @files ) {
29             # We're doing a similar behavior to <>, but manually for easier testing.
30 10         22 my $fh;
31 10 100       28 if ( $file eq '-' ) {
32             # Use the existing STDIN so tests can fake it
33 7         24 $fh = \*STDIN;
34             }
35             else {
36 3 50       78 unless ( open $fh, '<', $file ) {
37 0         0 warn "Could not open file '$file' for reading: $!\n";
38 0         0 next;
39             }
40             }
41              
42 10         44 my $in_fmt = load_module( format => 'default' )->new( input => $fh );
43 10         27 my $scope = {};
44 10         39 for my $doc ( $in_fmt->read ) {
45 18         87 my @output = $class->filter( $filter, $doc, $scope );
46 18         76 $class->write( \@output, \%opt );
47             }
48              
49             # Finish the scope, cleaning up any collections
50 10         55 $class->write( [ $class->finish( $scope ) ], \%opt );
51             }
52             }
53              
54             sub write {
55 28     28 0 58 my ( $class, $docs, $opt ) = @_;
56              
57 28 100       58 if ( $opt->{xargs} ) {
58 6         11 print "$_\n" for grep { defined } @$docs;
  11         128  
59 6         28 return;
60             }
61              
62 22         55 my $out_fmt = load_module( format => 'default' )->new;
63 22         99 for my $doc ( @$docs ) {
64 13 50       31 next if is_empty( $doc );
65 13 50       44 if ( isTrue( $doc ) ) {
    50          
66 0         0 print $out_fmt->write( "true" );
67             }
68             elsif ( isFalse( $doc ) ) {
69 0         0 print $out_fmt->write( "false" );
70             }
71             else {
72 13         402 print $out_fmt->write( $doc );
73             }
74             }
75             }
76              
77             $ENV{YQ_CLASS} ||= 'ETL::Yertl::Command::yq::Regex';
78             use_module( $ENV{YQ_CLASS} );
79             {
80 9     9   4342 no strict 'refs';
  9         19  
  9         231  
81 9     9   41 no warnings 'once';
  9         17  
  9         1429  
82             *filter = *{ $ENV{YQ_CLASS} . "::filter" };
83             }
84              
85             sub finish {
86 14     14 0 12790 my ( $class, $scope ) = @_;
87 14 100       59 if ( $scope->{sort} ) {
    100          
88 1         2 return map { $_->[1] } sort { $a->[0] cmp $b->[0] } @{ $scope->{sort} };
  3         6  
  3         8  
  1         5  
89             }
90             elsif ( $scope->{group_by} ) {
91 3         11 return $scope->{group_by};
92             }
93 10         30 return;
94             }
95              
96             1;
97              
98             __END__