implement the auto-restarter
[gitmo/MooseX-Runnable.git] / lib / MooseX / Runnable / Invocation / Plugin / Restart / Auto.pm
CommitLineData
3fe76927 1package MooseX::Runnable::Invocation::Plugin::Restart::Auto;
2use Moose::Role;
3use MooseX::Types;
4use MooseX::Types::Moose qw(ArrayRef RegexpRef Any Str);
5use MooseX::Types::Path::Class qw(Dir);
6use File::ChangeNotify;
7
8# coerce ArrayRef[Dir], from ArrayRef[Any], via {[
9# map { warn $_; Path::Class::dir($_) } @$_,
10# ]};
11
12coerce RegexpRef, from Str, via { qr/$_/i };
13
14use namespace::autoclean;
15
16with 'MooseX::Runnable::Invocation::Plugin::Restart::Base';
17
18has 'watch_regexp' => (
19 is => 'ro',
20 isa => RegexpRef,
21 required => 1,
22 coerce => 1,
23 default => sub { qr/^[^.].+[.]pmc?$/i },
24);
25
26has 'watch_directories' => (
27 is => 'ro',
28 isa => ArrayRef[Dir],
29 required => 1,
30 coerce => 1,
31 default => sub { [Path::Class::dir('.')] },
32);
33
34has 'watcher' => (
35 is => 'ro',
36 isa => 'File::ChangeNotify::Watcher',
37 lazy_build => 1,
38);
39
40sub _build_initargs_from_cmdline {
41 my ($self, @args) = @_;
42
43 my $regexp;
44 my @dirs;
45 my $next_type;
46 for my $arg (@args){
47 # if($arg eq '--inc'){
48 # push @dirs, @INC;
49 # }
50 if($arg eq '--dir'){
51 $next_type = 'dir';
52 }
53 elsif($arg eq '--regexp' || $arg eq '--regex'){
54 # i call them regexps, other people call them "regexen" :P
55 $next_type = 'regexp';
56 }
57 elsif($next_type eq 'dir'){
58 push @dirs, $arg;
59 }
60 elsif($next_type eq 'regexp'){
61 $regexp = $arg;
62 }
63 else {
64 confess 'Invalid args passed to Restart::Auto';
65 }
66 }
67 my %result;
68 $result{watch_directories} = [map { Path::Class::dir($_) } @dirs] if @dirs;
69 $result{watch_regexp} = $regexp if $regexp;
70 return \%result;
71}
72
73sub _build_watcher {
74 my $self = shift;
75 my $w = File::ChangeNotify->instantiate_watcher(
76 directories => [map { $_->stringify } @{$self->watch_directories}],
77 filter => $self->watch_regexp,
78 );
79
80 return $w;
81}
82
83sub run_parent_loop {
84 my $self = shift;
85 while(1){
86 my @events = $self->watcher->wait_for_events();
87 $self->restart;
88 sleep .5; # "debounce" the notifier
89 }
90}
91
921;