File Coverage

blib/lib/Log/Parallel/Paths.pm
Criterion Covered Total %
statement 68 74 91.8
branch 14 30 46.6
condition 1 5 20.0
subroutine 9 9 100.0
pod 0 4 0.0
total 92 122 75.4


line stmt bran cond sub pod time code
1              
2             package Log::Parallel::Paths;
3              
4 1     1   19562 use strict;
  1         1  
  1         29  
5 1     1   5 use warnings;
  1         1  
  1         22  
6 1     1   4 use Carp;
  1         2  
  1         91  
7             require Exporter;
8 1     1   691 use Eval::LineNumbers qw(eval_line_numbers);
  1         261  
  1         1294  
9              
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw(path_to_shell_glob path_to_regex path_to_filename);
12              
13             my $debug = 0;
14              
15             sub path_to_filename
16             {
17 4     4 0 21786 my ($raw, %data) = @_;
18              
19 4         32 my %formats = (
20             BUCKET => '%05d',
21             SOURCE_BKT => '%05d',
22             YYYY => '%04d',
23             MM => '%02d',
24             DD => '%02d',
25             HH => '%02d',
26             FROM_YYYY => '%04d',
27             FROM_MM => '%02d',
28             FROM_DD => '%02d',
29             );
30              
31 4         6 my $path = $raw;
32              
33 4         26 $path =~ s/%([A-Z_]+)%/do {
  16         49  
34 16 50       42 confess "No %$1% data element defined" unless defined $data{$1};
35 16   50     36 my $format = $formats{$1} || "%s";
36 16         23 my $data = $data{$1};
37 16         24 $data =~ s{ }{-}g;
38 16         73 sprintf($format, $data);
39             }/ge;
40              
41 4 50       13 print "path_to_filename($raw) = $path\n" if $debug;
42              
43 4         24 return $path;
44             }
45              
46             sub path_to_shell_glob
47             {
48 1     1 0 3235 my ($path) = @_;
49 1         3 my $orig = $path;
50              
51 1         5 $path =~ s/%BUCKET%/[0-9][0-9][0-9][0-9][0-9]/g; # buckets are five digits
52 1         3 $path =~ s/%SOURCE_BKT%/[0-9][0-9][0-9][0-9][0-9]/g; # buckets are five digits
53 1         4 $path =~ s/%YYYY%/20[0-9][0-9]/g; # will stop working in 2100 !
54 1         4 $path =~ s/%MM%/[01][0-9]/g;
55 1         4 $path =~ s/%DD%/[0-3][0-9]/g;
56 1         2 $path =~ s/%HH%/[0-3][0-9]/g;
57 1         3 $path =~ s/%FROM_YYYY%/20[0-9][0-9]/g; # will stop working in 2100 !
58 1         3 $path =~ s/%FROM_MM%/[01][0-9]/g;
59 1         2 $path =~ s/%FROM_DD%/[0-3][0-9]/g;
60 1         3 $path =~ s/%\w*=.*?%/*/g;
61 1         1 $path =~ s/%%%/%/g;
62 1 50       6 die $path if $path =~ /%/;
63              
64 1 50       4 print "path_to_shell_glob($orig) = $path\n" if $debug;
65              
66 1         3 return $path;
67             }
68              
69             sub alternates
70             {
71 1     1 0 3 my ($alts) = @_;
72 1         6 my @terms = split(/,/, $alts, -1);
73 1         3 return "(?:" . join('|', map { "\Q$_\E" } @terms) . ")";
  2         8  
74             }
75              
76             sub path_to_regex
77             {
78 2     2 0 5351 my ($path, $c) = @_;
79              
80 2         5 my $orig = $path;
81              
82 2 50       7 $c = 1 unless $c;
83 2         3 my @var_list;
84 2         33 my %canned = (
85             BUCKET => qr/\d{5}/,
86             SOURCE_BKT => qr/\d{5}/,
87             YYYY => qr/\d{4}/,
88             MM => qr/\d\d/,
89             DD => qr/\d\d/,
90             HH => qr/\d\d/,
91             FROM_YYYY => qr/\d{4}/,
92             FROM_MM => qr/\d\d/,
93             FROM_DD => qr/\d\d/,
94             DURATION => qr/(?:\d+(?:day|week|month|quarter|year)|(?:daily|weekly|monthly|quarterly|yearly))/,
95             );
96 2         17 my %reserved = (
97             %canned,
98             size => 1,
99             timestr => 1,
100             timezone => 1,
101             file => 1,
102             );
103              
104             my $replace = sub {
105 7     7   11 my $old = shift;
106 7 50       19 if ($canned{$old}) {
    0          
107 7         10 push(@var_list, $old);
108 7         84 return qr/($canned{$old})/;
109             } elsif ($old =~ /(\w*)=(.*)/) {
110 0 0       0 die if $reserved{$old};
111 0 0 0     0 if (defined($1) && $1 ne '') {
112 0         0 push(@var_list, $1);
113             } else {
114 0         0 push(@var_list, 's k i p');
115             }
116 0         0 return qr/($2)/;
117             } else {
118 0         0 die "No path substitution for '%$old%'\n";
119             }
120 2         11 };
121              
122             # everything but %stuff% should be literal
123 2         17 $path =~ s/
124             (?:
125             (?:
126             %([^%]*)%
127             )
128             |
129             (
130             [^-%a-z0-9A-Z_{}]+
131             (?:
132             %
133             (?!
134             .*%
135             )
136             )?
137             |
138             (?:
139             %
140             (?!
141             .*%
142             )
143             )
144             [^-%a-z0-9A-Z_{}]*
145             )
146             |
147             \{([^{}]+)\}
148             |
149             ([^-a-z0-9A-Z_]+)
150             )
151             /
152 18 50       87 $1 ? $replace->($1)
    100          
    100          
153             : defined($2) ? $2
154             : defined($3) ? alternates($3)
155             : "\Q$4\E"
156             /gsex;
157 2         10 $path =~ s/%%%/%/g;
158              
159 2         23 $path .= '$';
160              
161             # handle %YYYY% and such specially
162             # $path =~ s/%(YYYY|MM|DD|HH|[a-z]\w*=[^%]*?)%/$replace->($1)/ge;
163              
164 2         8 my $code = eval_line_numbers(<<'END_CODE');
165             sub {
166             return (
167             END_CODE
168 2         30 for my $v (@var_list) {
169 7 50       19 $code .= "\t\t\t\t'$v' => \$$c,\n"
170             unless $v eq 's k i p';
171 7         10 $c++;
172             }
173 2         5 $code .= eval_line_numbers(<<'END_CODE2');
174             );
175             };
176             END_CODE2
177 2         145 my $sub = eval $code;
178 2 50       7 die $@ if $@;
179              
180 2 50       5 print "path to regex($orig) = $path\n" if $debug;
181              
182 2         72 return (qr/$path/, $sub);
183             }
184              
185             1;
186              
187             __END__