File Coverage

blib/lib/App/PerlWatcher/Watcher/GenericExecutor.pm
Criterion Covered Total %
statement 70 80 87.5
branch 3 6 50.0
condition n/a
subroutine 18 18 100.0
pod 0 2 0.0
total 91 106 85.8


line stmt bran cond sub pod time code
1             package App::PerlWatcher::Watcher::GenericExecutor;
2             {
3             $App::PerlWatcher::Watcher::GenericExecutor::VERSION = '0.20';
4             }
5             # ABSTRACT: Watches for the output of execution of arbitrary command.
6              
7 2     2   3548 use 5.12.0;
  2         8  
  2         78  
8 2     2   12 use strict;
  2         4  
  2         57  
9 2     2   11 use warnings;
  2         3  
  2         53  
10              
11 2     2   10 use AnyEvent;
  2         2  
  2         58  
12 2     2   934 use AnyEvent::Util;
  2         12874  
  2         177  
13 2     2   16 use Smart::Comments -ENV;
  2         4  
  2         26  
14 2     2   3986 use IPC::Cmd qw/run/;
  2         165369  
  2         151  
15 2     2   24 use Moo;
  2         5  
  2         54  
16 2     2   844 use POSIX qw(SIGKILL);
  2         7  
  2         22  
17              
18 2     2   1190 use App::PerlWatcher::Levels qw/get_by_description LEVEL_NOTICE/;
  2         4  
  2         151  
19 2     2   17 use aliased qw/App::PerlWatcher::EventItem/;
  2         5  
  2         42  
20 2     2   302 use aliased qw/App::PerlWatcher::Status/;
  2         4  
  2         7  
21              
22             with qw/App::PerlWatcher::Watcher/;
23              
24              
25              
26              
27             has 'command' => ( is => 'ro', required => 1 );
28              
29              
30             has 'arguments' => (is => 'ro', default => sub{ []; } );
31              
32              
33             has 'frequency' => (is => 'ro', defalut => sub{ 600; } );
34              
35              
36             has 'timeout' => (is => 'ro', defalut => sub{ []; } );
37              
38              
39             has 'filter' => (is => 'ro', default => sub{ sub{ 1; }; } );
40              
41              
42             has 'beautifyer' => (is => 'ro', default => sub{ sub{ shift;}; });
43              
44              
45             has 'rules' => (is => 'ro', default => sub { []; });
46              
47              
48             sub description {
49 1     1 0 6 my $self = shift;
50 1         8 return "GenericExectuor [" . $self->command . "]";
51             }
52              
53             sub _get_level {
54 3     3   893 my ($self, @lines) = @_;
55 3         27 my $rules = $self->rules;
56 3         24 for (my $i =0; $i < @$rules; $i+=2 ) {
57 5         107 my $level_string = $rules->[$i];
58 5         25 my $rule = $rules->[$i+1];
59 5 100       51 return get_by_description($level_string)
60             if ($rule->(@lines));
61             }
62 1         41 return LEVEL_NOTICE;
63             }
64              
65              
66             has 'callback_proxy' => (is => 'lazy');
67              
68             sub _build_callback_proxy {
69 1     1   6543 my $self = shift;
70             return sub {
71 3     3   45 my $success = shift;
72 3 50       27 unless ($success) {
73 0         0 my $reason = shift;
74             return $self->callback->(
75             Status->new(
76             watcher => $self,
77             level => LEVEL_NOTICE,
78 0         0 description => sub { $self->description . " : $reason" },
79 0         0 items => sub { [] },
80             )
81 0         0 );
82             }
83 3         15 my $output = shift;
84 3         56 my @lines = split("\n", $output);
85 7         80 @lines =
86 16         536 map {$self->beautifyer->($_)}
87 3         24 grep { $self->filter->($_) }
88             @lines;
89 3         43 my $level = $self->_get_level(@lines);
90 7         917 my @items = map {
91 3         16 EventItem->new(
92             content => $_,
93             );
94             } @lines;
95             $self->callback->(
96             Status->new(
97             watcher => $self,
98             level => $level,
99 0         0 description => sub { $self->description; },
100 3         2271 items => sub { \@items, },
101             )
102 3         152 );
103 1         475 };
104             }
105              
106              
107             sub build_watcher_guard {
108 4     4 0 9 my $self = shift;
109             my $guard = AnyEvent->timer(
110             after => 0,
111             interval => $self->frequency,
112             cb => sub {
113 4     4   2911 $self->poll_callback->($self);
114 4         1910 my $output;
115 4         16 my $timeout = $self->timeout;
116 4         6 my $cv_cmd; $cv_cmd = fork_call {
117 0         0 my ($success, $buffer);
118 0         0 eval {
119 0         0 $success = run(
120 0         0 command => [$self->command, @{ $self->arguments }],
121             timeout => $timeout,
122             buffer => \$buffer);
123             };
124 0 0       0 ($success, $success ? $buffer : $@);
125             } sub {
126 3         428773 my ($success, $output) = @_;
127 3         29 undef $cv_cmd;
128 3         394 $self->callback_proxy->($success, $output);
129 4         41 };
130 4         89 });
131 4         117 return $guard;
132             };
133              
134             1;
135              
136             __END__