File Coverage

bin/yq
Criterion Covered Total %
statement 69 73 94.5
branch 23 28 82.1
condition 4 6 66.6
subroutine 13 13 100.0
pod n/a
total 109 120 90.8


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2             package yq;
3             # ABSTRACT: Filter YAML through a command-line program
4             $yq::VERSION = '0.015';
5 7     7   2943 use App::YAML::Filter::Base;
  7         14  
  7         93  
6 7     7   4155 use Pod::Usage::Return qw( pod2usage );
  7         267588  
  7         508  
7 7     7   5786 use Getopt::Long qw( GetOptionsFromArray );
  7         62894  
  7         43  
8 7     7   4266 use YAML;
  7         31589  
  7         380  
9 7     7   46 use boolean qw( :all );
  7         12  
  7         50  
10 7     7   995 use Module::Runtime qw( use_module );
  7         11  
  7         58  
11              
12             $|++; # no buffering
13              
14             our $VERBOSE = $ENV{YQ_VERBOSE} // 0;
15              
16             sub is_empty {
17 7     7   24 return ref $_[0] eq 'empty';
18             }
19              
20             sub main {
21 8     8   145050 my ( $class, @argv ) = @_;
22 8         16 my %opt;
23 8         45 GetOptionsFromArray( \@argv, \%opt,
24             'help|h',
25             'verbose|v+',
26             'version',
27             );
28 8 100       1843 return pod2usage(0) if $opt{help};
29 7 100       22 if ( $opt{version} ) {
30 1         44 print "yq version $yq::VERSION (Perl $^V)\n";
31 1         6 return 0;
32             }
33              
34 6   33     17 $VERBOSE //= $opt{verbose};
35              
36 6         11 my $filter = shift @argv;
37 6 100       20 return pod2usage("ERROR: Must give a filter") unless $filter;
38              
39 5 100       17 push @argv, "-" unless @argv;
40 5         13 for $ARGV ( @argv ) {
41             # We're doing a similar behavior to <>, but manually for easier testing.
42 5         4 my $fh;
43 5 100       14 if ( $ARGV eq '-' ) {
44             # Use the existing STDIN so tests can fake it
45 4         7 $fh = \*STDIN;
46             }
47             else {
48 1 50       41 unless ( open $fh, '<', $ARGV ) {
49 0         0 warn "Could not open file '$ARGV' for reading: $!\n";
50 0         0 next;
51             }
52             }
53              
54 5         6 my $buffer;
55 5         6 my $scope = {};
56 5         31 while ( my $line = <$fh> ) {
57             # --- is the start of a new document
58 22 100 100     81 if ( $buffer && $line =~ /^---/ ) {
59             # Flush the previous document
60 3         12 my @output = $class->filter( $filter, YAML::Load( $buffer ), $scope );
61 3         99 $class->write( @output );
62 3         829 $buffer = '';
63             }
64 22         63 $buffer .= $line;
65             }
66             # Flush the buffer in the case of a single document with no ---
67 5 50       24 if ( $buffer =~ /\S/ ) {
68             #print STDERR "Buffer is: $buffer\n";
69 5         16 my @output = $class->filter( $filter, YAML::Load( $buffer ), $scope );
70 5         52 $class->write( @output );
71             }
72              
73             # Finish the scope, cleaning up any collections
74 5         1190 $class->write( $class->finish( $scope ) );
75             }
76              
77 5         2419 return 0;
78             }
79              
80             sub write {
81 13     13   21 my ( $class, @docs ) = @_;
82 13         38 for my $doc ( @docs ) {
83 7 100       392 next if is_empty( $doc );
84 6 50       24 if ( isTrue( $doc ) ) {
    50          
85 0         0 print YAML::Dump( "true" );
86             }
87             elsif ( isFalse( $doc ) ) {
88 0         0 print YAML::Dump( "false" );
89             }
90             else {
91 6         197 print YAML::Dump( $doc );
92             }
93             }
94             }
95              
96             sub diag {
97 82     82   116 my ( $level, $text ) = @_;
98 82 50       267 print STDERR "$text\n" if $VERBOSE >= $level;
99             }
100              
101             $ENV{YQ_CLASS} ||= 'App::YAML::Filter::Regex';
102             use_module( $ENV{YQ_CLASS} );
103             {
104 7     7   4055 no strict 'refs';
  7         13  
  7         189  
105 7     7   27 no warnings 'once';
  7         10  
  7         1295  
106             *filter = *{ $ENV{YQ_CLASS} . "::filter" };
107             }
108              
109             sub finish {
110 8     8   14479 my ( $class, $scope ) = @_;
111 8 100       63 if ( $scope->{sort} ) {
    100          
112 1         2 return map { $_->[1] } sort { $a->[0] cmp $b->[0] } @{ $scope->{sort} };
  3         6  
  3         6  
  1         5  
113             }
114             elsif ( $scope->{group_by} ) {
115 3         8 return $scope->{group_by};
116             }
117 4         10 return;
118             }
119              
120             exit __PACKAGE__->main( @ARGV ) unless caller(0);
121              
122             __END__