X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine%2FHTTP%2FRestarter%2FWatcher.pm;h=4095e83e8f4b1c7294e6b57fd233aa85c6b582a9;hb=c03163b837135f3bf3d65380e90b4a68bcc38099;hp=b1ae9b74d6449674460c444173c556d11c6673bc;hpb=7fa2c9c1b85c98786655ad5169708d8dc84e8353;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm b/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm index b1ae9b7..4095e83 100644 --- a/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm +++ b/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm @@ -1,28 +1,34 @@ package Catalyst::Engine::HTTP::Restarter::Watcher; use Moose; +with 'MooseX::Emulate::Class::Accessor::Fast'; + use File::Find; use File::Modified; use File::Spec; use Time::HiRes qw/sleep/; +use Moose::Util qw/find_meta/; +use namespace::clean -except => 'meta'; + +BEGIN { + # If we can detect stash changes, then we do magic + # to make their metaclass mutable (if they have one) + # so that restarting works as expected. + eval { require B::Hooks::OP::Check::StashChange; }; + *DETECT_PACKAGE_COMPILATION = $@ + ? sub () { 0 } + : sub () { 1 } +} 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}; +has follow_symlinks => (is => 'rw'); - bless $self, $class; - - $self->_init; - - return $self; +sub BUILD { + shift->_init; } sub _init { @@ -44,7 +50,7 @@ sub watch { my @changes; my @changed_files; - + my $delay = ( defined $self->delay ) ? $self->delay : 1; sleep $delay if $delay > 0; @@ -130,7 +136,18 @@ sub _index_directory { sub _test { my ( $self, $file ) = @_; - delete $INC{$file}; + my $id; + if (DETECT_PACKAGE_COMPILATION) { + $id = B::Hooks::OP::Check::StashChange::register(sub { + my ($new, $old) = @_; + my $meta = find_meta($new); + if ($meta) { + $meta->make_mutable if $meta->is_immutable; + } + }); + } + + delete $INC{$file}; # Remove from %INC so it will reload local $SIG{__WARN__} = sub { }; open my $olderr, '>&STDERR'; @@ -138,6 +155,8 @@ sub _test { eval "require '$file'"; open STDERR, '>&', $olderr; + B::Hooks::OP::Check::StashChange::unregister($id) if $id; + return ($@) ? $@ : 0; } @@ -153,10 +172,10 @@ files my $watcher = Catalyst::Engine::HTTP::Restarter::Watcher->new( directory => '/path/to/MyApp', - regex => '\.yml$|\.yaml$|\.pm$', + regex => '\.yml$|\.yaml$|\.conf|\.pm$', delay => 1, ); - + while (1) { my @changed_files = $watcher->watch(); } @@ -178,15 +197,24 @@ Creates a new Watcher object. Returns a list of files that have been added, deleted, or changed since the last time watch was called. +=head2 DETECT_PACKAGE_COMPILATION + +Returns true if L is installed and +can be used to detect when files are compiled. This is used internally +to make the L metaclass of any class being reloaded immutable. + +If L is not installed, then the +restarter makes all application components immutable. This covers the +simple case, but is less useful if you're using Moose in components +outside Catalyst's namespaces, but inside your application directory. + =head1 SEE ALSO L, L, L =head1 AUTHORS -Sebastian Riedel, - -Andy Grundman, +Catalyst Contributors, see Catalyst.pm =head1 THANKS