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