File Coverage

lib/Dist/Zilla/Tempdir/Dir.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1 1     1   1008 use 5.008; # utf8
  1         3  
  1         35  
2 1     1   4 use strict;
  1         2  
  1         35  
3 1     1   7 use warnings;
  1         2  
  1         29  
4 1     1   943 use utf8;
  1         12  
  1         8  
5              
6             package Dist::Zilla::Tempdir::Dir;
7              
8             our $VERSION = '1.001001';
9              
10             # ABSTRACT: A temporary directory with a collection of item states
11              
12             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
13              
14              
15              
16              
17              
18              
19              
20              
21              
22              
23              
24              
25              
26 1     1   464 use Moose qw( has );
  0            
  0            
27             use Carp qw( croak );
28             use File::chdir;
29             use Dist::Zilla::Tempdir::Item::State;
30             use Dist::Zilla::Tempdir::Item;
31             use Path::Iterator::Rule;
32             use Dist::Zilla::File::InMemory;
33             use Path::Tiny qw(path);
34              
35             has '_tempdir' => (
36             is => ro =>,
37             lazy_build => 1,
38             );
39              
40             has '_tempdir_owner' => (
41             is => ro =>,
42             predicate => '_has_tempdir_owner',
43             );
44              
45             sub _build__tempdir {
46             my ($self) = @_;
47              
48             my $template = 'DZ_R_Tempdir_';
49             if ( $self->_has_tempdir_owner ) {
50             my $owner = $self->_tempdir_owner;
51             $owner =~ s/[^[:alpha:]\d]+/_/xmsg;
52             $template .= $owner . '_';
53             }
54             $template .= 'XXXXXX';
55             return Path::Tiny->tempdir( TEMPLATE => $template );
56             }
57              
58             has '_input_files' => (
59             isa => 'HashRef',
60             traits => [qw( Hash )],
61             is => ro =>,
62             lazy => 1,
63             default => sub { {} },
64             handles => {
65             '_set_input_file' => 'set',
66             '_all_input_files' => 'values',
67             '_has_input_file' => 'exists',
68             },
69             );
70              
71              
72              
73              
74              
75              
76              
77             has '_output_files' => (
78             isa => 'HashRef',
79             traits => [qw( Hash )],
80             is => ro =>,
81             lazy => 1,
82             default => sub { {} },
83             handles => {
84             '_set_output_file' => 'set',
85             'files' => 'values',
86             },
87             );
88              
89              
90              
91              
92              
93              
94              
95              
96              
97              
98             sub add_file {
99             my ( $self, $file ) = @_;
100             my $state = Dist::Zilla::Tempdir::Item::State->new(
101             file => $file,
102             storage_prefix => $self->_tempdir,
103             );
104             $state->write_out;
105             $self->_set_input_file( $file->name, $state );
106             return;
107             }
108              
109              
110              
111              
112              
113              
114              
115              
116              
117              
118             sub update_input_file {
119             my ( $self, $file ) = @_;
120              
121             my $update_item = Dist::Zilla::Tempdir::Item->new( name => $file->name, file => $file->file, );
122             $update_item->set_original;
123              
124             if ( not $file->on_disk ) {
125             $update_item->set_deleted;
126             }
127             elsif ( $file->on_disk_changed ) {
128             $update_item->set_modified;
129             my %params = ( name => $file->name, content => $file->new_content );
130             if ( Dist::Zilla::File::InMemory->can('encoded_content') ) {
131             $params{encoded_content} = delete $params{content};
132             }
133             $update_item->file( Dist::Zilla::File::InMemory->new(%params) );
134             }
135             $self->_set_output_file( $file->name, $update_item );
136             return;
137             }
138              
139              
140              
141              
142              
143              
144              
145              
146              
147             sub update_disk_file {
148             my ( $self, $fullname ) = @_;
149             my $fullpath = path($fullname);
150             my $shortname = $fullpath->relative( $self->_tempdir );
151              
152             my %params = ( name => "$shortname", content => $fullpath->slurp_raw );
153             if ( Dist::Zilla::File::InMemory->can('encoded_content') ) {
154             $params{encoded_content} = delete $params{content};
155             }
156             my $item = Dist::Zilla::Tempdir::Item->new(
157             name => "$shortname",
158             file => Dist::Zilla::File::InMemory->new(%params),
159             );
160             $item->set_new;
161             $self->_set_output_file( "$shortname", $item );
162             return;
163             }
164              
165              
166              
167              
168              
169              
170              
171              
172              
173             sub update_input_files {
174             my ($self) = @_;
175             for my $file ( $self->_all_input_files ) {
176             $self->update_input_file($file);
177             }
178             return;
179             }
180              
181              
182              
183              
184              
185              
186              
187              
188              
189              
190             sub update_disk_files {
191             my ($self) = @_;
192             for my $filename ( Path::Iterator::Rule->new->file->all( $self->_tempdir->stringify ) ) {
193             next if $self->_has_input_file( path($filename)->relative( $self->_tempdir ) );
194             $self->update_disk_file($filename);
195             }
196             return;
197             }
198              
199              
200              
201              
202              
203              
204              
205              
206              
207              
208              
209             sub run_in {
210             my ( $self, $code ) = @_;
211             ## no critic ( ProhibitLocalVars )
212             local $CWD = $self->_tempdir->stringify;
213             return $code->($self);
214             }
215              
216              
217              
218              
219              
220              
221              
222              
223              
224              
225              
226              
227              
228              
229              
230              
231              
232             sub keepalive {
233             my $nargs = my ( $self, $keep ) = @_;
234              
235             my $path = $self->_tempdir;
236              
237             if ( $nargs < 2 ) {
238             return $path;
239             }
240              
241             if ($keep) {
242             $path->[Path::Tiny::TEMP]->unlink_on_destroy(0);
243             }
244             else {
245             $path->[Path::Tiny::TEMP]->unlink_on_destroy(1);
246             }
247             return $path;
248             }
249              
250              
251              
252              
253              
254              
255              
256              
257              
258              
259              
260             sub keepalive_fail {
261             my ( $self, $message ) = @_;
262              
263             if ( not $message ) {
264             $message = q[];
265             }
266             else {
267             $message .= qq[\n];
268             }
269             $message .= q[Role::Tempdir's scratch directory preserved at ] . $self->keepalive(1);
270             croak $message;
271             }
272              
273             no Moose;
274             __PACKAGE__->meta->make_immutable;
275              
276             1;
277              
278             __END__
279              
280             =pod
281              
282             =encoding UTF-8
283              
284             =head1 NAME
285              
286             Dist::Zilla::Tempdir::Dir - A temporary directory with a collection of item states
287              
288             =head1 VERSION
289              
290             version 1.001001
291              
292             =head1 SYNOPSIS
293              
294             my $dir = Dist::Zilla::Tempdir::Dir->new();
295             $dir->add_file( $zilla_file );
296             $dir->run_in(sub { });
297             $dir->update_input_files;
298             $dir->update_disk_files;
299              
300             my @file_states = $dir->files();
301              
302             =head1 METHODS
303              
304             =head2 C<files>
305              
306             Returns a list of L<< C<Dist::Zilla::Tempdir::Item>|Dist::Zilla::Tempdir::Item >>
307              
308             =head2 C<add_file>
309              
310             $dir->add_file( $dzil_file );
311              
312             Adds C<$dzil_file> to the named temporary directory, written out to disk, and records
313             it internally as an "original" file.
314              
315             =head2 C<update_input_file>
316              
317             $dir->update_input_file( $dzil_file );
318              
319             Refreshes the C<$dzil_file> from its written out context, determining if that file has been changed since
320             addition or not, recording the relevant data for C<< ->files >>
321              
322             =head2 C<update_disk_file>
323              
324             $dir->update_disk_file( $disk_path );
325              
326             Assume C<$disk_path> is a path of a B<NEW> file and record it in C<< ->files >>
327              
328             =head2 C<update_input_files>
329              
330             $dir->update_input_files
331              
332             Refresh the state of all written out files and record them ready for C<< ->files >>
333              
334             =head2 C<update_disk_files>
335              
336             $dir->update_disk_files
337              
338             Scan the temporary directory for files that weren't added as an C<input> file, and record their status
339             and information ready for C<< ->files >>
340              
341             =head2 C<run_in>
342              
343             my $rval = $dir->run_in(sub {
344             return 1;
345             });
346              
347             Enter the temporary directory and run the passed code block, which is assumed to be creating/modifying/deleting files.
348              
349             =head2 C<keepalive>
350              
351             Utility method: Marks the temporary directory for preservation.
352              
353             $dir->keepalive() # simply returns the path to the tempdir
354             $dir->keepalive(1) # mark for retention
355             $dir->keepalive(0) # mark for erasure
356              
357             This is mostly an insane glue layer for
358              
359             $dir->_tempdir->[Path::Tiny::TEMP]->unlink_on_destroy($x)
360              
361             Except the insanity of poking too many internal guts is well encapsulated.
362              
363             =head2 C<keepalive_fail>
364              
365             A utility method to invoke a croak (heh) that preserves the scratch directory, and tells
366             the croak recipient where to find it.
367              
368             $dir->keepalive_fail();
369             $dir->keepalive_fail("Some Diagnostic Reason");
370              
371             =head1 AUTHOR
372              
373             Kent Fredric <kentnl@cpan.org>
374              
375             =head1 COPYRIGHT AND LICENSE
376              
377             This software is copyright (c) 2014 by Kent Fredric.
378              
379             This is free software; you can redistribute it and/or modify it under
380             the same terms as the Perl 5 programming language system itself.
381              
382             =cut