File Coverage

blib/lib/Directory/Deploy/Manifest.pm
Criterion Covered Total %
statement 66 86 76.7
branch 13 32 40.6
condition 4 12 33.3
subroutine 13 17 76.4
pod 0 10 0.0
total 96 157 61.1


line stmt bran cond sub pod time code
1             package Directory::Deploy::Manifest;
2              
3 4     4   23 use Moose;
  4         9  
  4         45  
4              
5 4     4   28721 use Directory::Deploy::Carp;
  4         56  
  4         38  
6              
7 4     4   5232 use Path::Abstract;
  4         91346  
  4         33  
8 4     4   927 use Scalar::Util qw/looks_like_number/;
  4         9  
  4         3790  
9              
10             has _entry_map => qw/is ro required 1/, default => sub { {} };
11              
12             sub normalize_path {
13 8     8 0 11 my $self = shift;
14 8         12 my $path = shift;
15              
16 8 50       18 croak "Wasn't given a path" unless defined $path;
17              
18 8         56 $path = Path::Abstract->new( $path );
19 8         406 s/^\///, s/\/$// for $$path;
20 8         24 return $path;
21             }
22              
23             sub _enter {
24 4     4   5 my $self = shift;
25 4         5 my $entry = shift;
26 4         152 $self->_entry_map->{$entry->path} = $entry;
27 4         25 return $entry;
28             }
29              
30             has include_parser => qw/is ro required 1 isa CodeRef/, default => sub { sub {
31             my $self = shift;
32             chomp;
33             return if m/^\s*$/ || m/^\s*#/;
34             my ($path, $content_source) = m/^\s*(\S+)(?:\s*(.*)\s*)?$/;
35             s/^\s*//, s/\s*$// for $path;
36             $self->add( path => $path, content_source => $content_source );
37             } };
38             sub include {
39 0     0 0 0 my $self = shift;
40 0 0 0     0 if (1 == @_ || ref $_[0] eq 'SCALAR') {
41 0         0 my $parse = shift;
42 0 0       0 croak "More than one argument passed to include" if @_;
43 0         0 my $parser = $self->include_parser;
44 0 0       0 $parse = $$parse if ref $_[0] eq 'SCALAR';
45 0         0 $parser->( $self, $_ ) for split m/\n/, $parse;
46             }
47             else {
48 0         0 while (@_) {
49 0         0 my $path = shift;
50 0         0 my $value = shift;
51 0 0       0 $self->add( $path => (ref $value eq 'HASH' ? %$value : $value) );
52             }
53             }
54             }
55              
56             sub add {
57 4     4 0 295 my $self = shift;
58 4         5 my %entry;
59 4 100 66     44 if (1 == @_) {
    100 33        
    50          
60 2         6 $entry{path} = shift;
61             }
62             elsif (2 == @_ && $_[0] && $_[0] ne 'path') {
63 1         3 $entry{path} = shift;
64 1         2 my $source_or_content = shift;
65 1 50       5 if (ref $source_or_content eq 'SCALAR') {
    0          
66 1         2 $entry{content} = $source_or_content;
67             }
68             elsif (! ref $source_or_content) {
69 0         0 $entry{content_source} = $source_or_content;
70             }
71             else {
72 0         0 confess "Huh, don't know what $source_or_content is";
73             }
74             }
75             elsif (@_ % 2) {
76 1         4 $entry{path} = shift;
77             }
78              
79 4         38 my $entry = Directory::Deploy::Manifest::Entry->new( %entry, @_ );
80 4         41 $self->_enter( $entry );
81 4         13 return $entry;
82             }
83              
84             sub lookup {
85 4     4 0 8 my $self = shift;
86 4         6 my $path = shift;
87              
88 4 50       10 croak "Wasn't given a path" unless defined $path;
89              
90 4         9 $path = $self->normalize_path( $path );
91              
92 4         163 return $self->_entry_map->{$path};
93             }
94              
95             sub entry {
96 0     0 0 0 return shift->lookup( @_ );
97             }
98              
99             sub each {
100 1     1 0 2 my $self = shift;
101 1         2 my $code = shift;
102              
103 1         2 for (sort keys %{ $self->_entry_map }) {
  1         39  
104 4         13 $code->( $self->lookup( $_ ), @_ );
105             }
106             }
107              
108             package Directory::Deploy::Manifest::Entry;
109              
110 4     4   27 use Moose;
  4         7  
  4         41  
111              
112 4     4   45409 use Directory::Deploy::Carp;
  4         27  
  4         39  
