1 package Catalyst::Engine::HTTP::Restarter::Watcher;
5 use base 'Class::Accessor::Fast';
9 use Time::HiRes qw/sleep/;
11 __PACKAGE__->mk_accessors(
20 my ( $class, %args ) = @_;
34 my $watch_list = $self->_index_directory;
35 $self->watch_list($watch_list);
40 files => [ keys %{$watch_list} ],
51 sleep $self->delay || 1;
53 eval { @changes = $self->modified->changed };
56 # File::Modified will die if a file is deleted.
57 my ($deleted_file) = $@ =~ /stat '(.+)'/;
58 push @changed_files, $deleted_file || 'unknown file';
63 # update all mtime information
64 $self->modified->update;
66 # check if any files were changed
67 @changed_files = grep { -f $_ } @changes;
69 # Check if only directories were changed. This means
70 # a new file was created.
71 unless (@changed_files) {
73 # re-index to find new files
74 my $new_watch = $self->_index_directory;
76 # look through the new list for new files
77 my $old_watch = $self->watch_list;
78 @changed_files = grep { !defined $old_watch->{$_} }
81 return unless @changed_files;
85 for my $file (@changed_files) {
86 next unless $file =~ /\.pm$/;
87 if ( my $error = $self->_test($file) ) {
88 print STDERR qq/File "$file" modified, not restarting\n\n/;
89 print STDERR '*' x 80, "\n";
91 print STDERR '*' x 80, "\n";
97 return @changed_files;
100 sub _index_directory {
103 my $dir = $self->directory || die "No directory specified";
104 my $regex = $self->regex || '\.pm$';
110 my $file = File::Spec->rel2abs($File::Find::name);
111 return unless $file =~ /$regex/;
112 return unless -f $file;
113 $file =~ s{/script/..}{};
116 # also watch the directory for changes
117 my $cur_dir = File::Spec->rel2abs($File::Find::dir);
118 $cur_dir =~ s{/script/..}{};
129 my ( $self, $file ) = @_;
132 local $SIG{__WARN__} = sub { };
134 open my $olderr, '>&STDERR';
135 open STDERR, '>', File::Spec->devnull;
136 eval "require '$file'";
137 open STDERR, '>&', $olderr;
139 return ($@) ? $@ : 0;
147 Catalyst::Engine::HTTP::Restarter::Watcher - Watch for changed application
152 my $watcher = Catalyst::Engine::HTTP::Restarter::Watcher->new(
153 directory => '/path/to/MyApp',
154 regex => '\.yml$|\.yaml$|\.pm$',
159 my @changed_files = $watcher->watch();
164 This class monitors a directory of files for changes made to any file
165 matching a regular expression. It correctly handles new files added to the
166 application as well as files that are deleted.
170 =head2 new ( directory => $path [, regex => $regex, delay => $delay ] )
172 Creates a new Watcher object.
176 Returns a list of files that have been added, deleted, or changed since the
177 last time watch was called.
181 L<Catalyst>, L<Catalyst::Engine::HTTP::Restarter>, L<File::Modified>
185 Sebastian Riedel, <sri@cpan.org>
187 Andy Grundman, <andy@hybridized.org>
191 Many parts are ripped out of C<HTTP::Server::Simple> by Jesse Vincent.
195 This program is free software, you can redistribute it and/or modify it under
196 the same terms as Perl itself.