File Coverage

blib/lib/ETL/Yertl/Command/yq.pm
Criterion Covered Total %
statement 50 60 83.3
branch 12 22 54.5
condition 1 3 33.3
subroutine 10 10 100.0
pod 0 4 0.0
total 73 99 73.7


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