1 package Catalyst::Engine::HTTP::Restarter::Watcher;
5 use base 'Class::Accessor::Fast';
9 use Time::HiRes qw/sleep/;
11 __PACKAGE__->mk_accessors(
21 my ( $class, %args ) = @_;
35 my $watch_list = $self->_index_directory;
36 $self->watch_list($watch_list);
41 files => [ keys %{$watch_list} ],
52 my $delay = ( defined $self->delay ) ? $self->delay : 1;
54 sleep $delay if $delay > 0;
56 eval { @changes = $self->modified->changed };
59 # File::Modified will die if a file is deleted.
60 my ($deleted_file) = $@ =~ /stat '(.+)'/;
61 push @changed_files, $deleted_file || 'unknown file';
66 # update all mtime information
67 $self->modified->update;
69 # check if any files were changed
70 @changed_files = grep { -f $_ } @changes;
72 # Check if only directories were changed. This means
73 # a new file was created.
74 unless (@changed_files) {
76 # re-index to find new files
77 my $new_watch = $self->_index_directory;
79 # look through the new list for new files
80 my $old_watch = $self->watch_list;
81 @changed_files = grep { !defined $old_watch->{$_} }
84 return unless @changed_files;
88 for my $file (@changed_files) {
89 next unless $file =~ /\.pm$/;
90 if ( my $error = $self->_test($file) ) {
91 print STDERR qq/File "$file" modified, not restarting\n\n/;
92 print STDERR '*' x 80, "\n";
94 print STDERR '*' x 80, "\n";
100 return @changed_files;
103 sub _index_directory {
106 my $dir = $self->directory;
107 die "No directory specified" if !$dir or ref($dir) && !@{$dir};
109 my $regex = $self->regex || '\.pm$';
115 my $file = File::Spec->rel2abs($File::Find::name);
116 return unless $file =~ /$regex/;
117 return unless -f $file;
118 $file =~ s{/script/..}{};
121 # also watch the directory for changes
122 my $cur_dir = File::Spec->rel2abs($File::Find::dir);
123 $cur_dir =~ s{/script/..}{};
126 follow_fast => $self->follow_symlinks ? 1 : 0,
129 ref $dir eq 'ARRAY' ? @{$dir} : $dir
135 my ( $self, $file ) = @_;
138 local $SIG{__WARN__} = sub { };
140 open my $olderr, '>&STDERR';
141 open STDERR, '>', File::Spec->devnull;
142 eval "require '$file'";
143 open STDERR, '>&', $olderr;
145 return ($@) ? $@ : 0;
153 Catalyst::Engine::HTTP::Restarter::Watcher - Watch for changed application
158 my $watcher = Catalyst::Engine::HTTP::Restarter::Watcher->new(
159 directory => '/path/to/MyApp',
160 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
165 my @changed_files = $watcher->watch();
170 This class monitors a directory of files for changes made to any file
171 matching a regular expression. It correctly handles new files added to the
172 application as well as files that are deleted.
176 =head2 new ( directory => $path [, regex => $regex, delay => $delay ] )
178 Creates a new Watcher object.
182 Returns a list of files that have been added, deleted, or changed since the
183 last time watch was called.
187 L<Catalyst>, L<Catalyst::Engine::HTTP::Restarter>, L<File::Modified>
191 Catalyst Contributors, see Catalyst.pm
195 Many parts are ripped out of C<HTTP::Server::Simple> by Jesse Vincent.
199 This program is free software, you can redistribute it and/or modify it under
200 the same terms as Perl itself.