File Coverage

blib/lib/File/Monitor.pm
Criterion Covered Total %
statement 67 77 87.0
branch 13 22 59.0
condition 5 11 45.4
subroutine 15 16 93.7
pod 5 5 100.0
total 105 131 80.1


line stmt bran cond sub pod time code
1             package File::Monitor;
2              
3 6     6   151465 use warnings;
  6         12  
  6         191  
4 6     6   30 use strict;
  6         12  
  6         220  
5 6     6   31 use Carp;
  6         17  
  6         521  
6              
7 6     6   42 use base qw(File::Monitor::Base);
  6         20  
  6         4310  
8              
9 6     6   4096 use File::Monitor::Object;
  6         20  
  6         358  
10              
11 6     6   146 use vars qw( $VERSION );
  6         11  
  6         5153  
12             $VERSION = '1.00';
13              
14             sub _initialize {
15 8     8   18 my $self = shift;
16 8   100     69 my $args = shift || {};
17              
18 8         73 $self->SUPER::_initialize( $args );
19 8         54 $self->_install_callbacks( $args );
20              
21 8 100       35 if ( my $base = delete $args->{base} ) {
22 3         18 $self->base( $base );
23             }
24              
25 8         91 $self->_report_extra( $args );
26              
27 8         56 $self->{_monitors} = {};
28             }
29              
30             sub has_monitors {
31 3     3 1 6 my $self = shift;
32 3 50 33     17 return 1 if exists $self->{_monitors} && %{ $self->{_monitors} };
  0         0  
33 3         20 return;
34             }
35              
36             sub base {
37 1202     1202 1 28945 my $self = shift;
38 1202         1856 my $cur_base = $self->{_base};
39 1202 100       5193 return $cur_base unless @_;
40 13 50       42 my $new_base = shift or croak "Can't unset base directory";
41              
42 13 50 66     73 if ( !defined $cur_base && $self->has_monitors ) {
43 0         0 croak "Can't make a non-empty absolute "
44             . __PACKAGE__
45             . " relative";
46             }
47              
48 13         202 $self->{_base}
49             = File::Spec->canonpath( File::Spec->rel2abs( $new_base ) );
50             }
51              
52             sub _set_watcher {
53 22     22   34 my $self = shift;
54 22         24 my $object = shift;
55              
56 22         307 my $name = $self->_make_relative( $object->name );
57 22         116 return $self->{_monitors}->{$name} = $object;
58             }
59              
60             sub watch {
61 22     22 1 1383 my $self = shift;
62              
63 22         29 my $args;
64              
65 22 50       60 if ( ref $_[0] eq 'HASH' ) {
66              
67             # Hash ref containing all arguments
68 22         34 $args = shift;
69              
70 22 50       53 croak "When options are supplied as a hash "
71             . "there may be no other arguments"
72             if @_;
73             }
74             else {
75              
76             # File/dir name, optional callback
77 0 0       0 my $name = shift or croak "A filename must be specified";
78 0         0 my $callback = shift;
79              
80 0         0 $args = { name => $name };
81              
82             # If a callback is defined install it for all changes
83 0 0       0 $args->{callback}->{change} = $callback
84             if defined $callback;
85             }
86              
87 22         41 $args->{owner} = $self;
88              
89 22         159 return $self->_set_watcher( File::Monitor::Object->new( $args ) );
90             }
91              
92             sub unwatch {
93 0     0 1 0 my $self = shift;
94 0   0     0 my $name = shift || croak "A filename must be specified";
95              
96 0         0 $name = $self->_make_relative( $self->_canonical_name( $name ) );
97 0         0 delete $self->{_monitors}->{$name};
98             }
99              
100             sub scan {
101 46     46 1 22725 my $self = shift;
102 46         106 my @changed = ();
103              
104 46         98 for my $obj ( values %{ $self->{_monitors} } ) {
  46         294  
105 352         1057 push @changed, $obj->scan;
106             }
107              
108 46         127 for my $change ( @changed ) {
109 42         136 $self->_make_callbacks( $change );
110             }
111              
112 46         529 return @changed;
113             }
114              
115             sub _canonical_name {
116 26     26   40 my $self = shift;
117 26         45 my $name = shift;
118 26         525 return $self->_make_relative(
119             File::Spec->canonpath( File::Spec->rel2abs( $name ) ) );
120             }
121              
122             # Make a filename (relative or absolute) relative to the base
123             # directory if any.
124             sub _make_relative {
125 238     238   328 my $self = shift;
126 238         345 my $name = shift;
127              
128 238 100       489 if ( my $base = $self->base ) {
129 162         11440 return File::Spec->abs2rel( $name, $base );
130             }
131              
132 76         339 return $name;
133             }
134              
135             # Make a filename relative to the base directory absolute.
136             sub _make_absolute {
137 941     941   1305 my $self = shift;
138 941         1405 my $name = shift;
139              
140 941 100       1807 if ( my $base = $self->base ) {
141 518         10500 return File::Spec->rel2abs( $name, $base );
142             }
143              
144 423         1232 return $name;
145             }
146              
147             1;
148             __END__