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.030;
2             # ABSTRACT: a testing-enabling stand-in for Dist::Zilla
3              
4 49     49   124220 use Moose;
  49         18609724  
  49         408  
5             extends 'Dist::Zilla::Dist::Builder';
6              
7 49     49   385793 use Dist::Zilla::Pragmas;
  49         138  
  49         479  
8              
9 49     49   26420 use autodie;
  49         559397  
  49         359  
10 49     49   377395 use Dist::Zilla::Chrome::Test;
  49         251  
  49         4648  
11 49     49   29702 use File::pushd ();
  49         932592  
  49         1467  
12 49     49   429 use File::Spec;
  49         154  
  49         980  
13 49     49   261 use File::Temp;
  49         1970  
  49         4491  
14 49     49   23361 use Dist::Zilla::Path;
  49         188  
  49         241  
15              
16 49     49   16206 use Sub::Exporter::Util ();
  49         109  
  49         5203  
17             use Sub::Exporter -setup => {
18             exports => [
19 1         305 Builder => sub { $_[0]->can('builder') },
20 1         45 Minter => sub { $_[0]->can('minter') },
21 49         484 ],
22              
23             groups => [ default => [ qw(Builder Minter) ] ],
24 49     49   322 };
  49         109  
25              
26 49     49   26445 use namespace::autoclean -except => 'import';
  49         123  
  49         267  
27              
28             sub from_config {
29 1     1 1 4 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         9 return $self->builder->from_config(@arg);
38             }
39              
40 167     167 0 2623 sub builder { 'Dist::Zilla::Tester::_Builder' }
41              
42 1     1 0 12 sub minter { 'Dist::Zilla::Tester::_Minter' }
43              
44             {
45             package
46             Dist::Zilla::Tester::_Role;
47              
48 49     49   12273 use Moose::Role;
  49         120  
  49         567  
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 53501 my ($self) = @_;
90 27         168 [ map {; $_->{message} } @{ $self->chrome->logger->events } ];
  189         1736  
  27         1249  
91             }
92              
93             sub slurp_file {
94 112     112 0 134171 my ($self, $filename) = @_;
95              
96 112         4178 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   4803 sub _metadata_generator_id { 'Dist::Zilla::Tester' }
110              
111 49     49   311129 no Moose::Role;
  49         124  
  49         372  
112             }
113              
114             {
115             package Dist::Zilla::Tester::_Builder 6.030;
116              
117 49     49   17446 use Moose;
  49         2062  
  49         2109  
118             extends 'Dist::Zilla::Dist::Builder';
119             with 'Dist::Zilla::Tester::_Role';
120              
121 49     49   378661 use File::Copy::Recursive 0.41 qw(dircopy);
  49         332649  
  49         3608  
122 49     49   411 use Dist::Zilla::Path;
  49         145  
  49         412  
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   65088 no Moose;
  49         123  
  49         437  
239              
240             sub unix_path_seems_portable {
241 289 50   289 0 1747 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.030;
261              
262 49     49   23000 use Moose;
  49         129  
  49         275  
263             extends 'Dist::Zilla::Dist::Minter';
264             with 'Dist::Zilla::Tester::_Role';
265              
266 49     49   332980 use File::Copy::Recursive 0.41 qw(dircopy);
  49         832  
  49         2633  
267 49     49   363 use Dist::Zilla::Path;
  49         148  
  49         267  
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   3 my ($self) = @_;
276              
277 1         24 my $name = $self->name;
278 1         31 my $dir = $self->tempdir->child('mint')->absolute;
279              
280 1 50       196 $self->log_fatal("$dir already exists") if -e $dir;
281              
282 1         70 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         84 my $stash_registry = {};
291              
292 1         534 require Dist::Zilla::MVP::Assembler::GlobalConfig;
293 1         600 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         529 require Dist::Zilla::MVP::Reader::Finder;
301 1         1538 my $reader = Dist::Zilla::MVP::Reader::Finder->new;
302              
303 1         11 my $seq = $reader->read_config($config_base, { assembler => $assembler });
304              
305 1         673 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   54773 no Moose; # XXX: namespace::autoclean caused problems -- rjbs, 2011-08-19
  49         129  
  49         265  
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.030
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) 2023 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