File Coverage

blib/lib/Dist/Zilla/Tester.pm
Criterion Covered Total %
statement 93 111 83.7
branch 2 8 25.0
condition n/a
subroutine 31 36 86.1
pod 1 12 8.3
total 127 167 76.0


line stmt bran cond sub pod time code
1             package Dist::Zilla::Tester 6.029;
2             # ABSTRACT: a testing-enabling stand-in for Dist::Zilla
3              
4 49     49   129044 use Moose;
  49         18541347  
  49         391  
5             extends 'Dist::Zilla::Dist::Builder';
6              
7 49     49   383417 use Dist::Zilla::Pragmas;
  49         213  
  49         489  
8              
9 49     49   25824 use autodie;
  49         560845  
  49         357  
10 49     49   378634 use Dist::Zilla::Chrome::Test;
  49         249  
  49         2649  
11 49     49   29175 use File::pushd ();
  49         932750  
  49         1475  
12 49     49   402 use File::Spec;
  49         143  
  49         997  
13 49     49   279 use File::Temp;
  49         123  
  49         4581  
14 49     49   23037 use Dist::Zilla::Path;
  49         203  
  49         247  
15              
16 49     49   18433 use Sub::Exporter::Util ();
  49         115  
  49         5186  
17             use Sub::Exporter -setup => {
18             exports => [
19 1         330 Builder => sub { $_[0]->can('builder') },
20 1         31 Minter => sub { $_[0]->can('minter') },
21 49         506 ],
22              
23             groups => [ default => [ qw(Builder Minter) ] ],
24 49     49   303 };
  49         117  
25              
26 49     49   26587 use namespace::autoclean -except => 'import';
  49         114  
  49         252  
