Fix -I issues for win32 (Changelog)
[catagits/Catalyst-Devel.git] / lib / Catalyst / Restarter.pm
CommitLineData
8462f41e 1package Catalyst::Restarter;
2
3use Moose;
4
ffbcd711 5use Cwd qw( abs_path );
a13b99da 6use File::ChangeNotify;
ffbcd711 7use FindBin;
8462f41e 8use namespace::clean -except => 'meta';
9
b8e3feb1 10has start_sub => (
8462f41e 11 is => 'ro',
12 isa => 'CodeRef',
13 required => 1,
14);
15
5ad5350a 16has argv => (
17 is => 'ro',
18 isa => 'ArrayRef',
19 required => 1,
20);
21
8462f41e 22has _watcher => (
23 is => 'rw',
a13b99da 24 isa => 'File::ChangeNotify::Watcher',
8462f41e 25);
26
27has _child => (
28 is => 'rw',
29 isa => 'Int',
30);
31
2e9609df 32sub pick_subclass {
33 my $class = shift;
34
35 my $subclass;
36 $subclass =
37 defined $ENV{CATALYST_RESTARTER}
38 ? $ENV{CATALYST_RESTARTER}
39 : $^O eq 'MSWin32'
40 ? 'Win32'
41 : 'Forking';
42
43 $subclass = 'Catalyst::Restarter::' . $subclass;
44
45 eval "use $subclass";
46 die $@ if $@;
47
48 return $subclass;
49}
50
8462f41e 51sub BUILD {
52 my $self = shift;
53 my $p = shift;
54
b8e3feb1 55 delete $p->{start_sub};
8462f41e 56
a13b99da 57 $p->{filter} ||= qr/(?:\/|^)(?!\.\#).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/;
ffbcd711 58 $p->{directories} ||= abs_path( File::Spec->catdir( $FindBin::Bin, '..' ) );
a13b99da 59
8462f41e 60 # We could make this lazily, but this lets us check that we
61 # received valid arguments for the watcher up front.
a13b99da 62 $self->_watcher( File::ChangeNotify->instantiate_watcher( %{$p} ) );
8462f41e 63}
64
65sub run_and_watch {
66 my $self = shift;
67
68 $self->_fork_and_start;
69
70 return unless $self->_child;
71
72 $self->_restart_on_changes;
73}
74
8462f41e 75sub _restart_on_changes {
76 my $self = shift;
77
a13b99da 78 my @events = $self->_watcher->wait_for_events();
79 $self->_handle_events(@events);
7f564068 80}
8462f41e 81
a13b99da 82sub _handle_events {
83 my $self = shift;
84 my @events = @_;
8462f41e 85
7f564068 86 print STDERR "\n";
87 print STDERR "Saw changes to the following files:\n";
a13b99da 88
89 for my $event (@events) {
90 my $path = $event->path();
91 my $type = $event->type();
92
93 print STDERR " - $path ($type)\n";
94 }
95
7f564068 96 print STDERR "\n";
97 print STDERR "Attempting to restart the server\n\n";
8462f41e 98
7f564068 99 $self->_kill_child;
8462f41e 100
7f564068 101 $self->_fork_and_start;
8462f41e 102
7f564068 103 $self->_restart_on_changes;
8462f41e 104}
105
02758cf8 106sub DEMOLISH {
107 my $self = shift;
108
109 $self->_kill_child;
110}
111
8462f41e 112__PACKAGE__->meta->make_immutable;
113
1141;
83d2d4a4 115
116__END__
117
118=head1 NAME
119
b8e3feb1 120Catalyst::Restarter - Uses File::ChangeNotify to check for changed files and restart the server
83d2d4a4 121
122=head1 SYNOPSIS
123
36ff1319 124 my $class = Catalyst::Restarter->pick_subclass;
125
126 my $restarter = $class->new(
b8e3feb1 127 directories => '/path/to/MyApp',
128 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
129 start_sub => sub { ... }
83d2d4a4 130 );
131
b8e3feb1 132 $restarter->run_and_watch;
83d2d4a4 133
134=head1 DESCRIPTION
135
36ff1319 136This is the base class for all restarters, and it also provide
137functionality for picking an appropriate restarter subclass for a
138given platform.
139
b8e3feb1 140This class uses L<File::ChangeNotify> to watch one or more directories
141of files and restart the Catalyst server when any of those files
142changes.
83d2d4a4 143
144=head1 METHODS
145
36ff1319 146=head2 pick_subclass
147
148Returns the name of an appropriate subclass for the given platform.
149
b8e3feb1 150=head2 new ( start_sub => sub { ... }, ... )
151
36ff1319 152This method creates a new restarter object, but should be called on a
153subclass, not this class.
83d2d4a4 154
b8e3feb1 155The "start_sub" argument is required. This is a subroutine reference
156that can be used to start the Catalyst server.
83d2d4a4 157
b8e3feb1 158=head2 run_and_watch
83d2d4a4 159
b8e3feb1 160This method forks, starts the server in a child process, and then
161watched for changed files in the parent. When files change, it kills
162the child, forks again, and starts a new server.
83d2d4a4 163
164=head1 SEE ALSO
165
b8e3feb1 166L<Catalyst>, <File::ChangeNotify>
83d2d4a4 167
168=head1 AUTHORS
169
170Catalyst Contributors, see Catalyst.pm
171
172=head1 COPYRIGHT
173
174This program is free software, you can redistribute it and/or modify
175it under the same terms as Perl itself.
176
177=cut