1 package Catalyst::Watcher;
4 use Moose::Util::TypeConstraints;
9 use Time::HiRes qw/sleep/;
10 use namespace::clean -except => 'meta';
21 default => sub { qr/(?:\/|^)(?!\.\#).+(?:\.yml$|\.yaml$|\.conf|\.pm)$/ },
27 => message { "$_ is not a valid directory" };
29 my $array_of_dirs = subtype
31 => where { map { -d } @{$_} }
32 => message { "@{$_} is not a list of valid directories" };
40 isa => $array_of_dirs,
41 default => sub { [ File::Spec->rel2abs( File::Spec->catdir( $FindBin::Bin, '..' ) ) ] },
45 has follow_symlinks => (
51 has _watched_files => (
53 isa => 'HashRef[Str]',
55 clearer => '_clear_watched_files',
60 isa => 'File::Modified',
64 sub _build__watched_files {
67 my $regex = $self->regex;
73 my $file = File::Spec->rel2abs($File::Find::name);
74 return unless $file =~ /$regex/;
75 return unless -f $file;
79 # also watch the directory for changes
80 my $cur_dir = File::Spec->rel2abs($File::Find::dir);
81 $cur_dir =~ s{/script/..}{};
84 follow_fast => $self->follow_symlinks ? 1 : 0,
93 sub _build__modified {
96 return File::Modified->new(
98 files => [ keys %{ $self->_watched_files } ],
102 sub find_changed_files {
108 sleep $self->interval if $self->interval > 0;
110 eval { @changes = $self->_modified->changed };
112 # File::Modified will die if a file is deleted.
113 my ($deleted_file) = $@ =~ /stat '(.+)'/;
116 file => $deleted_file || 'unknown file',
122 $self->_modified->update;
124 @changed_files = map { { file => $_, status => 'modified' } }
125 grep { -f $_ } @changes;
127 # We also need to check to see if a new directory was created
128 unless (@changed_files) {
129 my $old_watch = $self->_watched_files;
131 $self->_clear_watched_files;
133 my $new_watch = $self->_watched_files;
136 = map { { file => $_, status => 'added' } }
137 grep { !defined $old_watch->{$_} }
140 return unless @changed_files;
144 return @changed_files;
147 __PACKAGE__->meta->make_immutable;
155 Catalyst::Watcher - Watch for changed application files
159 my $watcher = Catalyst::Watcher->new(
160 directory => '/path/to/MyApp',
161 regex => '\.yml$|\.yaml$|\.conf|\.pm$',
166 my @changed_files = $watcher->watch();
171 This class monitors a directory of files for changes made to any file
172 matching a regular expression. It correctly handles new files added to the
173 application as well as files that are deleted.
177 =head2 new ( directory => $path [, regex => $regex, delay => $delay ] )
179 Creates a new Watcher object.
181 =head2 find_changed_files
183 Returns a list of files that have been added, deleted, or changed
184 since the last time watch was called. Each element returned is a hash
185 reference with two keys. The C<file> key contains the filename, and
186 the C<status> key contains one of "modified", "added", or "deleted".
190 L<Catalyst>, L<Catalyst::Restarter>, <File::Modified>
194 Catalyst Contributors, see Catalyst.pm
198 This program is free software, you can redistribute it and/or modify
199 it under the same terms as Perl itself.