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