X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FEngine%2FHTTP%2FRestarter%2FWatcher.pm;h=847fb0daadd49fe64af855298d7345a6b7592d30;hp=7a6bd10550611c36cc9817752d6e9439362af944;hb=ac5c933bdd463558e8d621507a53a7b247a9093e;hpb=65586a18685daa023a1a623cf228943e4a4f830d diff --git a/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm b/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm index 7a6bd10..847fb0d 100644 --- a/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm +++ b/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm @@ -1,37 +1,36 @@ package Catalyst::Engine::HTTP::Restarter::Watcher; -use strict; -use warnings; -use base 'Class::Accessor::Fast'; +use Moose; use File::Find; use File::Modified; use File::Spec; use Time::HiRes qw/sleep/; -__PACKAGE__->mk_accessors( qw/delay - directory - modified - regex - watch_list/ ); +has delay => (is => 'rw'); +has regex => (is => 'rw'); +has modified => (is => 'rw'); +has directory => (is => 'rw'); +has watch_list => (is => 'rw'); +has follow_simlinks => (is => 'rw'); sub new { my ( $class, %args ) = @_; - - my $self = { %args }; - + + my $self = {%args}; + bless $self, $class; - + $self->_init; - + return $self; } sub _init { my $self = shift; - + my $watch_list = $self->_index_directory; - $self->watch_list( $watch_list ); - + $self->watch_list($watch_list); + $self->modified( File::Modified->new( method => 'mtime', @@ -42,46 +41,50 @@ sub _init { sub watch { my $self = shift; - + my @changes; my @changed_files; - sleep $self->delay || 1; - + my $delay = ( defined $self->delay ) ? $self->delay : 1; + + sleep $delay if $delay > 0; + eval { @changes = $self->modified->changed }; - if ( $@ ) { + if ($@) { + # File::Modified will die if a file is deleted. my ($deleted_file) = $@ =~ /stat '(.+)'/; push @changed_files, $deleted_file || 'unknown file'; } - - if ( @changes ) { + + if (@changes) { + # update all mtime information $self->modified->update; - + # check if any files were changed @changed_files = grep { -f $_ } @changes; - + # Check if only directories were changed. This means # a new file was created. - unless ( @changed_files ) { + unless (@changed_files) { + # re-index to find new files my $new_watch = $self->_index_directory; - + # look through the new list for new files my $old_watch = $self->watch_list; - @changed_files = grep { ! defined $old_watch->{$_} } - keys %{ $new_watch }; - + @changed_files = grep { !defined $old_watch->{$_} } + keys %{$new_watch}; + return unless @changed_files; } # Test modified pm's - for my $file ( @changed_files ) { + for my $file (@changed_files) { next unless $file =~ /\.pm$/; if ( my $error = $self->_test($file) ) { - print STDERR - qq/File "$file" modified, not restarting\n\n/; + print STDERR qq/File "$file" modified, not restarting\n\n/; print STDERR '*' x 80, "\n"; print STDERR $error; print STDERR '*' x 80, "\n"; @@ -89,17 +92,19 @@ sub watch { } } } - + return @changed_files; } sub _index_directory { my $self = shift; - - my $dir = $self->directory || die "No directory specified"; - my $regex = $self->regex || '\.pm$'; + + my $dir = $self->directory; + die "No directory specified" if !$dir or ref($dir) && !@{$dir}; + + my $regex = $self->regex || '\.pm$'; my %list; - + finddepth( { wanted => sub { @@ -108,32 +113,33 @@ sub _index_directory { return unless -f $file; $file =~ s{/script/..}{}; $list{$file} = 1; - + # also watch the directory for changes my $cur_dir = File::Spec->rel2abs($File::Find::dir); - $cur_dir =~ s{/script/..}{}; + $cur_dir =~ s{/script/..}{}; $list{$cur_dir} = 1; }, + follow_fast => $self->follow_symlinks ? 1 : 0, no_chdir => 1 }, - $dir + ref $dir eq 'ARRAY' ? @{$dir} : $dir ); return \%list; } sub _test { my ( $self, $file ) = @_; - + delete $INC{$file}; local $SIG{__WARN__} = sub { }; - + open my $olderr, '>&STDERR'; open STDERR, '>', File::Spec->devnull; eval "require '$file'"; open STDERR, '>&', $olderr; - + return ($@) ? $@ : 0; -} +} 1; __END__