line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package CloudCron::Compiler; |
2
|
1
|
|
|
1
|
|
108882
|
use Moose; |
|
1
|
|
|
|
|
380365
|
|
|
1
|
|
|
|
|
11
|
|
3
|
1
|
|
|
1
|
|
7023
|
use namespace::autoclean; |
|
1
|
|
|
|
|
6266
|
|
|
1
|
|
|
|
|
5
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
363
|
use CloudCron::Parser; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
30
|
|
6
|
1
|
|
|
1
|
|
368
|
use CloudCron::TargetInput; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
30
|
|
7
|
1
|
|
|
1
|
|
376
|
use CloudCron::CronLineRule; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
27
|
|
8
|
1
|
|
|
1
|
|
474
|
use Cfn; |
|
1
|
|
|
|
|
498624
|
|
|
1
|
|
|
|
|
50
|
|
9
|
1
|
|
|
1
|
|
635
|
use Cfn::Resource::AWS::Events::Rule; |
|
1
|
|
|
|
|
70323
|
|
|
1
|
|
|
|
|
38
|
|
10
|
1
|
|
|
1
|
|
8
|
use Cfn::Resource::Properties::AWS::Events::Rule; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
17
|
|
11
|
1
|
|
|
1
|
|
5
|
use Path::Class; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
58
|
|
12
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
44
|
|
13
|
1
|
|
|
1
|
|
590
|
use ParseCron; |
|
1
|
|
|
|
|
3370
|
|
|
1
|
|
|
|
|
648
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
has target => (is => 'ro', isa => 'CloudCron::TargetQueue', required => 1); |
16
|
|
|
|
|
|
|
has content => (is => 'ro', isa => 'Str', lazy => 1, default => sub { |
17
|
|
|
|
|
|
|
my $self = shift; |
18
|
|
|
|
|
|
|
croak 'Attribute file or content is required!' unless defined $self->file; |
19
|
|
|
|
|
|
|
Path::Class::file($self->file)->slurp; |
20
|
|
|
|
|
|
|
}); |
21
|
|
|
|
|
|
|
has parser => (is => 'ro', isa => 'CloudCron::Parser', lazy => 1, builder => '_parser'); |
22
|
|
|
|
|
|
|
has file => (is => 'ro'); |
23
|
|
|
|
|
|
|
has translator => (is => 'ro', isa => 'ParseCron', lazy => 1, builder => '_translator'); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub _translator { |
26
|
6
|
|
|
6
|
|
7
|
my $self; |
27
|
6
|
|
|
|
|
28
|
return ParseCron->new; |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub _parser { |
31
|
8
|
|
|
8
|
|
16
|
my $self = shift; |
32
|
8
|
|
|
|
|
171
|
return CloudCron::Parser->new({ content => $self->content }); |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub rules { |
36
|
7
|
|
|
7
|
0
|
41
|
my $self = shift; |
37
|
|
|
|
|
|
|
|
38
|
7
|
100
|
|
|
|
168
|
die "Invalid crontab specification" if !$self->parser->is_valid; |
39
|
6
|
|
|
|
|
244
|
my @jobs = $self->parser->jobs; |
40
|
6
|
|
|
|
|
64
|
return map { $self->_as_line_rule($_); } @jobs; |
|
8
|
|
|
|
|
23
|
|
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub _as_line_rule { |
44
|
8
|
|
|
8
|
|
17
|
my ($self, $job) = @_; |
45
|
8
|
|
|
|
|
34
|
return CloudCron::CronLineRule->new({ |
46
|
|
|
|
|
|
|
line => $job->line_number, |
47
|
|
|
|
|
|
|
rule => $self->_as_rule($job), |
48
|
|
|
|
|
|
|
}); |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub envs { |
52
|
9
|
|
|
9
|
0
|
20
|
my $self = shift; |
53
|
9
|
|
|
|
|
225
|
return $self->parser->envs; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub _as_rule { |
57
|
8
|
|
|
8
|
|
14
|
my ($self, $job) = @_; |
58
|
8
|
|
|
|
|
22
|
return Cfn::Resource::AWS::Events::Rule->new({ |
59
|
|
|
|
|
|
|
Properties => $self->_get_properties($job), |
60
|
|
|
|
|
|
|
}); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub _cron { |
64
|
8
|
|
|
8
|
|
13
|
my $self = shift; |
65
|
8
|
|
|
|
|
13
|
my $job = shift; |
66
|
8
|
|
|
|
|
12
|
return join ' ', map { $job->$_->entity } qw/minute hour day month day_of_week/; |
|
40
|
|
|
|
|
433
|
|
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub _name { |
70
|
16
|
|
|
16
|
|
24
|
my ($self, $job) = @_; |
71
|
16
|
|
|
|
|
42
|
my @parts = split /\//, $job->command; |
72
|
16
|
|
|
|
|
37
|
return $parts[$#parts]; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub _input { |
76
|
8
|
|
|
8
|
|
19
|
my ($self, $job, @envars) = @_; |
77
|
8
|
|
|
|
|
17
|
my @aux = map { ($_->key, $_->value) } @envars; |
|
0
|
|
|
|
|
0
|
|
78
|
8
|
|
|
|
|
16
|
my %envs_hash = @aux; |
79
|
8
|
|
|
|
|
206
|
return CloudCron::TargetInput->new({ |
80
|
|
|
|
|
|
|
command => $job->command, |
81
|
|
|
|
|
|
|
env => \%envs_hash, |
82
|
|
|
|
|
|
|
}); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub _description { # name. human cron schedule |
86
|
8
|
|
|
8
|
|
16
|
my ($self, $job) = @_; |
87
|
8
|
|
|
|
|
15
|
my $name = $self->_name($job); |
88
|
8
|
|
|
|
|
216
|
my $human = $self->translator->parse_cron(join ' ', map { $job->$_->entity } qw/minute hour day month day_of_week/); |
|
40
|
|
|
|
|
379
|
|
89
|
8
|
|
|
|
|
2832
|
return $name . " " . $human; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# This method makes possible that crontab files that are valid could be "compiled" |
93
|
|
|
|
|
|
|
# to AWS::Events::Rule. There are some restrictions that needs to be taken |
94
|
|
|
|
|
|
|
# into account. For more information see the "Limits" section on AWS doc here: |
95
|
|
|
|
|
|
|
# http://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html#CronExpressions |
96
|
|
|
|
|
|
|
sub _patch_days { |
97
|
8
|
|
|
8
|
|
17
|
my ($self, $cron) = @_; |
98
|
8
|
|
|
|
|
39
|
my @parts = split /\s/, $cron; |
99
|
8
|
100
|
66
|
|
|
43
|
if (($parts[2] eq '*') && ($parts[4] eq '*')) { |
100
|
6
|
|
|
|
|
10
|
$parts[2] = '?'; |
101
|
|
|
|
|
|
|
} |
102
|
8
|
|
|
|
|
28
|
return (join ' ', @parts) . ' *'; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub _get_properties { |
106
|
8
|
|
|
8
|
|
13
|
my $self = shift; |
107
|
8
|
|
|
|
|
13
|
my $job = shift; |
108
|
8
|
|
|
|
|
29
|
my $cron = $self->_cron($job); |
109
|
8
|
|
|
|
|
107
|
$cron = $self->_patch_days($cron); |
110
|
8
|
|
|
|
|
23
|
my $name = $self->_name($job); |
111
|
8
|
|
|
|
|
18
|
my $description = $self->_description($job); |
112
|
8
|
|
|
|
|
24
|
my $input = $self->_input($job, $self->envs); |
113
|
8
|
|
|
|
|
186
|
return Cfn::Resource::Properties::AWS::Events::Rule->new({ |
114
|
|
|
|
|
|
|
Description => $description, |
115
|
|
|
|
|
|
|
ScheduleExpression => "cron($cron)", |
116
|
|
|
|
|
|
|
State => 'ENABLED', |
117
|
|
|
|
|
|
|
Targets => [ |
118
|
|
|
|
|
|
|
{ |
119
|
|
|
|
|
|
|
Arn => $self->target->Arn, |
120
|
|
|
|
|
|
|
Id => $self->target->Id, |
121
|
|
|
|
|
|
|
Input => $input->json, |
122
|
|
|
|
|
|
|
}, |
123
|
|
|
|
|
|
|
], |
124
|
|
|
|
|
|
|
}); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
128
|
|
|
|
|
|
|
1; |