27              
28             sub from_config {
29 1     1 1 6 my ($self, @arg) = @_;
30              
31             # The only thing using a local time zone should be NextRelease. Normally it
32             # defaults to "local," but since some users won't have an automatically
33             # determinable time zone, we'll switch to not-local times for testing.
34             # -- rjbs, 2015-11-26
35 1         3 local $Dist::Zilla::Plugin::NextRelease::DEFAULT_TIME_ZONE = 'GMT';
36              
37 1         8 return $self->builder->from_config(@arg);
38             }
39              
40 167     167 0 2566 sub builder { 'Dist::Zilla::Tester::_Builder' }
41              
42 1     1 0 14 sub minter { 'Dist::Zilla::Tester::_Minter' }
43              
44             {
45             package
46             Dist::Zilla::Tester::_Role;
47              
48 49     49   12295 use Moose::Role;
  49         127  
  49         656  
49              
50             has tempdir_root => (
51             is => 'rw', isa => 'Str|Undef',
52             writer => '_set_tempdir_root',
53             );
54             has tempdir_obj => (
55             is => 'ro', isa => 'File::Temp::Dir',
56             clearer => '_clear_tempdir_obj',
57             writer => '_set_tempdir_obj',
58             );
59              
60       10 0   sub DEMOLISH {}
61             around DEMOLISH => sub {
62             my $orig = shift;
63             my $self = shift;
64              
65             # File::Temp deletes the directory when it goes out of scope
66             $self->_clear_tempdir_obj;
67              
68             rmdir $self->tempdir_root if $self->tempdir_root;
69             return $self->$orig(@_);
70             };
71              
72             has tempdir => (
73             is => 'ro',
74             writer => '_set_tempdir',
75             init_arg => undef,
76             );
77              
78             sub clear_log_events {
79 0     0 0 0 my ($self) = @_;
80 0         0 $self->chrome->logger->clear_events;
81             }
82              
83             sub log_events {
84 0     0 0 0 my ($self) = @_;
85 0         0 $self->chrome->logger->events;
86             }
87              
88             sub log_messages {
89 27     27 0 46970 my ($self) = @_;
90 27         166 [ map {; $_->{message} } @{ $self->chrome->logger->events } ];
  189         988  
  27         1253  
91             }
92              
93             sub slurp_file {
94 112     112 0 129446 my ($self, $filename) = @_;
95              
96 112         4564 Dist::Zilla::Path::path(
97             $self->tempdir->child($filename)
98             )->slurp_utf8;
99             }
100              
101             sub slurp_file_raw {
102 0     0 0 0 my ($self, $filename) = @_;
103              
104 0         0 Dist::Zilla::Path::path(
105             $self->tempdir->child($filename)
106             )->slurp_raw;
107             }
108              
109 147     147   4742 sub _metadata_generator_id { 'Dist::Zilla::Tester' }
110              
111 49     49   309471 no Moose::Role;
  49         118  
  49         350  
112             }
113              
114             {
115             package Dist::Zilla::Tester::_Builder 6.029;
116              
117 49     49   15295 use Moose;
  49         108  
  49         438  
118             extends 'Dist::Zilla::Dist::Builder';
119             with 'Dist::Zilla::Tester::_Role';
120              
121 49     49   380685 use File::Copy::Recursive 0.41 qw(dircopy);
  49         331860  
  49         3488  
122 49     49   409 use Dist::Zilla::Path;
  49         116  
  49         362  
123              
124             our $Log_Events = [];
125             sub most_recent_log_events {
126 0     0 0 0 return @{ $Log_Events }
  0         0  
127             }
128              
129             around from_config => sub {
130             my ($orig, $self, $arg, $tester_arg) = @_;
131              
132             confess "dist_root required for from_config" unless $arg->{dist_root};
133              
134             my $source = $arg->{dist_root};
135              
136             my $tempdir_root = exists $tester_arg->{tempdir_root}
137             ? $tester_arg->{tempdir_root}
138             : 'tmp';
139              
140             mkdir $tempdir_root if defined $tempdir_root and not -d $tempdir_root;
141              
142             my $tempdir_obj = File::Temp->newdir(
143             CLEANUP => 1,
144             (defined $tempdir_root ? (DIR => $tempdir_root) : ()),
145             );
146              
147             my $tempdir = path( path($tempdir_obj)->absolute) ;
148              
149             my $root = $tempdir->child('source');
150             $root->mkpath;
151              
152             dircopy($source, $root);
153              
154             if ($tester_arg->{also_copy}) {
155             while (my ($src, $dest) = each %{ $tester_arg->{also_copy} }) {
156             dircopy($src, $tempdir->child($dest));
157             }
158             }
159              
160             if (my $files = $tester_arg->{add_files}) {
161             while (my ($name, $content) = each %$files) {
162             die "Unix path '$name' does not seem to be portable to the current OS"
163             if !unix_path_seems_portable($name);
164             my $fn = $tempdir->child($name);
165             $fn->parent->mkpath;
166             Dist::Zilla::Path::path($fn)->spew_utf8($content);
167             }
168             }
169              
170             local $arg->{dist_root} = "$root";
171             local $arg->{chrome} = Dist::Zilla::Chrome::Test->new;
172              
173             $Log_Events = $arg->{chrome}->logger->events;
174              
175             local @INC = @INC;
176              
177             my $had_dot;
178             if ($INC[-1] eq '.') {
179             $had_dot = 1;
180             pop @INC;
181             }
182              
183             @INC = map {; ref($_) ? $_ : File::Spec->rel2abs($_) } @INC;
184              
185             push @INC, '.' if $had_dot;
186              
187             # We do this so that . in @INC will find plugins like [=inc::YourFace]
188             # -- rjbs, 2016-04-24
189             my $wd = File::pushd::pushd($arg->{dist_root});
190              
191              
192             local $ENV{DZIL_GLOBAL_CONFIG_ROOT};
193             $ENV{DZIL_GLOBAL_CONFIG_ROOT} = $tester_arg->{global_config_root}
194             if defined $tester_arg->{global_config_root};
195              
196             my $zilla = $self->$orig($arg);
197              
198             $zilla->_set_tempdir_root($tempdir_root);
199             $zilla->_set_tempdir_obj($tempdir_obj);
200             $zilla->_set_tempdir($tempdir);
201              
202             return $zilla;
203             };
204              
205             around build_in => sub {
206             my ($orig, $self, $target) = @_;
207              
208             # Sometimes, we can't get a local time zone. When that happens, we're just
209             # going to pretend to be in UTC. We don't do this during actual runtime
210             # because the user can fix their own environment, but we'll let them do
211             # that after they get the software installed. -- rjbs, 2020-01-26
212             my $ok = eval { DateTime::TimeZone->new(name => 'local'); 1 };
213             local $ENV{TZ} = $ok ? $ENV{TZ} : 'UTC';
214              
215             # XXX: We *must eliminate* the need for this! It's only here because right
216             # now building a dist with (root <> cwd) doesn't work. -- rjbs, 2010-03-08
217             my $wd = File::pushd::pushd($self->root);
218              
219             $target ||= do {
220             my $target = path($self->tempdir)->child('build');
221             $target->mkpath;
222             $target;
223             };
224              
225             return $self->$orig($target);
226             };
227              
228             around ['test', 'release'] => sub {
229             my ($orig, $self) = @_;
230              
231             # XXX: We *must eliminate* the need for this! It's only here because right
232             # now building a dist with (root <> cwd) doesn't work. -- rjbs, 2010-03-08
233             my $wd = File::pushd::pushd($self->root);
234              
235             return $self->$orig;
236             };
237              
238 49     49   63435 no Moose;
  49         128  
  49         410  
239              
240             sub unix_path_seems_portable {
241 289 50   289 0 1798 return 1 if $^O eq "linux"; # this check only makes sense on non-unixes
242              
243 0         0 my ($unix_path) = @_;
244              
245             # split the $unix_path into 3 strings: $volume, $directories, $file; with:
246 0         0 my @native_parts = File::Spec->splitpath($unix_path); # current OS rules
247 0         0 my @unix_parts = File::Spec::Unix->splitpath($unix_path); # unix rules
248 0 0       0 return unless join(qq{\0}, @native_parts) eq join(qq{\0}, @unix_parts);
249              
250             # split the $directories string into a list of the sub-directories; with:
251 0         0 my @native_dirs = File::Spec->splitdir($native_parts[1]); # current OS rules
252 0         0 my @unix_dirs = File::Spec::Unix->splitdir($unix_parts[1]); # unix rules
253 0 0       0 return unless join(qq{\0}, @native_dirs) eq join(qq{\0}, @unix_dirs);
254              
255 0         0 return 1;
256             }
257             }
258              
259             {
260             package Dist::Zilla::Tester::_Minter 6.029;
261              
262 49     49   22312 use Moose;
  49         120  
  49         297  
263             extends 'Dist::Zilla::Dist::Minter';
264             with 'Dist::Zilla::Tester::_Role';
265              
266 49     49   330248 use File::Copy::Recursive 0.41 qw(dircopy);
  49         796  
  49         2660  
267 49     49   357 use Dist::Zilla::Path;
  49         137  
  49         281  
268              
269             our $Log_Events = [];
270             sub most_recent_log_events {
271 0     0 0 0 return @{ $Log_Events }
  0         0  
272             }
273              
274             sub _mint_target_dir {
275 1     1   4 my ($self) = @_;
276              
277 1         24 my $name = $self->name;
278 1         32 my $dir = $self->tempdir->child('mint')->absolute;
279              
280 1 50       183 $self->log_fatal("$dir already exists") if -e $dir;
281              
282 1         82 return $dir;
283             }
284              
285             sub _setup_global_config {
286 1     1   4 my ($self, $dir, $arg) = @_;
287              
288 1         5 my $config_base = path($dir)->child('config');
289              
290 1         85 my $stash_registry = {};
291              
292 1         610 require Dist::Zilla::MVP::Assembler::GlobalConfig;
293 1         638 require Dist::Zilla::MVP::Section;
294             my $assembler = Dist::Zilla::MVP::Assembler::GlobalConfig->new({
295             chrome => $arg->{chrome},
296 1         52 stash_registry => $stash_registry,
297             section_class => 'Dist::Zilla::MVP::Section', # make this DZMA default
298             });
299              
300 1         674 require Dist::Zilla::MVP::Reader::Finder;
301 1         73 my $reader = Dist::Zilla::MVP::Reader::Finder->new;
302              
303 1         12 my $seq = $reader->read_config($config_base, { assembler => $assembler });
304              
305 1         621 return $stash_registry;
306             }
307              
308             around _new_from_profile => sub {
309             my ($orig, $self, $profile_data, $arg, $tester_arg) = @_;
310              
311             # Sometimes, we can't get a local time zone. When that happens, we're just
312             # going to pretend to be in UTC. We don't do this during actual runtime
313             # because the user can fix their own environment, but we'll let them do
314             # that after they get the software installed. -- rjbs, 2020-01-26
315             my $ok = eval { DateTime::TimeZone->new(name => 'local'); 1 };
316             local $ENV{TZ} = $ok ? $ENV{TZ} : 'UTC';
317              
318             my $tempdir_root = exists $tester_arg->{tempdir_root}
319             ? $tester_arg->{tempdir_root}
320             : 'tmp';
321              
322             mkdir $tempdir_root if defined $tempdir_root and not -d $tempdir_root;
323              
324             my $tempdir_obj = File::Temp->newdir(
325             CLEANUP => 1,
326             (defined $tempdir_root ? (DIR => $tempdir_root) : ()),
327             );
328             my $tempdir = path($tempdir_obj)->absolute;
329              
330             local $arg->{chrome} = Dist::Zilla::Chrome::Test->new;
331             $Log_Events = $arg->{chrome}->logger->events;
332              
333             local @INC = map {; ref($_) ? $_ : File::Spec->rel2abs($_) } @INC;
334              
335             my $global_config_root = path($tester_arg->{global_config_root})->absolute;
336              
337             local $ENV{DZIL_GLOBAL_CONFIG_ROOT} = $global_config_root;
338              
339             my $global_stashes = $self->_setup_global_config(
340             $global_config_root,
341             { chrome => $arg->{chrome} },
342             );
343              
344             local $arg->{_global_stashes} = $global_stashes;
345              
346             my $zilla = $self->$orig($profile_data, $arg);
347              
348             $zilla->_set_tempdir_root($tempdir_root);
349             $zilla->_set_tempdir_obj($tempdir_obj);
350             $zilla->_set_tempdir($tempdir);
351              
352             return $zilla;
353             };
354             }
355              
356 49     49   53446 no Moose; # XXX: namespace::autoclean caused problems -- rjbs, 2011-08-19
  49         118  
  49         241  
357             __PACKAGE__->meta->make_immutable;
358             1;
359              
360             __END__
361              
362             =pod
363              
364             =encoding UTF-8
365              
366             =head1 NAME
367              
368             Dist::Zilla::Tester - a testing-enabling stand-in for Dist::Zilla
369              
370             =head1 VERSION
371              
372             version 6.029
373              
374             =head1 PERL VERSION
375              
376             This module should work on any version of perl still receiving updates from
377             the Perl 5 Porters. This means it should work on any version of perl released
378             in the last two to three years. (That is, if the most recently released
379             version is v5.40, then this module should work on both v5.40 and v5.38.)
380              
381             Although it may work on older versions of perl, no guarantee is made that the
382             minimum required version will not be increased. The version may be increased
383             for any reason, and there is no promise that patches will be accepted to lower
384             the minimum required perl.
385              
386             =head1 AUTHOR
387              
388             Ricardo SIGNES 😏 <cpan@semiotic.systems>
389              
390             =head1 COPYRIGHT AND LICENSE
391              
392             This software is copyright (c) 2022 by Ricardo SIGNES.
393              
394             This is free software; you can redistribute it and/or modify it under
395             the same terms as the Perl 5 programming language system itself.
396              
397             =cut