113              
114             has is_file => qw/is rw/;
115 0     0 0 0 sub is_dir { return ! shift->is_file }
116             has mode => qw/is rw isa Maybe[Int]/;
117             has path => qw/is ro required 1/;
118             has comment => qw/is rw isa Maybe[Str]/;
119             has content => qw/is rw/;
120             has content_source => qw/is rw/;
121              
122             sub path_like_file {
123 0     0 0 0 my $self = shift; # Probably $class
124 0         0 my $path = shift;
125              
126 0         0 my $trailing_slash = $path =~ m/\/(?::\d+)?$/; # Optional octal mode at the end
127              
128 0         0 return ! $trailing_slash;
129             }
130              
131             sub parse_path {
132 4     4 0 6 my $self = shift; # Probably $class
133 4         6 my $path = shift;
134              
135 4 50 33     23 croak "Wasn't given a path to parse" unless defined $path && length $path;
136              
137 4         5 my $mode;
138 4 50       14 $mode = oct $1 if $path =~ s/:(\d+)$//;
139            
140 4         5 my $is_file;
141 4         13 $is_file = ! ($path =~ s{/+$}{}); # Trailing slash(es) is a directory indicator
142              
143             return (
144 4         13 Directory::Deploy::Manifest->normalize_path( $path ),
145             $is_file,
146             $mode,
147             );
148             }
149              
150             sub BUILD {
151 4     4 0 4855 my $self = shift;
152 4         7 my $given = shift;
153              
154 4         158 my ($path, $is_file, $mode) = $self->parse_path( $self->path );
155              
156 4 50       18 if ($given->{is_dir}) {
    50          
157 0         0 $self->is_file( 0 );
158             }
159             elsif ($given->{is_file}) {
160             }
161             else {
162 4         161 $self->is_file( $is_file );
163             }
164              
165 4 50       11 unless (defined $given->{mode}) {
166 4         157 $self->mode( $mode );
167             }
168              
169 4         24 $self->{path} = $path;
170             }
171              
172             1;
173              
174             __END__
175             #sub add {
176             # my $self = shift;
177             # my $kind = shift;
178             # croak "You didn't specify a kind" unless defined $kind;
179             #
180             # if ($kind eq 'file') {
181             # $self->file( @_ );
182             # }
183             # elsif ($kind eq 'dir') {
184             # $self->dir( @_ );
185             # }
186             # else {
187             # croak "Don't understand kind $kind";
188             # }
189             #}
190              
191             #sub file {
192             # my $self = shift;
193             # my %entry;
194             # if (1 == @_) {
195             # $entry{path} = shift;
196             # }
197             # elsif (2 == @_ && ref $_[1] eq 'SCALAR') {
198             # $entry{path} = shift;
199             # $entry{content} = shift;
200             # }
201             # elsif (3 == @_) {
202             # $entry{path} = shift;
203             # if (ref $_[0] eq 'SCALAR' && $_[1] =~ m/^\d+$/) {
204             # $entry{content} = shift;
205             # $entry{mode} = shift;
206             # }
207             # elsif (ref $_[1] eq 'SCALAR' && $_[0] =~ m/^\d+$/) {
208             # $entry{mode} = shift;
209             # $entry{content} = shift;
210             # }
211             # }
212             # elsif (@_ % 2) {
213             # $entry{path} = shift;
214             # }
215              
216             # my $entry = Directory::Deploy::Manifest::Entry->new( %entry, @_ );
217             # $self->_enter( $entry );
218             # return $entry;
219             #}
220              
221             #sub dir {
222             # my $self = shift;
223             # my %entry;
224             # if (1 == @_) {
225             # $entry{path} = shift;
226             # }
227             # elsif (@_ % 2) {
228             # $entry{path} = shift;
229             # }
230              
231             # my $entry = Directory::Deploy::Manifest::Dir->new( %entry, @_ );
232             # $self->_enter( $entry );
233             # return $entry;
234             #}
235              
236             #has _entry_list => qw/is ro required 1/, default => sub { {} };
237              
238             #sub _entry {
239             # my $self = shift;
240             # return $_[0] if @_ == 1 && blessed $_[0];
241             # return Directory::Deploy::Manifest::Om::Manifest::Entry->new(@_);
242             #}
243              
244             #sub entry_list {
245             # return shift->_entry_list;
246             #}
247              
248             #sub entry {
249             # my $self = shift;
250             # return $self->_entry_list unless @_;
251             # my $path = shift;
252             # return $self->_entry_list->{$path};
253             #}
254              
255             #sub all {
256             # my $self = shift;
257             # return sort { $a cmp $b } keys %{ $self->_entry_list };
258             #}
259              
260             #sub add {
261             # my $self = shift;
262             # my $entry = $self->_entry(@_);
263             # $self->_entry_list->{$entry->path} = $entry;
264             #}
265              
266             #sub each {
267             # my $self = shift;
268             # my $code = shift;
269              
270             # for (sort keys %{ $self->_entry_list }) {
271             # $code->($self->entry->{$_})
272             # }
273             #}
274              
275             #sub include {
276             # my $self = shift;
277              
278             # while (@_) {
279             # local $_ = shift;
280             # if ($_ =~ m/\n/) {
281             # $self->_include_list($_);
282             # }
283             # else {
284             # my $path = $_;
285             # my %entry;
286             # %entry = %{ shift() } if ref $_[0] eq 'HASH';
287             # # FIXME Should we do it this way?
288             # my $comment = delete $entry{comment};
289             # $self->add(path => $_, comment => $comment, stash => { %entry });
290             # }
291             # }
292             #}
293              
294             #sub _include_list {
295             # my $self = shift;
296             # my $list = shift;
297              
298             # for (split m/\n/, $list) {
299             # $self->parser->($self);
300             # }
301             #}
302              
303              
304             package Directory::Deploy::Manifest::File;
305              
306             use Moose;
307              
308             with qw/Directory::Deploy::Manifest::DoesEntry/;
309              
310             sub is_file { 1 }
311              
312             package Directory::Deploy::Manifest::Dir;
313              
314             use Moose;
315              
316             with qw/Directory::Deploy::Manifest::DoesEntry/;
317              
318             sub is_file { 0 }
319              
320             1;
321              
322             __END__
323              
324             use Moose;
325              
326             has comment => qw/is ro isa Maybe[Str]/;
327             has stash => qw/is ro required 1 isa HashRef/, default => sub { {} };
328             has process => qw/is rw isa Maybe[Str|HashRef]/;
329              
330             sub content {
331             return shift->stash->{content};
332             }
333              
334             sub copy_into {
335             my $self = shift;
336             my $hash = shift;
337             while (my ($key, $value) = each %{ $self->stash }) {
338             $hash->{$key} = $value;
339             }
340             }
341              
342             1;