File Coverage

blib/lib/File/Dir/Map.pm
Criterion Covered Total %
statement 18 51 35.2
branch 0 12 0.0
condition n/a
subroutine 6 9 66.6
pod 1 2 50.0
total 25 74 33.7


line stmt bran cond sub pod time code
1             package File::Dir::Map;
2 1     1   23288 use common::sense;
  1         10  
  1         5  
3 1     1   922 use File::Copy;
  1         5055  
  1         81  
4 1     1   9 use File::Find;
  1         6  
  1         68  
5 1     1   7 use File::Path qw(make_path remove_tree);
  1         2  
  1         69  
6 1     1   8191 use English '-no_match_vars';
  1         10784  
  1         11  
7 1     1   874 use base qw(Exporter);
  1         3  
  1         1653  
8              
9             our @EXPORT_OK = qw(dirmap);
10              
11             =head1 NAME
12              
13             File::Dir::Map - Map a directory recursively
14              
15             =head1 VERSION
16              
17             Version 0.01
18              
19             =cut
20              
21             our $VERSION = '0.02';
22              
23             =head1 SYNOPSIS
24              
25             The following snippet summarizes what File::Dir::Map does.
26              
27             Files are copied from src to build dirs such that files
28             with extension ignore will not be copied, files with extension
29             markdown will get processed by markdown and saved in build dir,
30             and files with extension raw are guaranteed to be copied without
31             processing but stripped of the raw extension.
32              
33             use File::Dir::Map qw(dirmap);
34             use Text::MultiMarkdown qw(markdown);
35            
36             dirmap src => build => {
37             ignore => sub{ [] },
38             raw => sub{
39             my( $name, $content ) = @_;
40             [ $name, $content ];
41             },
42             markrown => sub{
43             my( $name, $contnet ) = @_;
44             [ "$name.html", markdown $content ]
45             },
46             };
47              
48             So this before the map:
49              
50             src/pages/todo.ignore
51             src/pages/index.markdown
52             src/pages/about.html
53             src/pages/index.markdown.raw
54             src/files/
55             build/some/junk/here.txt
56              
57             Will be this after the map:
58              
59             src/pages/todo.ignore
60             src/pages/index.markdown
61             src/pages/about.html
62             src/pages/index.markdown.raw
63             src/files/
64             build/pages/index.html
65             build/pages/about.html
66             build/pages/index.markdown
67             build/files/
68              
69             Note that old build directory is purged!
70              
71             =head1 EXPORT
72              
73             dirmap
74              
75             =head1 SUBROUTINES/METHODS
76              
77             =cut
78              
79             sub inventory ($$) {
80 0     0 0   my ( $dir, $familiar ) = @_;
81 0           my $inv;
82             find(
83             sub {
84 0     0     $File::Find::name =~ m{^$dir/(.*?)(?:\.(.*?))?$};
85 0 0         if (-d) {
  0 0          
86 0 0         push @{ $inv->{dirs} }, $1 if $1;
  0            
87             }
88             elsif ( grep { $_ eq $2 } @$familiar ) {
89 0           $inv->{items}->{$1}->{$2} = $File::Find::name;
90             }
91             else {
92 0 0         $inv->{files}->{ $1 . ( $2 ? ".$2" : '' ) } = $File::Find::name;
93             }
94             },
95 0           $dir
96             );
97 0           $inv;
98             }
99              
100             =head2 dirmap $dir_from, $dir_to, $funcs
101              
102             $funcs is a hashref with file extensions as keys and mapping functions as
103             values.
104              
105             Each mapping function takes two arguments: filename stripped of the extension
106             and file contents.
107              
108             Each mapping function should return a listref that's either empty or contains
109             two elements: new filename and new content. In case the listref is empty,
110             file will not be saved in the destination directory.
111              
112             =cut
113              
114             sub dirmap ($$$) {
115 0     0 1   my ( $dir_from, $dir_to, $funcs ) = @_;
116 0           my $inv = inventory $dir_from => [ keys %$funcs ];
117 0           remove_tree( $dir_to, { keep_root => 1, safe => 1 } );
118 0           make_path( map { join '/', $dir_to, $_ } sort @{ $inv->{dirs} } );
  0            
  0            
119 0           copy( $inv->{files}->{$_}, join '/', $dir_to, $_ )
120 0           for keys %{ $inv->{files} };
121              
122 0           for my $item ( keys %{ $inv->{items} } ) {
  0            
123 0           for my $type ( keys %{ $inv->{items}->{$item} } ) {
  0            
124 0           open my $fh, '<', $inv->{items}->{$item}->{$type};
125 0           local $INPUT_RECORD_SEPARATOR = undef;
126 0           my $content_in = <$fh>;
127 0           close $fh;
128              
129 0           my ( $filename, $content_out ) =
130 0           @{ $funcs->{$type}->( $item, $content_in ) };
131              
132 0 0         if ($filename) {
133 0 0         open my $fh, '>', join '/', $dir_to, $filename or die $ERRNO;
134 0           print $fh $content_out;
135 0           close $fh;
136             }
137             }
138             }
139             }
140              
141             =head1 AUTHOR
142              
143             Eugene Grigoriev, C<< >>
144              
145             =head1 BUGS
146              
147             Please report any bugs or feature requests to C, or through
148             the web interface at L. I will be notified, and then you'll
149             automatically be notified of progress on your bug as I make changes.
150              
151             =head1 SUPPORT
152              
153             You can find documentation for this module with the perldoc command.
154              
155             perldoc File::Dir::Map
156              
157              
158             You can also look for information at:
159              
160             =over 4
161              
162             =item * RT: CPAN's request tracker
163              
164             L
165              
166             =item * AnnoCPAN: Annotated CPAN documentation
167              
168             L
169              
170             =item * CPAN Ratings
171              
172             L
173              
174             =item * Search CPAN
175              
176             L
177              
178             =back
179              
180              
181             =head1 ACKNOWLEDGEMENTS
182              
183              
184             =head1 LICENSE AND COPYRIGHT
185              
186             Copyright 2010 Eugene Grigoriev.
187              
188             This program is free software; you can redistribute it and/or modify it
189             under the terms of either: the GNU General Public License as published
190             by the Free Software Foundation; or the Artistic License.
191              
192             See http://dev.perl.org/licenses/ for more information.
193              
194             =cut
195              
196             1; # End of File::Dir::Map