File Coverage

blib/lib/Dist/Zilla.pm
Criterion Covered Total %
statement 165 183 90.1
branch 42 64 65.6
condition 3 5 60.0
subroutine 34 34 100.0
pod 4 5 80.0
total 248 291 85.2


line stmt bran cond sub pod time code
1             package Dist::Zilla 6.030;
2             # ABSTRACT: distribution builder; installer not included!
3              
4 52     52   598471 use Moose 0.92; # role composition fixes
  52         450587  
  52         415  
5             with 'Dist::Zilla::Role::ConfigDumper';
6              
7 52     52   350164 use Dist::Zilla::Pragmas;
  52         153  
  52         429  
8              
9             # This comment has fün̈n̈ÿ characters.
10              
11 52     52   1976 use MooseX::Types::Moose qw(ArrayRef Bool HashRef Object Str);
  52         143621  
  52         463  
12 52     52   332526 use MooseX::Types::Perl qw(DistName LaxVersionStr);
  52         1783608  
  52         409  
13 52     52   136119 use Moose::Util::TypeConstraints;
  52         137  
  52         324  
14              
15 52     52   121230 use Dist::Zilla::Types qw(Path License ReleaseStatus);
  52         162  
  52         498  
16              
17 52     52   149472 use Log::Dispatchouli 1.100712; # proxy_loggers, quiet_fatal
  52         923169  
  52         1694  
18 52     52   1793 use Dist::Zilla::Path;
  52         149  
  52         476  
19 52     52   16849 use List::Util 1.33 qw(first none);
  52         1434  
  52         4656  
20 52     52   31486 use Software::License 0.104001; # ->program
  52         1052820  
  52         1958  
21 52     52   22511 use String::RewritePrefix;
  52         47694  
  52         339  
22 52     52   10757 use Try::Tiny;
  52         282  
  52         3407  
23              
24 52     52   30125 use Dist::Zilla::Prereqs;
  52         212  
  52         2291  
25 52     52   28130 use Dist::Zilla::File::OnDisk;
  52         214  
  52         2660  
26 52     52   32876 use Dist::Zilla::Role::Plugin;
  52         210  
  52         2001  
27 52     52   25982 use Dist::Zilla::Util;
  52         162  
  52         1992  
28 52     52   494 use Module::Runtime 'require_module';
  52         126  
  52         531  
29              
30 52     52   2917 use namespace::autoclean;
  52         123  
  52         375  
31              
32             #pod =head1 DESCRIPTION
33             #pod
34             #pod Dist::Zilla builds distributions of code to be uploaded to the CPAN. In this
35             #pod respect, it is like L<ExtUtils::MakeMaker>, L<Module::Build>, or
36             #pod L<Module::Install>. Unlike those tools, however, it is not also a system for
37             #pod installing code that has been downloaded from the CPAN. Since it's only run by
38             #pod authors, and is meant to be run on a repository checkout rather than on
39             #pod published, released code, it can do much more than those tools, and is free to
40             #pod make much more ludicrous demands in terms of prerequisites.
41             #pod
42             #pod If you have access to the web, you can learn more and find an interactive
43             #pod tutorial at B<L<dzil.org|https://dzil.org/>>. If not, try
44             #pod L<Dist::Zilla::Tutorial>.
45             #pod
46             #pod =cut
47              
48             has chrome => (
49             is => 'rw',
50             isa => role_type('Dist::Zilla::Role::Chrome'),
51             required => 1,
52             );
53              
54             #pod =attr name
55             #pod
56             #pod The name attribute (which is required) gives the name of the distribution to be
57             #pod built. This is usually the name of the distribution's main module, with the
58             #pod double colons (C<::>) replaced with dashes. For example: C<Dist-Zilla>.
59             #pod
60             #pod =cut
61              
62             has name => (
63             is => 'ro',
64             isa => DistName,
65             lazy => 1,
66             builder => '_build_name',
67             );
68              
69             #pod =attr version
70             #pod
71             #pod This is the version of the distribution to be created.
72             #pod
73             #pod =cut
74              
75             has _version_override => (
76             isa => LaxVersionStr,
77             is => 'ro' ,
78             init_arg => 'version',
79             );
80              
81             # XXX: *clearly* this needs to be really much smarter -- rjbs, 2008-06-01
82             has version => (
83             is => 'rw',
84             isa => LaxVersionStr,
85             lazy => 1,
86             init_arg => undef,
87             builder => '_build_version',
88             );
89              
90             sub _build_name {
91 1     1   4 my ($self) = @_;
92              
93 1         2 my $name;
94 1         2 for my $plugin (@{ $self->plugins_with(-NameProvider) }) {
  1         6  
95 1 50       8 next unless defined(my $this_name = $plugin->provide_name);
96              
97 1 50       13 $self->log_fatal('attempted to set name twice') if defined $name;
98              
99 1         3 $name = $this_name;
100             }
101              
102 1 50       8 $self->log_fatal('no name was ever set') unless defined $name;
103              
104 1         28 $name;
105             }
106              
107             sub _build_version {
108 151     151   550 my ($self) = @_;
109              
110 151         4616 my $version = $self->_version_override;
111              
112 151         391 for my $plugin (@{ $self->plugins_with(-VersionProvider) }) {
  151         675  
113 3 50       26 next unless defined(my $this_version = $plugin->provide_version);
114              
115 3 50       11 $self->log_fatal('attempted to set version twice') if defined $version;
116              
117 3         11 $version = $this_version;
118             }
119              
120 151 50       825 $self->log_fatal('no version was ever set') unless defined $version;
121              
122 151         4493 $version;
123             }
124              
125             #pod =attr release_status
126             #pod
127             #pod This attribute sets the release status to one of the
128             #pod L<CPAN::META::Spec|https://metacpan.org/pod/CPAN::Meta::Spec#release_status>
129             #pod values: 'stable', 'testing' or 'unstable'.
130             #pod
131             #pod If the C<$ENV{RELEASE_STATUS}> environment variable exists, its value will
132             #pod be used as the release status.
133             #pod
134             #pod For backwards compatibility, if C<$ENV{RELEASE_STATUS}> does not exist and
135             #pod the C<$ENV{TRIAL}> variable is true, the release status will be 'testing'.
136             #pod
137             #pod Otherwise, the release status will be set from a
138             #pod L<ReleaseStatusProvider|Dist::Zilla::Role::ReleaseStatusProvider>, if one
139             #pod has been configured.
140             #pod
141             #pod For backwards compatibility, setting C<is_trial> true in F<dist.ini> is
142             #pod equivalent to using a C<ReleaseStatusProvider>. If C<is_trial> is false,
143             #pod it has no effect.
144             #pod
145             #pod Only B<one> C<ReleaseStatusProvider> may be used.
146             #pod
147             #pod If no providers are used, the release status defaults to 'stable' unless there
148             #pod is an "_" character in the version, in which case, it defaults to 'testing'.
149             #pod
150             #pod =cut
151              
152             # release status must be lazy, after files are gathered
153             has release_status => (
154             is => 'ro',
155             isa => ReleaseStatus,
156             lazy => 1,
157             builder => '_build_release_status',
158             );
159              
160             sub _build_release_status {
161 150     150   512 my ($self) = @_;
162              
163             # environment variables override completely
164 150 100       4633 return $self->_release_status_from_env if $self->_release_status_from_env;
165              
166             # other ways of setting status must not conflict
167 143         343 my $status;
168              
169             # dist.ini is equivalent to a release provider if is_trial is true.
170             # If false, though, we want other providers to run or fall back to
171             # the version
172 143 100       4385 $status = 'testing' if $self->_override_is_trial;
173              
174 143         357 for my $plugin (@{ $self->plugins_with(-ReleaseStatusProvider) }) {
  143         626  
175 3 50       26 next unless defined(my $this_status = $plugin->provide_release_status);
176              
177 3 100       37 $self->log_fatal('attempted to set release status twice')
178             if defined $status;
179              
180 2         6 $status = $this_status;
181             }
182              
183 142   66     5091 return $status || ( $self->version =~ /_/ ? 'testing' : 'stable' );
184             }
185              
186             # captures environment variables early during Zilla object construction
187             has _release_status_from_env => (
188             is => 'ro',
189             isa => Str,
190             builder => '_build_release_status_from_env',
191             );
192              
193             sub _build_release_status_from_env {
194 188     188   529662 my ($self) = @_;
195 188 100       1008 return $ENV{RELEASE_STATUS} if $ENV{RELEASE_STATUS};
196 187 100       1843 return $ENV{TRIAL} ? 'testing' : '';
197             }
198              
199             #pod =attr abstract
200             #pod
201             #pod This is a one-line summary of the distribution. If none is given, one will be
202             #pod looked for in the L</main_module> of the dist.
203             #pod
204             #pod =cut
205              
206             has abstract => (
207             is => 'rw',
208             isa => 'Str',
209             lazy => 1,
210             default => sub {
211             my ($self) = @_;
212              
213             unless ($self->main_module) {
214             die "no abstract given and no main_module found; make sure your main module is in ./lib\n";
215             }
216              
217             my $file = $self->main_module;
218             $self->log_debug("extracting distribution abstract from " . $file->name);
219             my $abstract = Dist::Zilla::Util->abstract_from_file($file);
220              
221             if (!defined($abstract)) {
222             my $filename = $file->name;
223             die "Unable to extract an abstract from $filename. Please add the following comment to the file with your abstract:
224             # ABSTRACT: turns baubles into trinkets
225             ";
226             }
227              
228             return $abstract;
229             }
230             );
231              
232             #pod =attr main_module
233             #pod
234             #pod This is the module where Dist::Zilla might look for various defaults, like
235             #pod the distribution abstract. By default, it's derived from the distribution
236             #pod name. If your distribution is Foo-Bar, and F<lib/Foo/Bar.pm> exists,
237             #pod that's the main_module. Otherwise, it's the shortest-named module in the
238             #pod distribution. This may change!
239             #pod
240             #pod You can override the default by specifying the file path explicitly,
241             #pod ie:
242             #pod
243             #pod main_module = lib/Foo/Bar.pm
244             #pod
245             #pod =cut
246              
247             has _main_module_override => (
248             isa => 'Str',
249             is => 'ro' ,
250             init_arg => 'main_module',
251             predicate => '_has_main_module_override',
252             );
253              
254             has main_module => (
255             is => 'ro',
256             isa => 'Dist::Zilla::Role::File',
257             lazy => 1,
258             init_arg => undef,
259             default => sub {
260             my ($self) = @_;
261              
262             my $file;
263             my $guess;
264              
265             if ( $self->_has_main_module_override ) {
266             $file = first { $_->name eq $self->_main_module_override }
267             @{ $self->files };
268             } else {
269             # We're having to guess
270              
271             $guess = $self->name =~ s{-}{/}gr;
272             $guess = "lib/$guess.pm";
273              
274             $file = (first { $_->name eq $guess } @{ $self->files })
275             || (sort { length $a->name <=> length $b->name }
276             grep { $_->name =~ m{\.pm\z} and $_->name =~ m{\Alib/} }
277             @{ $self->files })[0];
278             $self->log("guessing dist's main_module is " . ($file ? $file->name : $guess));
279             }
280              
281             if (not $file) {
282             my @errorlines;
283              
284             push @errorlines, "Unable to find main_module in the distribution";
285             if ($self->_has_main_module_override) {
286             push @errorlines, "'main_module' was specified in dist.ini but the file '" . $self->_main_module_override . "' is not to be found in our dist. ( Did you add it? )";
287             } else {
288             push @errorlines,"We tried to guess '$guess' but no file like that existed";
289             }
290             if (not @{ $self->files }) {
291             push @errorlines, "Upon further inspection we didn't find any files in your dist, did you add any?";
292             } elsif ( none { $_->name =~ m{^lib/.+\.pm\z} } @{ $self->files } ){
293             push @errorlines, "We didn't find any .pm files in your dist, this is probably a problem.";
294             }
295             push @errorlines,"Cannot continue without a main_module";
296             $self->log_fatal( join qq{\n}, @errorlines );
297             }
298             $self->log_debug("dist's main_module is " . $file->name);
299              
300             return $file;
301             },
302             );
303              
304             #pod =attr license
305             #pod
306             #pod This is the L<Software::License|Software::License> object for this dist's
307             #pod license and copyright.
308             #pod
309             #pod It will be created automatically, if possible, with the
310             #pod C<copyright_holder> and C<copyright_year> attributes. If necessary, it will
311             #pod try to guess the license from the POD of the dist's main module.
312             #pod
313             #pod A better option is to set the C<license> name in the dist's config to something
314             #pod understandable, like C<Perl_5>.
315             #pod
316             #pod =cut
317              
318             has license => (
319             is => 'ro',
320             isa => License,
321             lazy => 1,
322             init_arg => 'license_obj',
323             predicate => '_has_license',
324             builder => '_build_license',
325             handles => {
326             copyright_holder => 'holder',
327             copyright_year => 'year',
328             },
329             );
330              
331             sub _build_license {
332 150     150   515 my ($self) = @_;
333              
334 150         4478 my $license_class = $self->_license_class;
335 150         4266 my $copyright_holder = $self->_copyright_holder;
336 150         4348 my $copyright_year = $self->_copyright_year;
337              
338 150         381 my $provided_license;
339              
340 150         334 for my $plugin (@{ $self->plugins_with(-LicenseProvider) }) {
  150         644  
341 1         14 my $this_license = $plugin->provide_license({
342             copyright_holder => $copyright_holder,
343             copyright_year => $copyright_year,
344             });
345              
346 1 50       37 next unless defined $this_license;
347              
348 1 50       4 $self->log_fatal('attempted to set license twice')
349             if defined $provided_license;
350              
351 1         3 $provided_license = $this_license;
352             }
353              
354 150 100       781 return $provided_license if defined $provided_license;
355              
356 149 50       962 if ($license_class) {
357 149         2424 $license_class = String::RewritePrefix->rewrite(
358             {
359             '=' => '',
360             '' => 'Software::License::'
361             },
362             $license_class,
363             );
364             } else {
365 0         0 require Software::LicenseUtils;
366 0         0 my @guess = Software::LicenseUtils->guess_license_from_pod(
367             $self->main_module->content
368             );
369              
370 0 0       0 if (@guess != 1) {
371 0         0 $self->log_fatal(
372             "no license data in config, no %Rights stash,",
373             "couldn't make a good guess at license from Pod; giving up. ",
374             "Perhaps you need to set up a global config file (dzil setup)?"
375             );
376             }
377              
378 0         0 my $filename = $self->main_module->name;
379 0         0 $license_class = $guess[0];
380 0         0 $self->log("based on POD in $filename, guessing license is $guess[0]");
381             }
382              
383 149 50       14374 unless (eval { require_module($license_class) }) {
  149         1010  
384 0         0 $self->log_fatal(
385             "could not load class $license_class for license " . $self->_license_class
386             );
387             }
388              
389 149         112779 my $license = $license_class->new({
390             holder => $self->_copyright_holder,
391             year => $self->_copyright_year,
392             program => $self->name,
393             });
394              
395 149         6992 $self->_clear_license_class;
396 149         5184 $self->_clear_copyright_holder;
397 149         5067 $self->_clear_copyright_year;
398              
399 149         3594 return $license;
400             }
401              
402             has _license_class => (
403             is => 'ro',
404             isa => 'Maybe[Str]',
405             lazy => 1,
406             init_arg => 'license',
407             clearer => '_clear_license_class',
408             default => sub {
409             my $stash = $_[0]->stash_named('%Rights');
410             $stash && return $stash->license_class;
411             return;
412             }
413             );
414              
415             has _copyright_holder => (
416             is => 'ro',
417             isa => 'Maybe[Str]',
418             lazy => 1,
419             init_arg => 'copyright_holder',
420             clearer => '_clear_copyright_holder',
421             default => sub {
422             return unless my $stash = $_[0]->stash_named('%Rights');
423             $stash && return $stash->copyright_holder;
424             return;
425             }
426             );
427              
428             has _copyright_year => (
429             is => 'ro',
430             isa => 'Str',
431             lazy => 1,
432             init_arg => 'copyright_year',
433             clearer => '_clear_copyright_year',
434             default => sub {
435             # Oh man. This is a terrible idea! I mean, what if by the code gets run
436             # around like Dec 31, 23:59:59.9 and by the time the default gets called
437             # it's the next year but the default was already set up? Oh man. That
438             # could ruin lives! I guess we could make this a sub to defer the guess,
439             # but think of the performance hit! I guess we'll have to suffer through
440             # this until we can optimize the code to not take .1s to run, right? --
441             # rjbs, 2008-06-13
442             my $stash = $_[0]->stash_named('%Rights');
443             my $year = $stash && $stash->copyright_year;
444             return( $year // (localtime)[5] + 1900 );
445             }
446             );
447              
448             #pod =attr authors
449             #pod
450             #pod This is an arrayref of author strings, like this:
451             #pod
452             #pod [
453             #pod 'Ricardo Signes <rjbs@cpan.org>',
454             #pod 'X. Ample, Jr <example@example.biz>',
455             #pod ]
456             #pod
457             #pod This is likely to change at some point in the near future.
458             #pod
459             #pod =cut
460              
461             has authors => (
462             is => 'ro',
463             isa => ArrayRef[Str],
464             lazy => 1,
465             default => sub {
466             my ($self) = @_;
467              
468             if (my $stash = $self->stash_named('%User')) {
469             return $stash->authors;
470             }
471              
472             my $author = try { $self->copyright_holder };
473             return [ $author ] if length $author;
474              
475             $self->log_fatal(
476             "No %User stash and no copyright holder;",
477             "can't determine dist author; configure author or a %User section",
478             );
479             },
480             );
481              
482             #pod =attr files
483             #pod
484             #pod This is an arrayref of objects implementing L<Dist::Zilla::Role::File> that
485             #pod will, if left in this arrayref, be built into the dist.
486             #pod
487             #pod Non-core code should avoid altering this arrayref, but sometimes there is not
488             #pod other way to change the list of files. In the future, the representation used
489             #pod for storing files B<will be changed>.
490             #pod
491             #pod =cut
492              
493             has files => (
494             is => 'ro',
495             isa => ArrayRef[ role_type('Dist::Zilla::Role::File') ],
496             lazy => 1,
497             init_arg => undef,
498             default => sub { [] },
499             );
500              
501             sub prune_file {
502 22     22 0 58 my ($self, $file) = @_;
503 22         42 my @files = @{ $self->files };
  22         530  
504              
505 22         106 for my $i (0 .. $#files) {
506 52 100       124 next unless $file == $files[ $i ];
507 22         37 splice @{ $self->files }, $i, 1;
  22         489  
508 22         549 return;
509             }
510              
511 0         0 return;
512             }
513              
514             #pod =attr root
515             #pod
516             #pod This is the root directory of the dist, as a L<Path::Tiny>. It will
517             #pod nearly always be the current working directory in which C<dzil> was run.
518             #pod
519             #pod =cut
520              
521             has root => (
522             is => 'ro',
523             isa => Path,
524             coerce => 1,
525             required => 1,
526             );
527              
528             #pod =attr is_trial
529             #pod
530             #pod This attribute tells us whether or not the dist will be a trial release,
531             #pod i.e. whether it has C<release_status> 'testing' or 'unstable'.
532             #pod
533             #pod Do not set this directly, it will be derived from C<release_status>.
534             #pod
535             #pod =cut
536              
537             has is_trial => (
538             is => 'ro',
539             isa => Bool,
540             init_arg => undef,
541             lazy => 1,
542             builder => '_build_is_trial',
543             );
544              
545             has _override_is_trial => (
546             is => 'ro',
547             isa => Bool,
548             init_arg => 'is_trial',
549             default => 0,
550             );
551              
552             sub _build_is_trial {
553 56     56   243 my ($self) = @_;
554 56 100       1939 return $self->release_status =~ /\A(?:testing|unstable)\z/ ? 1 : 0;
555             }
556              
557             #pod =attr plugins
558             #pod
559             #pod This is an arrayref of plugins that have been plugged into this Dist::Zilla
560             #pod object.
561             #pod
562             #pod Non-core code B<must not> alter this arrayref. Public access to this attribute
563             #pod B<may go away> in the future.
564             #pod
565             #pod =cut
566              
567             has plugins => (
568             is => 'ro',
569             isa => 'ArrayRef[Dist::Zilla::Role::Plugin]',
570             init_arg => undef,
571             default => sub { [ ] },
572             );
573              
574             #pod =attr distmeta
575             #pod
576             #pod This is a hashref containing the metadata about this distribution that will be
577             #pod stored in META.yml or META.json. You should not alter the metadata in this
578             #pod hash; use a MetaProvider plugin instead.
579             #pod
580             #pod =cut
581              
582             has distmeta => (
583             is => 'ro',
584             isa => 'HashRef',
585             init_arg => undef,
586             lazy => 1,
587             builder => '_build_distmeta',
588             );
589              
590             sub _build_distmeta {
591 149     149   536 my ($self) = @_;
592              
593 149         30346 require CPAN::Meta::Merge;
594 149         820659 my $meta_merge = CPAN::Meta::Merge->new(default_version => 2);
595 149         32726 my $meta = {};
596              
597 149         480 for (@{ $self->plugins_with(-MetaProvider) }) {
  149         1126  
598 13         4866 $meta = $meta_merge->merge($meta, $_->metadata);
599             }
600              
601 149   50     15552 my %meta_main = (
602             'meta-spec' => {
603             version => 2,
604             url => 'https://metacpan.org/pod/CPAN::Meta::Spec',
605             },
606             name => $self->name,
607             version => $self->version,
608             abstract => $self->abstract,
609             author => $self->authors,
610             license => [ $self->license->meta2_name ],
611              
612             release_status => $self->release_status,
613              
614             dynamic_config => 0, # problematic, I bet -- rjbs, 2010-06-04
615             generated_by => $self->_metadata_generator_id
616             . ' version '
617             . ($self->VERSION // '(undef)'),
618             x_generated_by_perl => "$^V", # v5.24.0
619             );
620 148 100       4079 if (my $spdx = $self->license->spdx_expression) {
621 147         1304 $meta_main{x_spdx_expression} = $spdx;
622             }
623              
624 148         880 $meta = $meta_merge->merge($meta, \%meta_main);
625              
626 148         188458 return $meta;
627             }
628              
629 1     1   28 sub _metadata_generator_id { 'Dist::Zilla' }
630              
631             #pod =attr prereqs
632             #pod
633             #pod This is a L<Dist::Zilla::Prereqs> object, which is a thin layer atop
634             #pod L<CPAN::Meta::Prereqs>, and describes the distribution's prerequisites.
635             #pod
636             #pod =method register_prereqs
637             #pod
638             #pod Allows registration of prerequisites; delegates to
639             #pod L<Dist::Zilla::Prereqs/register_prereqs> via our L</prereqs> attribute.
640             #pod
641             #pod =cut
642              
643             has prereqs => (
644             is => 'ro',
645             isa => 'Dist::Zilla::Prereqs',
646             init_arg => undef,
647             lazy => 1,
648             default => sub { Dist::Zilla::Prereqs->new },
649             handles => [ qw(register_prereqs) ],
650             );
651              
652             #pod =method plugin_named
653             #pod
654             #pod my $plugin = $zilla->plugin_named( $plugin_name );
655             #pod
656             #pod =cut
657              
658             sub plugin_named {
659 2027     2027 1 65998 my ($self, $name) = @_;
660 2027     17979   8361 my $plugin = first { $_->plugin_name eq $name } @{ $self->plugins };
  17979         493411  
  2027         47432  
661              
662 2027 100       8809 return $plugin if $plugin;
663 1762         7896 return;
664             }
665              
666             #pod =method plugins_with
667             #pod
668             #pod my $roles = $zilla->plugins_with( -SomeRole );
669             #pod
670             #pod This method returns an arrayref containing all the Dist::Zilla object's plugins
671             #pod that perform the named role. If the given role name begins with a dash, the
672             #pod dash is replaced with "Dist::Zilla::Role::"
673             #pod
674             #pod =cut
675              
676             sub plugins_with {
677 2148     2148 1 5493 my ($self, $role) = @_;
678              
679 2148         10017 $role =~ s/^-/Dist::Zilla::Role::/;
680 2148         4136 my $plugins = [ grep { $_->does($role) } @{ $self->plugins } ];
  30698         1236495  
  2148         57406  
681              
682 2148         99051 return $plugins;
683             }
684              
685             #pod =method find_files
686             #pod
687             #pod my $files = $zilla->find_files( $finder_name );
688             #pod
689             #pod This method will look for a
690             #pod L<FileFinder|Dist::Zilla::Role::FileFinder>-performing plugin with the given
691             #pod name and return the result of calling C<find_files> on it. If no plugin can be
692             #pod found, an exception will be raised.
693             #pod
694             #pod =cut
695              
696             sub find_files {
697 233     233 1 1761 my ($self, $finder_name) = @_;
698              
699 233 50       748 $self->log_fatal("no plugin named $finder_name found")
700             unless my $plugin = $self->plugin_named($finder_name);
701              
702 233 50       1389 $self->log_fatal("plugin $finder_name is not a FileFinder")
703             unless $plugin->does('Dist::Zilla::Role::FileFinder');
704              
705 233         15180 $plugin->find_files;
706             }
707              
708             sub _check_dupe_files {
709 147     147   554 my ($self) = @_;
710              
711 147         602 my %files_named;
712             my @dupes;
713 147         359 for my $file (@{ $self->files }) {
  147         4255  
714 645         2064 my $filename = $file->name;
715 645 50       1837 if (my $seen = $files_named{ $filename }) {
716 0         0 push @{ $seen }, $file;
  0         0  
717 0 0       0 push @dupes, $filename if @{ $seen } == 2;
  0         0  
718             } else {
719 645         2463 $files_named{ $filename } = [ $file ];
720             }
721             }
722              
723 147 50       1181 return unless @dupes;
724              
725 0         0 for my $name (@dupes) {
726             $self->log("attempt to add $name multiple times; added by: "
727 0         0 . join('; ', map { $_->added_by } @{ $files_named{ $name } })
  0         0  
  0         0  
728             );
729             }
730              
731 0         0 Carp::croak("aborting; duplicate files would be produced");
732             }
733              
734             sub _write_out_file {
735 646     646   1832 my ($self, $file, $build_root) = @_;
736              
737             # Okay, this is a bit much, until we have ->debug. -- rjbs, 2008-06-13
738             # $self->log("writing out " . $file->name);
739              
740 646         2482 my $file_path = path($file->name);
741              
742 646         27613 my $to_dir = path($build_root)->child( $file_path->parent );
743 646         72297 my $to = $to_dir->child( $file_path->basename );
744 646 100       29147 $to_dir->mkpath unless -e $to_dir;
745 646 50       117930 die "not a directory: $to_dir" unless -d $to_dir;
746              
747 646 50       15099 Carp::croak("attempted to write $to multiple times") if -e $to;
748              
749 646         17476 path("$to")->spew_raw( $file->encoded_content );
750 646 50       442308 chmod $file->mode, "$to" or die "couldn't chmod $to: $!";
751             }
752              
753             #pod =attr logger
754             #pod
755             #pod This attribute stores a L<Log::Dispatchouli::Proxy> object, used to log
756             #pod messages. By default, a proxy to the dist's L<Chrome|Dist::Zilla::Role::Chrome> is
757             #pod taken.
758             #pod
759             #pod The following methods are delegated from the Dist::Zilla object to the logger:
760             #pod
761             #pod =for :list
762             #pod * log
763             #pod * log_debug
764             #pod * log_fatal
765             #pod
766             #pod =cut
767              
768             has logger => (
769             is => 'ro',
770             isa => 'Log::Dispatchouli::Proxy', # could be duck typed, I guess
771             lazy => 1,
772             handles => [ qw(log log_debug log_fatal) ],
773             default => sub {
774             $_[0]->chrome->logger->proxy({ proxy_prefix => '[DZ] ' })
775             },
776             );
777              
778             around dump_config => sub {
779             my ($orig, $self) = @_;
780             my $config = $self->$orig;
781             $config->{is_trial} = $self->is_trial;
782             return $config;
783             };
784              
785             has _local_stashes => (
786             is => 'ro',
787             isa => HashRef[ Object ],
788             lazy => 1,
789             default => sub { {} },
790             );
791              
792             has _global_stashes => (
793             is => 'ro',
794             isa => HashRef[ Object ],
795             lazy => 1,
796             default => sub { {} },
797             );
798              
799             #pod =method stash_named
800             #pod
801             #pod my $stash = $zilla->stash_named( $name );
802             #pod
803             #pod This method will return the stash with the given name, or undef if none exists.
804             #pod It looks for a local stash (for this dist) first, then falls back to a global
805             #pod stash (from the user's global configuration).
806             #pod
807             #pod =cut
808              
809             sub stash_named {
810 161     161 1 645 my ($self, $name) = @_;
811              
812 161 100       4840 return $self->_local_stashes->{ $name } if $self->_local_stashes->{$name};
813 158         5322 return $self->_global_stashes->{ $name };
814             }
815              
816             __PACKAGE__->meta->make_immutable;
817             1;
818              
819             #pod =head1 STABILITY PROMISE
820             #pod
821             #pod None.
822             #pod
823             #pod I will try not to break things within any major release. Minor releases are
824             #pod not extensively tested before release. In major releases, anything goes,
825             #pod although I will try to publish a complete list of known breaking changes in any
826             #pod major release.
827             #pod
828             #pod If Dist::Zilla was a tool, it would have yellow and black stripes and there
829             #pod would be no L<UL
830             #pod certification|https://en.wikipedia.org/wiki/UL_(safety_organization)> on it.
831             #pod It is nasty, brutish, and large.
832             #pod
833             #pod =head1 SUPPORT
834             #pod
835             #pod There are usually people on C<irc.perl.org> in C<#distzilla>, even if they're
836             #pod idling.
837             #pod
838             #pod The L<Dist::Zilla website|https://dzil.org/> has several valuable resources for
839             #pod learning to use Dist::Zilla.
840             #pod
841             #pod =head1 SEE ALSO
842             #pod
843             #pod =over 4
844             #pod
845             #pod =item *
846             #pod
847             #pod In the Dist::Zilla distribution:
848             #pod
849             #pod =over 4
850             #pod
851             #pod =item *
852             #pod
853             #pod Plugin bundles:
854             #pod L<@Basic|Dist::Zilla::PluginBundle::Basic>,
855             #pod L<@Filter|Dist::Zilla::PluginBundle::Filter>.
856             #pod
857             #pod =item *
858             #pod
859             #pod Major plugins:
860             #pod L<GatherDir|Dist::Zilla::Plugin::GatherDir>,
861             #pod L<Prereqs|Dist::Zilla::Plugin::Prereqs>,
862             #pod L<AutoPrereqs|Dist::Zilla::Plugin::AutoPrereqs>,
863             #pod L<MetaYAML|Dist::Zilla::Plugin::MetaYAML>,
864             #pod L<MetaJSON|Dist::Zilla::Plugin::MetaJSON>,
865             #pod ...
866             #pod
867             #pod =back
868             #pod
869             #pod =item *
870             #pod
871             #pod On the CPAN:
872             #pod
873             #pod =over 4
874             #pod
875             #pod =item *
876             #pod
877             #pod Search for plugins: L<https://metacpan.org/search?q=Dist::Zilla::Plugin::>
878             #pod
879             #pod =item *
880             #pod
881             #pod Search for plugin bundles: L<https://metacpan.org/search?q=Dist::Zilla::PluginBundle::>
882             #pod
883             #pod =back
884             #pod
885             #pod =back
886              
887             __END__
888              
889             =pod
890              
891             =encoding UTF-8
892              
893             =head1 NAME
894              
895             Dist::Zilla - distribution builder; installer not included!
896              
897             =head1 VERSION
898              
899             version 6.030
900              
901             =head1 DESCRIPTION
902              
903             Dist::Zilla builds distributions of code to be uploaded to the CPAN. In this
904             respect, it is like L<ExtUtils::MakeMaker>, L<Module::Build>, or
905             L<Module::Install>. Unlike those tools, however, it is not also a system for
906             installing code that has been downloaded from the CPAN. Since it's only run by
907             authors, and is meant to be run on a repository checkout rather than on
908             published, released code, it can do much more than those tools, and is free to
909             make much more ludicrous demands in terms of prerequisites.
910              
911             If you have access to the web, you can learn more and find an interactive
912             tutorial at B<L<dzil.org|https://dzil.org/>>. If not, try
913             L<Dist::Zilla::Tutorial>.
914              
915             =head1 PERL VERSION
916              
917             This module should work on any version of perl still receiving updates from
918             the Perl 5 Porters. This means it should work on any version of perl released
919             in the last two to three years. (That is, if the most recently released
920             version is v5.40, then this module should work on both v5.40 and v5.38.)
921              
922             Although it may work on older versions of perl, no guarantee is made that the
923             minimum required version will not be increased. The version may be increased
924             for any reason, and there is no promise that patches will be accepted to lower
925             the minimum required perl.
926              
927             =head1 ATTRIBUTES
928              
929             =head2 name
930              
931             The name attribute (which is required) gives the name of the distribution to be
932             built. This is usually the name of the distribution's main module, with the
933             double colons (C<::>) replaced with dashes. For example: C<Dist-Zilla>.
934              
935             =head2 version
936              
937             This is the version of the distribution to be created.
938              
939             =head2 release_status
940              
941             This attribute sets the release status to one of the
942             L<CPAN::META::Spec|https://metacpan.org/pod/CPAN::Meta::Spec#release_status>
943             values: 'stable', 'testing' or 'unstable'.
944              
945             If the C<$ENV{RELEASE_STATUS}> environment variable exists, its value will
946             be used as the release status.
947              
948             For backwards compatibility, if C<$ENV{RELEASE_STATUS}> does not exist and
949             the C<$ENV{TRIAL}> variable is true, the release status will be 'testing'.
950              
951             Otherwise, the release status will be set from a
952             L<ReleaseStatusProvider|Dist::Zilla::Role::ReleaseStatusProvider>, if one
953             has been configured.
954              
955             For backwards compatibility, setting C<is_trial> true in F<dist.ini> is
956             equivalent to using a C<ReleaseStatusProvider>. If C<is_trial> is false,
957             it has no effect.
958              
959             Only B<one> C<ReleaseStatusProvider> may be used.
960              
961             If no providers are used, the release status defaults to 'stable' unless there
962             is an "_" character in the version, in which case, it defaults to 'testing'.
963              
964             =head2 abstract
965              
966             This is a one-line summary of the distribution. If none is given, one will be
967             looked for in the L</main_module> of the dist.
968              
969             =head2 main_module
970              
971             This is the module where Dist::Zilla might look for various defaults, like
972             the distribution abstract. By default, it's derived from the distribution
973             name. If your distribution is Foo-Bar, and F<lib/Foo/Bar.pm> exists,
974             that's the main_module. Otherwise, it's the shortest-named module in the
975             distribution. This may change!
976              
977             You can override the default by specifying the file path explicitly,
978             ie:
979              
980             main_module = lib/Foo/Bar.pm
981              
982             =head2 license
983              
984             This is the L<Software::License|Software::License> object for this dist's
985             license and copyright.
986              
987             It will be created automatically, if possible, with the
988             C<copyright_holder> and C<copyright_year> attributes. If necessary, it will
989             try to guess the license from the POD of the dist's main module.
990              
991             A better option is to set the C<license> name in the dist's config to something
992             understandable, like C<Perl_5>.
993              
994             =head2 authors
995              
996             This is an arrayref of author strings, like this:
997              
998             [
999             'Ricardo Signes <rjbs@cpan.org>',
1000             'X. Ample, Jr <example@example.biz>',
1001             ]
1002              
1003             This is likely to change at some point in the near future.
1004              
1005             =head2 files
1006              
1007             This is an arrayref of objects implementing L<Dist::Zilla::Role::File> that
1008             will, if left in this arrayref, be built into the dist.
1009              
1010             Non-core code should avoid altering this arrayref, but sometimes there is not
1011             other way to change the list of files. In the future, the representation used
1012             for storing files B<will be changed>.
1013              
1014             =head2 root
1015              
1016             This is the root directory of the dist, as a L<Path::Tiny>. It will
1017             nearly always be the current working directory in which C<dzil> was run.
1018              
1019             =head2 is_trial
1020              
1021             This attribute tells us whether or not the dist will be a trial release,
1022             i.e. whether it has C<release_status> 'testing' or 'unstable'.
1023              
1024             Do not set this directly, it will be derived from C<release_status>.
1025              
1026             =head2 plugins
1027              
1028             This is an arrayref of plugins that have been plugged into this Dist::Zilla
1029             object.
1030              
1031             Non-core code B<must not> alter this arrayref. Public access to this attribute
1032             B<may go away> in the future.
1033              
1034             =head2 distmeta
1035              
1036             This is a hashref containing the metadata about this distribution that will be
1037             stored in META.yml or META.json. You should not alter the metadata in this
1038             hash; use a MetaProvider plugin instead.
1039              
1040             =head2 prereqs
1041              
1042             This is a L<Dist::Zilla::Prereqs> object, which is a thin layer atop
1043             L<CPAN::Meta::Prereqs>, and describes the distribution's prerequisites.
1044              
1045             =head2 logger
1046              
1047             This attribute stores a L<Log::Dispatchouli::Proxy> object, used to log
1048             messages. By default, a proxy to the dist's L<Chrome|Dist::Zilla::Role::Chrome> is
1049             taken.
1050              
1051             The following methods are delegated from the Dist::Zilla object to the logger:
1052              
1053             =over 4
1054              
1055             =item *
1056              
1057             log
1058              
1059             =item *
1060              
1061             log_debug
1062              
1063             =item *
1064              
1065             log_fatal
1066              
1067             =back
1068              
1069             =head1 METHODS
1070              
1071             =head2 register_prereqs
1072              
1073             Allows registration of prerequisites; delegates to
1074             L<Dist::Zilla::Prereqs/register_prereqs> via our L</prereqs> attribute.
1075              
1076             =head2 plugin_named
1077              
1078             my $plugin = $zilla->plugin_named( $plugin_name );
1079              
1080             =head2 plugins_with
1081              
1082             my $roles = $zilla->plugins_with( -SomeRole );
1083              
1084             This method returns an arrayref containing all the Dist::Zilla object's plugins
1085             that perform the named role. If the given role name begins with a dash, the
1086             dash is replaced with "Dist::Zilla::Role::"
1087              
1088             =head2 find_files
1089              
1090             my $files = $zilla->find_files( $finder_name );
1091              
1092             This method will look for a
1093             L<FileFinder|Dist::Zilla::Role::FileFinder>-performing plugin with the given
1094             name and return the result of calling C<find_files> on it. If no plugin can be
1095             found, an exception will be raised.
1096              
1097             =head2 stash_named
1098              
1099             my $stash = $zilla->stash_named( $name );
1100              
1101             This method will return the stash with the given name, or undef if none exists.
1102             It looks for a local stash (for this dist) first, then falls back to a global
1103             stash (from the user's global configuration).
1104              
1105             =head1 STABILITY PROMISE
1106              
1107             None.
1108              
1109             I will try not to break things within any major release. Minor releases are
1110             not extensively tested before release. In major releases, anything goes,
1111             although I will try to publish a complete list of known breaking changes in any
1112             major release.
1113              
1114             If Dist::Zilla was a tool, it would have yellow and black stripes and there
1115             would be no L<UL
1116             certification|https://en.wikipedia.org/wiki/UL_(safety_organization)> on it.
1117             It is nasty, brutish, and large.
1118              
1119             =head1 SUPPORT
1120              
1121             There are usually people on C<irc.perl.org> in C<#distzilla>, even if they're
1122             idling.
1123              
1124             The L<Dist::Zilla website|https://dzil.org/> has several valuable resources for
1125             learning to use Dist::Zilla.
1126              
1127             =head1 SEE ALSO
1128              
1129             =over 4
1130              
1131             =item *
1132              
1133             In the Dist::Zilla distribution:
1134              
1135             =over 4
1136              
1137             =item *
1138              
1139             Plugin bundles:
1140             L<@Basic|Dist::Zilla::PluginBundle::Basic>,
1141             L<@Filter|Dist::Zilla::PluginBundle::Filter>.
1142              
1143             =item *
1144              
1145             Major plugins:
1146             L<GatherDir|Dist::Zilla::Plugin::GatherDir>,
1147             L<Prereqs|Dist::Zilla::Plugin::Prereqs>,
1148             L<AutoPrereqs|Dist::Zilla::Plugin::AutoPrereqs>,
1149             L<MetaYAML|Dist::Zilla::Plugin::MetaYAML>,
1150             L<MetaJSON|Dist::Zilla::Plugin::MetaJSON>,
1151             ...
1152              
1153             =back
1154              
1155             =item *
1156              
1157             On the CPAN:
1158              
1159             =over 4
1160              
1161             =item *
1162              
1163             Search for plugins: L<https://metacpan.org/search?q=Dist::Zilla::Plugin::>
1164              
1165             =item *
1166              
1167             Search for plugin bundles: L<https://metacpan.org/search?q=Dist::Zilla::PluginBundle::>
1168              
1169             =back
1170              
1171             =back
1172              
1173             =head1 AUTHOR
1174              
1175             Ricardo SIGNES 😏 <cpan@semiotic.systems>
1176              
1177             =head1 CONTRIBUTORS
1178              
1179             =for stopwords Ævar Arnfjörð Bjarmason Alastair McGowan-Douglas Alceu Rodrigues de Freitas Junior Alexei Znamensky Alex Vandiver ambs Andrew Rodland Andy Jack Apocalypse ben hengst Bernardo Rechea Branislav Zahradník Brian Fraser Caleb Cushing Chase Whitener Chisel Christian Walde Christopher Bottoms J. Madsen Chris Weyl Cory G Watson csjewell Curtis Brandt Dagfinn Ilmari Mannsåker Damien KRotkine Dan Book Daniel Böhmer Danijel Tasov Dave Lambley O'Neill Rolsky David E. Wheeler Golden H. Adler Steinbrunner Zurborg Davor Cubranic Dimitar Petrov Doug Bell Elvin Aslanov Erik Carlsson Fayland Lam Felix Ostmann Florian Ragwitz Fred Moyer fREW Schmidt gardnerm Gianni Ceccarelli Graham Barr Knop Ollis Grzegorz Rożniecki Håkon Hægland Hans Dieter Pearcey Hunter McMillen Ivan Bessarabov Jakob Voss jantore Jérôme Quelin Jesse Luehrs Vincent JJ Merelo John Napiorkowski jonasbn Jonathan C. Otsuka Rockway Scott Duff Yu Karen Etheridge Kent Fredric Leon Timmermans Lucas Theisen Luc St-Louis Marcel Gruenauer Mark Flickinger Martin McGrath Mary Ehlers Mateu X Matthew Horsfall mauke Michael Conrad G. Schwern Jemmeson Mickey Nasriachi Mike Doherty Mohammad S Anwar Moritz Onken Neil Bowers Nickolay Platonov Nick Tonkin nperez Olivier Mengué Paul Cochrane Paulo Custodio Pedro Melo perlancar (@pc-office) Philippe Bruhat (BooK) raf Randy Stauner Ricardo Signes robertkrimen Rob Hoelz Robin Smidsrød Roy Ivy III Shawn M Moore Shlomi Fish Shoichi Kaji Smylers Steffen Schwigon Steven Haryanto Tatsuhiko Miyagawa Upasana Shukla Van Bugger Vyacheslav Matjukhin Yanick Champoux Yuval Kogman
1180              
1181             =over 4
1182              
1183             =item *
1184              
1185             Ævar Arnfjörð Bjarmason <avarab@gmail.com>
1186              
1187             =item *
1188              
1189             Alastair McGowan-Douglas <alastair.mcgowan@opusvl.com>
1190              
1191             =item *
1192              
1193             Alceu Rodrigues de Freitas Junior <glasswalk3r@yahoo.com.br>
1194              
1195             =item *
1196              
1197             Alexei Znamensky <russoz@cpan.org>
1198              
1199             =item *
1200              
1201             Alex Vandiver <alexmv@mit.edu>
1202              
1203             =item *
1204              
1205             ambs <ambs@cpan.org>
1206              
1207             =item *
1208              
1209             Andrew Rodland <andrew@hbslabs.com>
1210              
1211             =item *
1212              
1213             Andy Jack <andyjack@cpan.org>
1214              
1215             =item *
1216              
1217             Apocalypse <APOCAL@cpan.org>
1218              
1219             =item *
1220              
1221             ben hengst <ben.hengst@gmail.com>
1222              
1223             =item *
1224              
1225             Bernardo Rechea <brbpub@gmail.com>
1226              
1227             =item *
1228              
1229             Branislav Zahradník <happy.barney@gmail.com>
1230              
1231             =item *
1232              
1233             Brian Fraser <fraserbn@gmail.com>
1234              
1235             =item *
1236              
1237             Caleb Cushing <xenoterracide@gmail.com>
1238              
1239             =item *
1240              
1241             Chase Whitener <cwhitener@gmail.com>
1242              
1243             =item *
1244              
1245             Chisel <chisel@chizography.net>
1246              
1247             =item *
1248              
1249             Christian Walde <walde.christian@googlemail.com>
1250              
1251             =item *
1252              
1253             Christopher Bottoms <molecules@users.noreply.github.com>
1254              
1255             =item *
1256              
1257             Christopher J. Madsen <cjm@cjmweb.net>
1258              
1259             =item *
1260              
1261             Chris Weyl <cweyl@alumni.drew.edu>
1262              
1263             =item *
1264              
1265             Cory G Watson <gphat@onemogin.com>
1266              
1267             =item *
1268              
1269             csjewell <perl@csjewell.fastmail.us>
1270              
1271             =item *
1272              
1273             Curtis Brandt <curtisjbrandt@gmail.com>
1274              
1275             =item *
1276              
1277             Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1278              
1279             =item *
1280              
1281             Damien KRotkine <dkrotkine@booking.com>
1282              
1283             =item *
1284              
1285             Dan Book <grinnz@gmail.com>
1286              
1287             =item *
1288              
1289             Daniel Böhmer <post@daniel-boehmer.de>
1290              
1291             =item *
1292              
1293             Danijel Tasov <dt@korn.shell.la>
1294              
1295             =item *
1296              
1297             Dave Lambley <dave@lambley.me.uk>
1298              
1299             =item *
1300              
1301             Dave O'Neill <dmo@dmo.ca>
1302              
1303             =item *
1304              
1305             Dave Rolsky <autarch@urth.org>
1306              
1307             =item *
1308              
1309             David E. Wheeler <david@justatheory.com>
1310              
1311             =item *
1312              
1313             David Golden <dagolden@cpan.org>
1314              
1315             =item *
1316              
1317             David H. Adler <dha@pobox.com>
1318              
1319             =item *
1320              
1321             David Steinbrunner <dsteinbrunner@pobox.com>
1322              
1323             =item *
1324              
1325             David Zurborg <port@david-zurb.org>
1326              
1327             =item *
1328              
1329             Davor Cubranic <cubranic@stat.ubc.ca>
1330              
1331             =item *
1332              
1333             Dimitar Petrov <mitakaa@gmail.com>
1334              
1335             =item *
1336              
1337             Doug Bell <doug@preaction.me>
1338              
1339             =item *
1340              
1341             Doug Bell <madcityzen@gmail.com>
1342              
1343             =item *
1344              
1345             Elvin Aslanov <rwp.primary@gmail.com>
1346              
1347             =item *
1348              
1349             Erik Carlsson <info@code301.com>
1350              
1351             =item *
1352              
1353             Fayland Lam <fayland@gmail.com>
1354              
1355             =item *
1356              
1357             Felix Ostmann <felix.ostmann@gmail.com>
1358              
1359             =item *
1360              
1361             Florian Ragwitz <rafl@debian.org>
1362              
1363             =item *
1364              
1365             Fred Moyer <fred@redhotpenguin.com>
1366              
1367             =item *
1368              
1369             fREW Schmidt <frioux@gmail.com>
1370              
1371             =item *
1372              
1373             gardnerm <gardnerm@gsicommerce.com>
1374              
1375             =item *
1376              
1377             Gianni Ceccarelli <gianni.ceccarelli@net-a-porter.com>
1378              
1379             =item *
1380              
1381             Graham Barr <gbarr@pobox.com>
1382              
1383             =item *
1384              
1385             Graham Knop <haarg@haarg.org>
1386              
1387             =item *
1388              
1389             Graham Ollis <perl@wdlabs.com>
1390              
1391             =item *
1392              
1393             Graham Ollis <plicease@cpan.org>
1394              
1395             =item *
1396              
1397             Grzegorz Rożniecki <xaerxess@gmail.com>
1398              
1399             =item *
1400              
1401             Håkon Hægland <hakon.hagland@gmail.com>
1402              
1403             =item *
1404              
1405             Hans Dieter Pearcey <hdp@weftsoar.net>
1406              
1407             =item *
1408              
1409             Hunter McMillen <mcmillhj@gmail.com>
1410              
1411             =item *
1412              
1413             Ivan Bessarabov <ivan@bessarabov.ru>
1414              
1415             =item *
1416              
1417             Jakob Voss <jakob@nichtich.de>
1418              
1419             =item *
1420              
1421             jantore <jantore@32k.org>
1422              
1423             =item *
1424              
1425             Jérôme Quelin <jquelin@gmail.com>
1426              
1427             =item *
1428              
1429             Jesse Luehrs <doy@tozt.net>
1430              
1431             =item *
1432              
1433             Jesse Vincent <jesse@bestpractical.com>
1434              
1435             =item *
1436              
1437             JJ Merelo <jjmerelo@gmail.com>
1438              
1439             =item *
1440              
1441             John Napiorkowski <jjnapiork@cpan.org>
1442              
1443             =item *
1444              
1445             jonasbn <jonasbn@gmail.com>
1446              
1447             =item *
1448              
1449             Jonathan C. Otsuka <djgoku@gmail.com>
1450              
1451             =item *
1452              
1453             Jonathan Rockway <jrockway@cpan.org>
1454              
1455             =item *
1456              
1457             Jonathan Scott Duff <duff@pobox.com>
1458              
1459             =item *
1460              
1461             Jonathan Yu <jawnsy@cpan.org>
1462              
1463             =item *
1464              
1465             Karen Etheridge <ether@cpan.org>
1466              
1467             =item *
1468              
1469             Kent Fredric <kentfredric@gmail.com>
1470              
1471             =item *
1472              
1473             Kent Fredric <kentnl@gentoo.org>
1474              
1475             =item *
1476              
1477             Leon Timmermans <fawaka@gmail.com>
1478              
1479             =item *
1480              
1481             Lucas Theisen <lucastheisen@pastdev.com>
1482              
1483             =item *
1484              
1485             Luc St-Louis <lucs@pobox.com>
1486              
1487             =item *
1488              
1489             Marcel Gruenauer <hanekomu@gmail.com>
1490              
1491             =item *
1492              
1493             Mark Flickinger <mark.flickinger@grantstreet.com>
1494              
1495             =item *
1496              
1497             Martin McGrath <mcgrath.martin@gmail.com>
1498              
1499             =item *
1500              
1501             Mary Ehlers <regina.verb.ae@gmail.com>
1502              
1503             =item *
1504              
1505             Mateu X Hunter <hunter@missoula.org>
1506              
1507             =item *
1508              
1509             Matthew Horsfall <wolfsage@gmail.com>
1510              
1511             =item *
1512              
1513             mauke <l.mai@web.de>
1514              
1515             =item *
1516              
1517             Michael Conrad <mike@nrdvana.net>
1518              
1519             =item *
1520              
1521             Michael G. Schwern <schwern@pobox.com>
1522              
1523             =item *
1524              
1525             Michael Jemmeson <mjemmeson@cpan.org>
1526              
1527             =item *
1528              
1529             Mickey Nasriachi <mickey@cpan.org>
1530              
1531             =item *
1532              
1533             Mike Doherty <mike@mikedoherty.ca>
1534              
1535             =item *
1536              
1537             Mohammad S Anwar <mohammad.anwar@yahoo.com>
1538              
1539             =item *
1540              
1541             Moritz Onken <onken@netcubed.de>
1542              
1543             =item *
1544              
1545             Neil Bowers <neil@bowers.com>
1546              
1547             =item *
1548              
1549             Nickolay Platonov <nickolay@desktop.(none)>
1550              
1551             =item *
1552              
1553             Nick Tonkin <1nickt@users.noreply.github.com>
1554              
1555             =item *
1556              
1557             nperez <nperez@cpan.org>
1558              
1559             =item *
1560              
1561             Olivier Mengué <dolmen@cpan.org>
1562              
1563             =item *
1564              
1565             Paul Cochrane <paul@liekut.de>
1566              
1567             =item *
1568              
1569             Paulo Custodio <pauloscustodio@gmail.com>
1570              
1571             =item *
1572              
1573             Pedro Melo <melo@simplicidade.org>
1574              
1575             =item *
1576              
1577             perlancar (@pc-office) <perlancar@gmail.com>
1578              
1579             =item *
1580              
1581             Philippe Bruhat (BooK) <book@cpan.org>
1582              
1583             =item *
1584              
1585             raf <68724930+rafork@users.noreply.github.com>
1586              
1587             =item *
1588              
1589             Randy Stauner <rwstauner@cpan.org>
1590              
1591             =item *
1592              
1593             Ricardo Signes <rjbs@semiotic.systems>
1594              
1595             =item *
1596              
1597             robertkrimen <robertkrimen@gmail.com>
1598              
1599             =item *
1600              
1601             Rob Hoelz <rob@hoelz.ro>
1602              
1603             =item *
1604              
1605             Robin Smidsrød <robin@smidsrod.no>
1606              
1607             =item *
1608              
1609             Roy Ivy III <rivy@cpan.org>
1610              
1611             =item *
1612              
1613             Shawn M Moore <sartak@gmail.com>
1614              
1615             =item *
1616              
1617             Shlomi Fish <shlomif@shlomifish.org>
1618              
1619             =item *
1620              
1621             Shoichi Kaji <skaji@cpan.org>
1622              
1623             =item *
1624              
1625             Smylers <Smylers@stripey.com>
1626              
1627             =item *
1628              
1629             Steffen Schwigon <ss5@renormalist.net>
1630              
1631             =item *
1632              
1633             Steven Haryanto <stevenharyanto@gmail.com>
1634              
1635             =item *
1636              
1637             Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1638              
1639             =item *
1640              
1641             Upasana Shukla <me@upasana.me>
1642              
1643             =item *
1644              
1645             Van de Bugger <van.de.bugger@gmail.com>
1646              
1647             =item *
1648              
1649             Vyacheslav Matjukhin <mmcleric@yandex-team.ru>
1650              
1651             =item *
1652              
1653             Yanick Champoux <yanick@babyl.dyndns.org>
1654              
1655             =item *
1656              
1657             Yuval Kogman <nothingmuch@woobling.org>
1658              
1659             =back
1660              
1661             =head1 COPYRIGHT AND LICENSE
1662              
1663             This software is copyright (c) 2023 by Ricardo SIGNES.
1664              
1665             This is free software; you can redistribute it and/or modify it under
1666             the same terms as the Perl 5 programming language system itself.
1667              
1668             =cut