|  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.014';  | 
| 
5
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
2929
 | 
 use App::YAML::Filter::Base;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
    | 
| 
6
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
4334
 | 
 use Pod::Usage::Return qw( pod2usage );  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
297998
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
605
 | 
    | 
| 
7
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
6525
 | 
 use Getopt::Long qw( GetOptionsFromArray );  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72203
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
8
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
4851
 | 
 use YAML;  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35530
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
506
 | 
    | 
| 
9
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
54
 | 
 use boolean qw( :all );  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
    | 
| 
10
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
1160
 | 
 use Module::Runtime qw( use_module );  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
    | 
| 
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
  
 | 
 
 | 
141852
 | 
     my ( $class, @argv ) = @_;  | 
| 
22
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my %opt;  | 
| 
23
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     GetOptionsFromArray( \@argv, \%opt,  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'help|h',  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'verbose|v+',  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'version',  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
28
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1816
 | 
     return pod2usage(0) if $opt{help};  | 
| 
29
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     if ( $opt{version} ) {  | 
| 
30
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         print "yq version $yq::VERSION (Perl $^V)\n";  | 
| 
31
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         return 0;  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
34
 | 
6
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
16
 | 
     $VERBOSE //= $opt{verbose};  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $filter = shift @argv;  | 
| 
37
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     return pod2usage("ERROR: Must give a filter") unless $filter;  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
39
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     push @argv, "-" unless @argv;  | 
| 
40
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     for $ARGV ( @argv ) {  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # We're doing a similar behavior to <>, but manually for easier testing.  | 
| 
42
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         my $fh;  | 
| 
43
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         if ( $ARGV eq '-' ) {  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Use the existing STDIN so tests can fake it  | 
| 
45
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             $fh = \*STDIN;  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
48
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
39
 | 
             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
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         my $buffer;  | 
| 
55
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         my $scope = {};  | 
| 
56
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
         while ( my $line = <$fh> ) {  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # --- is the start of a new document  | 
| 
58
 | 
22
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
76
 | 
             if ( $buffer && $line =~ /^---/ ) {  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # Flush the previous document  | 
| 
60
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
                 my @output = $class->filter( $filter, YAML::Load( $buffer ), $scope );  | 
| 
61
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
                 $class->write( @output );  | 
| 
62
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
702
 | 
                 $buffer = '';  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
64
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
             $buffer .= $line;  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Flush the buffer in the case of a single document with no ---  | 
| 
67
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
         if ( $buffer =~ /\S/ ) {  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print STDERR "Buffer is: $buffer\n";  | 
| 
69
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             my @output = $class->filter( $filter, YAML::Load( $buffer ), $scope );  | 
| 
70
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
             $class->write( @output );  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Finish the scope, cleaning up any collections  | 
| 
74
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1149
 | 
         $class->write( $class->finish( $scope ) );  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2262
 | 
     return 0;  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub write {  | 
| 
81
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
 
 | 
22
 | 
     my ( $class, @docs ) = @_;  | 
| 
82
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     for my $doc ( @docs ) {  | 
| 
83
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
347
 | 
         next if is_empty( $doc );  | 
| 
84
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         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
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
             print YAML::Dump( $doc );  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub diag {  | 
| 
97
 | 
82
 | 
 
 | 
 
 | 
  
82
  
 | 
 
 | 
109
 | 
     my ( $level, $text ) = @_;  | 
| 
98
 | 
82
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
265
 | 
     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
  
 | 
 
 | 
5154
 | 
     no strict 'refs';  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
227
 | 
    | 
| 
105
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
44
 | 
     no warnings 'once';  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1486
 | 
    | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     *filter = *{ $ENV{YQ_CLASS} . "::filter" };  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub finish {  | 
| 
110
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
23924
 | 
     my ( $class, $scope ) = @_;  | 
| 
111
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     if ( $scope->{sort} ) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
112
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         return map { $_->[1] } sort { $a->[0] cmp $b->[0] } @{ $scope->{sort} };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ( $scope->{group_by} ) {  | 
| 
115
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         return $scope->{group_by};  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
117
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     return;  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 exit __PACKAGE__->main( @ARGV ) unless caller(0);  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |