File Coverage

blib/lib/Dist/Zilla/Plugin/Manifest/Write.pm
Criterion Covered Total %
statement 176 187 94.1
branch 31 44 70.4
condition 8 13 61.5
subroutine 36 37 97.3
pod 3 3 100.0
total 254 284 89.4


line stmt bran cond sub pod time code
1             # ---------------------------------------------------------------------- copyright and license ---
2             #
3             # file: lib/Dist/Zilla/Plugin/Manifes/Write.pm
4             #
5             # Copyright © 2015, 2016 Van de Bugger.
6             #
7             # This file is part of perl-Dist-Zilla-Plugin-Manifest-Write.
8             #
9             # perl-Dist-Zilla-Plugin-Manifest-Write is free software: you can redistribute it and/or modify
10             # it under the terms of the GNU General Public License as published by the Free Software
11             # Foundation, either version 3 of the License, or (at your option) any later version.
12             #
13             # perl-Dist-Zilla-Plugin-Manifest-Write is distributed in the hope that it will be useful, but
14             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15             # PARTICULAR PURPOSE. See the GNU General Public License for more details.
16             #
17             # You should have received a copy of the GNU General Public License along with
18             # perl-Dist-Zilla-Plugin-Manifest-Write. If not, see <http://www.gnu.org/licenses/>.
19             #
20             # ---------------------------------------------------------------------- copyright and license ---
21              
22             #pod =for :this This is C<Dist::Zilla::Plugin::Manifest::Write> module documentation. Read this if you are going to hack or
23             #pod extend C<Manifest::Write>.
24             #pod
25             #pod =for :those If you want to have annotated distribution manifest, read the L<plugin user
26             #pod manual|Dist::Zilla::Plugin::Manifest::Write::Manual>. General topics like getting source, building, installing, bug
27             #pod reporting and some others are covered in the F<README>.
28             #pod
29             #pod =head1 DESCRIPTION
30             #pod
31             #pod In order to add a manifest file to the distribution, C<Dist::Zilla::Plugin::Manifest::Write> class consumes
32             #pod C<Dist::Zilla::Role::FileGatherer> role. To meet the role requirements, the class implements
33             #pod C<gather_files> method. Other methods are supporting helpers for this one.
34             #pod
35             #pod Most of attributes are initialized by builders for easier customization by subclassing. Code is
36             #pod also divided into small methods for the same purpose.
37             #pod
38             #pod =head1 SEE ALSO
39             #pod
40             #pod =for :list
41             #pod = L<Dist::Zilla>
42             #pod = L<Dist::Zilla::Role>
43             #pod = L<Dist::Zilla::Role::Plugin>
44             #pod = L<Dist::Zilla::Role::FileInjector>
45             #pod = L<Dist::Zilla::Role::FileGatherer>
46             #pod = L<Dist::Zilla::Plugin::Manifest>
47             #pod = L<Dist::Zilla::Plugin::Manifest::Write::Manual>
48             #pod
49             #pod =cut
50              
51             # --------------------------------------------------------------------------------------------------
52              
53             package Dist::Zilla::Plugin::Manifest::Write;
54              
55 2     2   2339348 use Moose; # Let `perlcritic` shut up: it complains on code (`$VERSION`) before `strict`.
  2         4  
  2         19  
56 2     2   9841 use namespace::autoclean;
  2         2  
  2         16  
57              
58             # PODNAME: Dist::Zilla::Plugin::Manifest::Write
59             # ABSTRACT: Have annotated distribution manifest
60             our $VERSION = 'v0.9.6_01'; # TRIAL VERSION
61              
62             with 'Dist::Zilla::Role::FileGatherer';
63             with 'Dist::Zilla::Role::BeforeBuild';
64             with 'Dist::Zilla::Role::BeforeArchive';
65             with 'Dist::Zilla::Role::ErrorLogger';
66             with 'Dist::Zilla::Role::FileFinderUser' => {
67             finder_arg_names => [ qw{ exclude_files } ],
68             default_finders => [ ':NoFiles' ],
69             };
70              
71 2     2   1407 use Dist::Zilla::File::FromCode;
  2         134114  
  2         89  
72 2     2   18 use ExtUtils::Manifest qw{};
  2         2  
  2         37  
73 2     2   9 use List::Util;
  2         5  
  2         146  
74 2     2   1402 use Module::Util qw{ is_valid_module_name };
  2         3146  
  2         150  
75 2     2   13 use Path::Tiny qw{};
  2         3  
  2         35  
76 2     2   1136 use Readonly;
  2         6789  
  2         110  
77 2     2   13 use Set::Object qw{};
  2         2  
  2         56  
78 2     2   17 use String::RewritePrefix;
  2         2  
  2         23  
79              
80 2     2   500 use Dist::Zilla::Role::File 5.023 (); # Hint for `AutoPrereqs`.
  2         56  
  2         5711  
81             # We do not consume the role but just require the specified version. Before this version
82             # `_added_by` was a `Str`, not `ArrayRef`.
83              
84             # --------------------------------------------------------------------------------------------------
85              
86             # File deeds:
87             Readonly our $SOURCE => 1;
88             Readonly our $META => 2;
89             Readonly our $OTHER => 3;
90             # File breeds:
91             Readonly our $ADDED => 4;
92             Readonly our $BUILT => 5;
93              
94             # --------------------------------------------------------------------------------------------------
95              
96             #pod =head1 FUNCTIONS
97             #pod
98             #pod I would expect to find these functions in C<Dist::Zilla>. Actually, C<Dist::Zilla::Util> defines
99             #pod the function C<expand_config_package_name>, but that function "is likely to change or go away" and
100             #pod there is no reverse transformation.
101             #pod
102             #pod =cut
103              
104             # --------------------------------------------------------------------------------------------------
105              
106             #pod =func __plugin_moniker
107             #pod
108             #pod $str = __plugin_moniker( 'Dist::Zilla::Plugin::Name' ); # 'Name'
109             #pod $str = __plugin_moniker( 'Non::Standard::Name' ); # '=Non::Standard::Name'
110             #pod $str = __plugin_moniker( $plugin );
111             #pod
112             #pod The function takes either reference to a plugin object or a string, package name, and returns
113             #pod C<Dist::Zilla> plugin moniker: If its package name begins with C<Dist::Zilla::Plugin::>, this
114             #pod common prefix is dropped, otherwise the package name prepended with C<=>.
115             #pod
116             #pod =cut
117              
118             {
119              
120             my $package2moniker = {
121             'Dist::Zilla::Plugin::' => '',
122             'Dist::Zilla::Role::' => '*',
123             '' => '=',
124             };
125              
126             sub __plugin_moniker($) { ## no critic ( ProhibitSubroutinePrototypes )
127 98     98   132 my ( $arg ) = @_;
128 98 50       347 if ( my $blessed = blessed( $arg ) ) {
129 98         131 $arg = $blessed;
130             };
131 98         419 return String::RewritePrefix->rewrite( $package2moniker, $arg );
132             };
133              
134             }
135              
136             # --------------------------------------------------------------------------------------------------
137              
138             #pod =func __package_name
139             #pod
140             #pod $str = __package_name( 'Name' ); # returns 'Dist::Zilla::Plugin::Name'
141             #pod $str = __package_name( '=Name' ); # returns 'Name'
142             #pod $str = __package_name( $plugin );
143             #pod
144             #pod This is operation opposite to C<__plugin_moniker>. It takes either reference to plugin object, or
145             #pod string, plugin moniker, and returns package name.
146             #pod
147             #pod This function is similar to C<expand_config_package_name> from C<Dist::Zilla::Util>, with minor
148             #pod difference: this function works with plugins only (not with plugin bundles and stashes), and
149             #pod accepts also reference to plugin object.
150             #pod
151             #pod =cut
152              
153             {
154              
155             my $moniker2package = {
156             '=' => '',
157             '' => 'Dist::Zilla::Plugin::',
158             };
159              
160             sub __package_name($) { ## no critic ( ProhibitSubroutinePrototypes )
161 0     0   0 my ( $arg ) = @_;
162 0 0       0 if ( my $blessed = blessed( $arg ) ) {
163 0         0 return $blessed;
164             };
165 0         0 return String::RewritePrefix->rewrite( $moniker2package, $arg );
166             };
167              
168             }
169              
170             # --------------------------------------------------------------------------------------------------
171              
172             #pod =Method BUILDARGS
173             #pod
174             #pod The method splits values of C<source_providers> option into separate plugin names using whitespaces
175             #pod as delimiters, combines result of splitting with C<source_provider> option values, then filters out
176             #pod empty values. Resulting C<ArrayRef> saved as C<source_providers> options.
177             #pod
178             #pod The same for C<metainfo_providers> and C<metainfo_provider> options.
179             #pod
180             #pod =cut
181              
182             around BUILDARGS => sub {
183             my ( $orig, $class, $args ) = @_;
184             for my $type ( qw{ source metainfo } ) {
185             my $provider = $type . '_provider';
186             my $providers = $type . '_providers';
187             if ( exists( $args->{ $provider } ) or exists( $args->{ $providers } ) ) {
188             $args->{ $providers } = [
189             grep( # Filter out empty values.
190             { $_ ne '' }
191             @{ $args->{ $provider } or [] }, # Get singular option values as-is.
192             map( { split( m{\s+}x, $_ ) } @{ $args->{ $providers } or [] } )
193             # Split plural option values.
194             )
195             ];
196             };
197             };
198             return $class->$orig( $args );
199             };
200              
201             # --------------------------------------------------------------------------------------------------
202              
203             has _heading => (
204             isa => 'Str',
205             is => 'ro',
206             lazy => 1,
207             builder => '_build_heading',
208             );
209              
210             sub _build_heading {
211 20     20   33 my ( $self ) = @_;
212 20         1089 return sprintf( "# This file was generated with %s %s.", blessed( $self ), $self->VERSION );
213             };
214              
215             # --------------------------------------------------------------------------------------------------
216              
217             #pod =attr manifest
218             #pod
219             #pod Name of manifest file to write.
220             #pod
221             #pod C<Str>, read-only. Default value is C<'MANIFEST'>.
222             #pod
223             #pod =cut
224              
225             has manifest => (
226             isa => 'Str',
227             is => 'ro',
228             default => 'MANIFEST',
229             );
230              
231             has _manifest_file => (
232             isa => 'Dist::Zilla::Role::File',
233             is => 'ro',
234             lazy => 1,
235             init_arg => undef,
236             builder => '_build_manifest_file',
237             );
238              
239             sub _build_manifest_file {
240 20     20   38 my ( $self ) = @_;
241 20         577 my $zilla = $self->zilla;
242             return Dist::Zilla::File::FromCode->new( {
243             name => $self->manifest,
244             code_return_type => 'bytes',
245             code => sub {
246 20     20   819130 my @list;
247 20         46 my $files = Set::Object->new( @{ $zilla->files } );
  20         561  
248 20         462 $files->remove( @{ $self->found_files } );
  20         135  
249             # Process all files in alphbetical order.
250 20         36 for my $file ( sort( { $a->name cmp $b->name } @{ $files } ) ) {
  144         10577  
  20         1472  
251 97         1722 push( @list, {
252             name => $self->_file_name( $file ),
253             comment => $self->_file_comment( $file )
254             } );
255             };
256 20         284 $self->abort_if_error(); # `_file_comment` methods may generate errors.
257             # Find width of filename column.
258 20         981 my $width = List::Util::max( map( { length( $_->{ name } ) } @list ) );
  97         152  
259             # Output formats.
260 20         44 my $body = "%*s # %s";
261             return
262             join(
263             "\n",
264             $self->_heading,
265 20         771 map( { sprintf( $body, - $width, $_->{ name }, $_->{ comment } ) } @list ),
  97         553  
266             ) . "\n";
267             },
268 20         901 } );
269             };
270              
271             # --------------------------------------------------------------------------------------------------
272              
273             #pod =attr manifest_skip
274             #pod
275             #pod Name of manifest.skip file to write.
276             #pod
277             #pod C<Str>, read-only. Default value is C<'MANIFEST.SKIP'>.
278             #pod
279             #pod =cut
280              
281             has manifest_skip => (
282             isa => 'Str',
283             is => 'ro',
284             default => 'MANIFEST.SKIP',
285             );
286              
287              
288             has _manifest_skip_file => (
289             isa => 'Maybe[Dist::Zilla::Role::File]',
290             is => 'ro',
291             lazy => 1,
292             init_arg => undef,
293             builder => '_build_manifest_skip',
294             );
295              
296             sub _build_manifest_skip {
297 20     20   43 my ( $self ) = @_;
298 20 100       870 return if $self->manifest_skip eq '';
299             return Dist::Zilla::File::FromCode->new( {
300             name => $self->manifest_skip,
301             code_return_type => 'bytes',
302             code => sub {
303 19     19   15441 my $default = Path::Tiny::path( $ExtUtils::Manifest::DEFAULT_MSKIP );
304             return join( "\n",
305             $self->_heading,
306             '',
307 19         1085 map( { "^" . quotemeta( $_->name ) . "\$" } @{ $self->found_files } ),
  25         293  
  19         78  
308             '',
309             # `ExtUtils::Manifest` recognizes `#!include_default` directive. Unfortunately,
310             # `Module::Manifest` does not. So I have to copy default `MANIFEST.SKIP`.
311             "# The rest is a copy of $default file:",
312             '',
313             $default->slurp_utf8(),
314             '# end of file #'
315             ) . "\n";
316             },
317 19         718 } );
318             };
319              
320             # --------------------------------------------------------------------------------------------------
321              
322             #pod =attr source_providers
323             #pod
324             #pod List of plugin names. Enlisted plugins are considered as source file providers. A file added to
325             #pod distribution by any of these plugins is considered as source file.
326             #pod
327             #pod C<ArrayRef[Str]>, read-only, default value is empty array. Init argument (and config file
328             #pod multi-value option) name is C<source_provider>. (C<BUILDARGS> also handles C<source_providers>
329             #pod option.)
330             #pod
331             #pod =cut
332              
333             has source_providers => (
334             isa => 'ArrayRef[Str]',
335             is => 'ro',
336             required => 1,
337             lazy => 1,
338             builder => '_build_source_providers',
339             );
340              
341             sub _build_source_providers {
342 2     2   72 return [];
343             };
344              
345             # --------------------------------------------------------------------------------------------------
346              
347             #pod =attr metainfo_providers
348             #pod
349             #pod Like C<source_providers> but enlists meta info file providers.
350             #pod
351             #pod C<ArrayRef[Str]>, read-only, default value is C<CPANFile>, C<Manifest>, C<MetaYAML>, C<MetaJSON>,
352             #pod and the plugin itself. Init argument (and config file multi-value option) name is
353             #pod C<metainfo_provider>. (C<BUILDARGS> also handles C<metainfo_providers> option.)
354             #pod
355             #pod Note: Do not confuse C<Manifest::Write>'s term I<metainfo providers> with C<Dist::Zilla>'s
356             #pod C<MetaProvider> role. Plugins do C<MetaProvider> role provide I<metadata>, while C<Manifest::Write>
357             #pod is interested in plugins which adds I<files> containing metadata to the distribution (such plugins
358             #pod do C<FileInjector> role, not C<MetaProvider>).
359             #pod
360             #pod =cut
361              
362             has metainfo_providers => (
363             isa => 'ArrayRef[Str]',
364             is => 'ro',
365             required => 1,
366             lazy => 1,
367             builder => '_build_metainfo_providers',
368             );
369              
370             sub _build_metainfo_providers {
371 17     17   28 my ( $self ) = @_;
372 17         513 my @list = ( qw{ CPANFile Manifest MetaYAML MetaJSON }, $self->plugin_name );
373 17 50       711 if ( $self->strict >= 0 ) {
374 17         48 @list = grep( { $self->_is_injector( $_ ) } @list );
  85         776  
375             };
376 17         1388 return \@list;
377             };
378              
379             sub _is_injector {
380 85     85   110 my ( $self, $name ) = @_;
381 85         2373 my $plugin = $self->zilla->plugin_named( $name );
382 85   66     25419 return $plugin && $plugin->does( 'Dist::Zilla::Role::FileInjector' );
383             };
384              
385             # --------------------------------------------------------------------------------------------------
386              
387             #pod =attr strict
388             #pod
389             #pod Strictness of checking source and metainfo provider names: -1 (no checks), 0 (some mistakes are
390             #pod fatal, some are not), or 1 (all mistakes are fatal).
391             #pod
392             #pod C<Int>, read-only. Default is 1.
393             #pod
394             #pod See L<Dist::Zilla::Plugin::Manifest::Write::Manual/"strict">.
395             #pod
396             #pod =cut
397              
398             has strict => (
399             isa => 'Int',
400             is => 'ro',
401             default => 1,
402             );
403              
404             # --------------------------------------------------------------------------------------------------
405              
406             #pod =attr show_mungers
407             #pod
408             #pod If C<1>, file mungers will be included into annotation. By default mungers are not included.
409             #pod
410             #pod C<Bool>, read-only. Default is C<0>.
411             #pod
412             #pod =cut
413              
414             has show_mungers => (
415             isa => 'Bool',
416             is => 'ro',
417             default => 0,
418             );
419              
420             # --------------------------------------------------------------------------------------------------
421              
422             #pod =attr deeds
423             #pod
424             #pod This attribute maps internal file deed constants (C<SOURCE>, C<META>, C<OTHER>) to user-visible
425             #pod names used in manifest (project name, C<metainfo>, and C<3rd party> respectively).
426             #pod
427             #pod C<HashRef[Str]>, read-only.
428             #pod
429             #pod =cut
430              
431             has deeds => (
432             isa => 'HashRef[Str]',
433             is => 'ro',
434             lazy => 1,
435             builder => '_build_deeds',
436             init_arg => undef,
437             );
438              
439             sub _build_deeds {
440 20     20   31 my ( $self ) = @_;
441             return {
442 20         579 $SOURCE => $self->zilla->name,
443             $META => 'metainfo',
444             $OTHER => '3rd party',
445             };
446             };
447              
448             # --------------------------------------------------------------------------------------------------
449              
450             #pod =attr breeds
451             #pod
452             #pod This attribute maps internal file deed constants (C<$ADDED> and C<$BUILT>) to user-visible names
453             #pod used in manifest. By default user-visible breed names are the same as internal identifiers.
454             #pod
455             #pod C<HashRef[Str]>, read-only.
456             #pod
457             #pod =cut
458              
459             has breeds => (
460             isa => 'HashRef[Str]',
461             is => 'ro',
462             lazy => 1,
463             builder => '_build_breeds',
464             init_arg => undef,
465             );
466              
467             sub _build_breeds {
468 20     20   27 my ( $self ) = @_;
469             return {
470 20         101 $ADDED => 'added',
471             $BUILT => 'built',
472             };
473             };
474              
475             # --------------------------------------------------------------------------------------------------
476              
477             #pod =attr _providers
478             #pod
479             #pod This attribute maps provider names to file deeds. It makes C<_file_deed> method implementation
480             #pod simpler and faster.
481             #pod
482             #pod C<HashRef[Str]>, read-only, not an init arg.
483             #pod
484             #pod =cut
485              
486             has _providers => (
487             isa => 'HashRef[Int]',
488             is => 'ro',
489             required => 1,
490             lazy => 1,
491             builder => '_build_providers',
492             init_arg => undef,
493             );
494              
495             sub _build_providers {
496 21     21   30 my ( $self ) = @_;
497 21         55 my $providers = {};
498 21         30 for my $provider ( @{ $self->source_providers } ) {
  21         840  
499 29         269 $providers->{ $provider } = $SOURCE;
500             };
501 21         108 for my $provider ( @{ $self->metainfo_providers } ) {
  21         836  
502 36 100 66     183 if ( exists( $providers->{ $provider } ) and $providers->{ $provider } != $META ) {
503             # The same plugin name may be specified in the same option multiple times.
504 1         11 $self->log_error( [
505             "%s cannot be a source provider and a metainfo provider simultaneously",
506             $provider
507             ] );
508             } else {
509 35         147 $providers->{ $provider } = $META;
510             };
511             };
512 21         1096 return $providers;
513             };
514              
515             # --------------------------------------------------------------------------------------------------
516              
517             #pod =attr _dw
518             #pod
519             #pod Max length of user-visible deed names.
520             #pod
521             #pod C<Int>, read-only, not an init arg.
522             #pod
523             #pod =cut
524              
525             has _dw => (
526             isa => 'Int',
527             is => 'ro',
528             lazy => 1,
529             builder => '_build_dw',
530             init_arg => undef,
531             );
532              
533             sub _build_dw {
534 20     20   40 my ( $self ) = @_;
535 20         38 return List::Util::max( map( { length( $_ ) } values( %{ $self->deeds } ) ) );
  60         980  
  20         745  
536             };
537              
538             # --------------------------------------------------------------------------------------------------
539              
540             around found_files => sub {
541             my ( $orig, $self ) = @_;
542             my $found = $self->$orig();
543             push( @$found, $self->_manifest_skip_file ) if defined $self->_manifest_skip_file;
544             return $found;
545             };
546              
547             # --------------------------------------------------------------------------------------------------
548              
549             #pod =method before_build
550             #pod
551             #pod This method is called by C<Dist::Zilla> automatically before build. The method checks validity of
552             #pod source and metainfo provider names.
553             #pod
554             #pod =cut
555              
556             sub before_build {
557 21     21 1 1494695 my ( $self ) = @_;
558 21 100       933 if ( $self->strict >= 0 ) {
559 20 100       719 my $log_warning = $self->strict > 0 ? 'log_error' : 'log';
560 20         575 my $zilla = $self->zilla;
561 20         109 for my $provider ( @{ $self->source_providers }, @{ $self->metainfo_providers } ) {
  20         835  
  20         810  
562 62 100       3730 if ( my $plugin = $zilla->plugin_named( $provider ) ) {
563 58 100       5843 if ( not $plugin->does( 'Dist::Zilla::Role::FileInjector' ) ) {
564 1         37 $self->log_error( [ "%s does not do FileInjector role", $provider ] );
565             };
566             } else {
567 4         1600 $self->$log_warning( [ "%s is not a plugin", $provider ] );
568             };
569             };
570 20         1760 $self->_providers(); # Initiate building the attribute. It can report errors.
571 20         124 $self->abort_if_error();
572             };
573 20         899 return;
574             };
575              
576             # --------------------------------------------------------------------------------------------------
577              
578             #pod =method before_archive
579             #pod
580             #pod This method is called by C<Dist::Zilla> automatically before build the archive. The method prunes
581             #pod files found by file finders specified in the C<exclude_files> option.
582             #pod
583             #pod =cut
584              
585             sub before_archive {
586 2     2 1 6286 my ( $self ) = @_;
587 2         71 my $zilla = $self->zilla;
588 2         14 for my $file ( @{ $self->found_files } ) {
  2         8  
589 5         202 $zilla->prune_file( $file );
590             };
591 2         168 return;
592             };
593              
594             # --------------------------------------------------------------------------------------------------
595              
596             #pod =method gather_files
597             #pod
598             #pod This is the main method of the class. It adds a file with name C<< $self->manifest >> to the
599             #pod distribution. File content is specified by C<CodeRef> to postpone actual file creation. Being
600             #pod evaluated, the code iterates through all the files in distribution in alphabetical order, and
601             #pod fulfills the manifest with filenames and comments.
602             #pod
603             #pod =cut
604              
605             sub gather_files {
606 20     20 1 162413 my ( $self, $arg ) = @_;
607 20         843 $self->add_file( $self->_manifest_file );
608 20 100       7142 $self->add_file( $self->_manifest_skip_file ) if defined $self->_manifest_skip_file;
609 20         6209 return;
610             };
611              
612             # --------------------------------------------------------------------------------------------------
613              
614             #pod =method _file_name
615             #pod
616             #pod $str = $self->_file_name( $file );
617             #pod
618             #pod Returns filename to be used in manifest. If filename does not include special characters (spaces,
619             #pod backslashes (C<\>), apostrophes (C<'>), hashes (C<#>)), it is the same as real filename, otherwise
620             #pod filename encoded like Perl single-quoted string: backslashes and apostrophes are escaped, and
621             #pod entire filename is enclosed into apostrophes.
622             #pod
623             #pod =cut
624              
625             sub _file_name {
626 97     97   128 my ( $self, $file ) = @_;
627 97         292 my $name = $file->name;
628 97 100       4214 if ( $name =~ m{[\ '\\#]}x ) {
629 5         17 $name =~ s{([\\'])}{\\$1}gx;
630 5         11 $name = "'" . $name . "'";
631             };
632 97         271 return $name;
633             };
634              
635             # --------------------------------------------------------------------------------------------------
636              
637             #pod =method _file_comment
638             #pod
639             #pod $str = $self->_file_comment( $file ); # Without leading sharp.
640             #pod
641             #pod The method returns comment to be used with the specified file. Comment should not include leading
642             #pod sharp character (C<#>).
643             #pod
644             #pod =cut
645              
646             sub _file_comment {
647 97     97   142 my ( $self, $file ) = @_;
648 97         184 my $history = $self->_file_history( $file );
649 97         182 my $deed = $self->_file_deed( $file, $history );
650 97         256 my $breed = $self->_file_breed( $file, $history );
651 97         172 my $adder = $self->_file_adder( $file, $history );
652 97         236 my @mungers = $self->_file_mungers( $file, $history );
653             my $comment =
654             sprintf(
655             "%*s file %s by %s",
656             $self->_dw,
657             $self->deeds->{ $deed } || $deed || '(*UNKNOWN*)',
658 97 100 50     3373 $self->breeds->{ $breed } || $breed || '(*UNKNOWN*)',
      50        
659             $adder
660             ) .
661             (
662             @mungers ? (
663             ' and munged by ' . join( ', ', @mungers )
664             ) : (
665             ''
666             )
667             );
668 97         562 return $comment;
669             };
670              
671             # --------------------------------------------------------------------------------------------------
672              
673             #pod =method _file_history
674             #pod
675             #pod $arrayref = $self->_file_history( $file );
676             #pod
677             #pod The method calls C<_file_added_by> then does post-processing: all C<filename set> records are
678             #pod filtered out as insignificant and makes sure the log is not empty.
679             #pod
680             #pod =cut
681              
682             sub _file_history {
683 97     97   112 my ( $self, $file ) = @_;
684 97         134 my $added_by = $file->{ added_by };
685 97         167 my $history = $self->_file_added_by( $file );
686             # Filter out 'filename set' entries.
687 97         178 $history = [ grep( { $_->{ action } ne 'filename set' } @$history ) ];
  146         368  
688             # Just in case make sure history is not empty.
689 97 50       246 if ( not @$history ) {
690 0         0 $self->log_error( [ '%s file history is empty', $file->name ] );
691             };
692 97         139 return $history;
693             };
694              
695             # --------------------------------------------------------------------------------------------------
696              
697             #pod =method _file_added_by
698             #pod
699             #pod $arrayref = $self->_file_added_by( $file );
700             #pod
701             #pod The method parses file's C<added_by> log. Internally, C<added_by> log is a list of strings. Here
702             #pod are few examples:
703             #pod
704             #pod content added by COPYING (Dist::Zilla::Plugin::GenerateFile line 114)
705             #pod filename set by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 125)
706             #pod encoded_content added by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 126)
707             #pod text from coderef added by MetaJSON (Dist::Zilla::Plugin::MetaJSON line 83)
708             #pod content set by TemplateFiles (Dist::Zilla::Plugin::TemplateFiles line 35)
709             #pod content set by OurPkgVersion (Dist::Zilla::Plugin::OurPkgVersion line 82)
710             #pod content set by PodWeaver (Dist::Zilla::Plugin::PodWeaver line 175)
711             #pod
712             #pod Thus, each string in C<added_by> log follows the format:
713             #pod
714             #pod <action> by <name> (<package> line <number>)
715             #pod
716             #pod The method parses these strings and returns a more convenient for further processing form:
717             #pod
718             #pod [ { action => …, name => …, package => …, line => … }, { … }, … ]
719             #pod
720             #pod Do not call this method directly, use C<_file_history> instead.
721             #pod
722             #pod =cut
723              
724             sub _file_added_by {
725 97     97   96 my ( $self, $file ) = @_;
726 97         100 my $added_by = $file->{ added_by };
727             # ^ Do not use accessor — it will convert array of strings into single string.
728 97         111 my $history = [];
729 97         130 my $n = 0;
730 97         237 for my $entry ( @$added_by ) {
731 146         134 ++ $n;
732 146 50       1270 if ( $entry =~ m{\A (.*?) \s by \s (.*) \s \( ([a-z_0-9:]+) \s line \s (\d+) \) \z}ix ) {
733 146         485 my ( $action, $name, $package, $line ) = ( $1, $2, $3, $4 );
734 146         688 push(
735             @$history,
736             { action => $action, name => $name, package => $package, line => $line }
737             );
738             } else {
739             $self->log_error( [
740             "Can't parse entry #%d in file %s added_by log:\n%s",
741             $n, $file->name,
742             join(
743             "\n",
744             map(
745 0 0       0 { ( $_ == $n ? '>>> ' : ' ' ) . $added_by->[ $_ - 1 ] }
  0         0  
746             1 .. @$added_by
747             )
748             )
749             ] );
750             };
751             };
752 97         156 return $history;
753             };
754              
755             # --------------------------------------------------------------------------------------------------
756              
757             #pod =method _file_deed
758             #pod
759             #pod $str = $self->_file_deed( $file, $history ); # $SOURCE, $META, or $OTHER.
760             #pod
761             #pod Returns internal identifier of file deed.
762             #pod
763             #pod =cut
764              
765             sub _file_deed {
766 97     97   107 my ( $self, $file, $history ) = @_;
767 97         109 my $deed;
768 97 50       186 if ( my $first = $history->[ 0 ] ) {
769 97   66     3832 $deed = $self->_providers->{ $first->{ name } } || $OTHER;
770             } else {
771 0         0 $self->log_error( [ "can't find file %s deed: file history is empty", $file->name ] );
772             };
773 97         213 return $deed;
774             };
775              
776             # --------------------------------------------------------------------------------------------------
777              
778             #pod =method _file_breed
779             #pod
780             #pod $str = $self->_file_breed( $file, $history ); # ADDED or BUILT.
781             #pod
782             #pod Returns internal identifier of file breed, either C<$ADDED> or C<$BUILT>.
783             #pod
784             #pod Current implementation checks file object class: if it is a C<Dist::Zilla::File::OnDisk>, the file
785             #pod is added to distribution, otherwise the file is built.
786             #pod
787             #pod =cut
788              
789             sub _file_breed {
790 97     97   123 my ( $self, $file, $history ) = @_;
791 97         101 my $breed;
792 97 100       551 if ( $file->isa( 'Dist::Zilla::File::OnDisk' ) ) {
793 43         137 $breed = $ADDED;
794             } else {
795 54         227 $breed = $BUILT;
796             };
797 97         380 return $breed;
798             };
799              
800             # --------------------------------------------------------------------------------------------------
801              
802             #pod =method _file_adder
803             #pod
804             #pod $str = $self->_file_adder( $file, $history );
805             #pod
806             #pod Returns moniker of the plugin added the file to the distribution.
807             #pod
808             #pod =cut
809              
810             sub _file_adder {
811 97     97   130 my ( $self, $file, $history ) = @_;
812 97         107 my $adder = '(*UNKNOWN*)';
813 97 50       182 if ( my $first = $history->[ 0 ] ) {
814 97         109 my $name = $first->{ name };
815 97 50       2854 if ( my $plugin = $self->zilla->plugin_named( $name ) ) {
816 97         10015 $adder = __plugin_moniker( $plugin );
817             # Just in case make sure found plugin does `FileInjector` role.
818 97 50       4673 $plugin->does( 'Dist::Zilla::Role::FileInjector' ) or
819             $self->log_error( [
820             "oops: found file adder %s does not do FileInjector role", $name
821             ] );
822             } else {
823 0         0 $self->log_error( [
824             "can't find file %s adder: %s is not a plugin", $file->name, $name
825             ] );
826             };
827             } else {
828 0         0 $self->log_error( [ "can't find file %s adder: file history is empty", $file->name ] );
829             };
830 97         6776 return $adder;
831             };
832              
833             # --------------------------------------------------------------------------------------------------
834              
835             #pod =method _file_mungers
836             #pod
837             #pod @list = $self->_file_mungers( $file, $history );
838             #pod
839             #pod If C<show_mungers> attribute is C<true>, returns list of monikers of the plugins munged the file.
840             #pod Otherwise returns empty list.
841             #pod
842             #pod =cut
843              
844             sub _file_mungers {
845 97     97   128 my ( $self, $file, $history ) = @_;
846 97         105 my @mungers;
847 97 100       3982 if ( $self->show_mungers ) {
848 4         12 for my $i ( 1 .. @$history - 1 ) {
849 1         5 push( @mungers, $self->_file_munger( $file, $history->[ $i ] ) );
850             };
851             };
852 97         246 return @mungers;
853             };
854              
855             # --------------------------------------------------------------------------------------------------
856              
857             #pod =method _file_munger
858             #pod
859             #pod $str = $self->_file_munger( $file, $history->[ $n ] );
860             #pod
861             #pod The method is supposed to return a moniker of plugin munged the file. But… see
862             #pod L<Dist::Zilla::Plugin::Manifest::Write/"Correctness of Information">.
863             #pod
864             #pod =cut
865              
866             sub _file_munger {
867 1     1   3 my ( $self, $file, $entry ) = @_;
868             # Try to find a plugin with given name.
869 1 50       36 if ( my $plugin = $self->zilla->plugin_named( $entry->{ name } ) ) {
870             # Bingo! Return (correct) plugin moniker.
871 1         150 return __plugin_moniker( $plugin );
872             };
873             # Oops, bad luck. We have:
874             # * a plugin name which is not a plugin name but moniker of *some* plugin.
875             # * a package name which can be a plugin package name or not.
876             # We have to guess.
877             # BTW, I have tried to mark guessed monikers with a question mark, but *all* file mungers
878             # will carry this mark. Looks ugly,so I rejected it.
879 0           return __plugin_moniker( $entry->{ package } );
880             };
881              
882             # --------------------------------------------------------------------------------------------------
883              
884             #pod =method mvp_multivalue_args
885             #pod
886             #pod This method tells C<Dist::Zilla> that C<source_provider>, C<source_providers>,
887             #pod C<metainfo_provider>, and C<metainfo_providers> are multi-value options (i. e. can be specified in
888             #pod several times).
889             #pod
890             #pod =cut
891              
892             around mvp_multivalue_args => sub {
893             my ( $orig, $self ) = @_;
894             return (
895             $self->$orig(),
896             qw{ source_provider source_providers metainfo_provider metainfo_providers }
897             );
898             };
899              
900             # --------------------------------------------------------------------------------------------------
901              
902             __PACKAGE__->meta->make_immutable;
903              
904             1;
905              
906             # --------------------------------------------------------------------------------------------------
907              
908             #pod =head1 SYNOPSIS
909             #pod
910             #pod package ManifestWithFileSize;
911             #pod
912             #pod use Moose;
913             #pod use namespace::autoclean;
914             #pod extends 'Dist::Zilla::Plugin::Manifest::Write';
915             #pod our $VERSION = '0.007';
916             #pod
917             #pod # Overload any method or modify it with all the Moose power, e. g.:
918             #pod around _file_comment => sub {
919             #pod my ( $orig, $self, $file ) = @_;
920             #pod my $comment = $self->$orig( $file );
921             #pod if ( $file->name ne $self->manifest ) { # Avoid infinite recursion.
922             #pod $comment .= sprintf( ' (%d bytes)', length( $file->encoded_content ) );
923             #pod };
924             #pod return $comment;
925             #pod };
926             #pod
927             #pod __PACKAGE__->meta->make_immutable;
928             #pod 1;
929             #pod
930             #pod =example Manifest with File Size
931             #pod
932             #pod A module shown in Synopsis is a real example. Its result looks like:
933             #pod
934             #pod # This file was generated with ManifestWithFileSize 0.007.
935             #pod MANIFEST # metainfo file built by =ManifestWithFileSize
936             #pod dist.ini # Dummy file added by GatherDir (239 bytes)
937             #pod lib/Dummy.pm # Dummy file added by GatherDir (22 bytes)
938             #pod
939             #pod
940             #pod =head1 COPYRIGHT AND LICENSE
941             #pod
942             #pod Copyright (C) 2015, 2016 Van de Bugger
943             #pod
944             #pod License GPLv3+: The GNU General Public License version 3 or later
945             #pod <http://www.gnu.org/licenses/gpl-3.0.txt>.
946             #pod
947             #pod This is free software: you are free to change and redistribute it. There is
948             #pod NO WARRANTY, to the extent permitted by law.
949             #pod
950             #pod
951             #pod =cut
952              
953             # ------------------------------------------------------------------------------------------------
954             #
955             # file: doc/what.pod
956             #
957             # This file is part of perl-Dist-Zilla-Plugin-Manifest-Write.
958             #
959             # ------------------------------------------------------------------------------------------------
960              
961             #pod =encoding UTF-8
962             #pod
963             #pod =head1 WHAT?
964             #pod
965             #pod C<Dist-Zilla-Plugin-Manifest-Write> (or C<Manifest::Write> for brevity) is a plugin for C<Dist::Zilla>, a replacement
966             #pod for standard plugin C<Manifest>. C<Manifest::Write> writes I<annotated> distribution manifest: each
967             #pod filename is followed by a comment explaining origin of the file: if it is a part of software, meta
968             #pod information, or 3rd-party file. Also it can B<I<exclude> built files from distribution>, e. g.
969             #pod extra tests have to be built (to run) but need not be distributed.
970             #pod
971             #pod =cut
972              
973             # end of file #
974              
975              
976             # end of file #
977              
978             __END__
979              
980             =pod
981              
982             =encoding UTF-8
983              
984             =head1 NAME
985              
986             Dist::Zilla::Plugin::Manifest::Write - Have annotated distribution manifest
987              
988             =head1 VERSION
989              
990             Version v0.9.6_01, released on 2016-12-09 21:24 UTC.
991             This is a B<trial release>.
992              
993             =head1 WHAT?
994              
995             C<Dist-Zilla-Plugin-Manifest-Write> (or C<Manifest::Write> for brevity) is a plugin for C<Dist::Zilla>, a replacement
996             for standard plugin C<Manifest>. C<Manifest::Write> writes I<annotated> distribution manifest: each
997             filename is followed by a comment explaining origin of the file: if it is a part of software, meta
998             information, or 3rd-party file. Also it can B<I<exclude> built files from distribution>, e. g.
999             extra tests have to be built (to run) but need not be distributed.
1000              
1001             This is C<Dist::Zilla::Plugin::Manifest::Write> module documentation. Read this if you are going to hack or
1002             extend C<Manifest::Write>.
1003              
1004             If you want to have annotated distribution manifest, read the L<plugin user
1005             manual|Dist::Zilla::Plugin::Manifest::Write::Manual>. General topics like getting source, building, installing, bug
1006             reporting and some others are covered in the F<README>.
1007              
1008             =head1 SYNOPSIS
1009              
1010             package ManifestWithFileSize;
1011              
1012             use Moose;
1013             use namespace::autoclean;
1014             extends 'Dist::Zilla::Plugin::Manifest::Write';
1015             our $VERSION = '0.007';
1016              
1017             # Overload any method or modify it with all the Moose power, e. g.:
1018             around _file_comment => sub {
1019             my ( $orig, $self, $file ) = @_;
1020             my $comment = $self->$orig( $file );
1021             if ( $file->name ne $self->manifest ) { # Avoid infinite recursion.
1022             $comment .= sprintf( ' (%d bytes)', length( $file->encoded_content ) );
1023             };
1024             return $comment;
1025             };
1026              
1027             __PACKAGE__->meta->make_immutable;
1028             1;
1029              
1030             =head1 DESCRIPTION
1031              
1032             In order to add a manifest file to the distribution, C<Dist::Zilla::Plugin::Manifest::Write> class consumes
1033             C<Dist::Zilla::Role::FileGatherer> role. To meet the role requirements, the class implements
1034             C<gather_files> method. Other methods are supporting helpers for this one.
1035              
1036             Most of attributes are initialized by builders for easier customization by subclassing. Code is
1037             also divided into small methods for the same purpose.
1038              
1039             =head1 CLASS METHODS
1040              
1041             =head2 BUILDARGS
1042              
1043             The method splits values of C<source_providers> option into separate plugin names using whitespaces
1044             as delimiters, combines result of splitting with C<source_provider> option values, then filters out
1045             empty values. Resulting C<ArrayRef> saved as C<source_providers> options.
1046              
1047             The same for C<metainfo_providers> and C<metainfo_provider> options.
1048              
1049             =head1 OBJECT ATTRIBUTES
1050              
1051             =head2 manifest
1052              
1053             Name of manifest file to write.
1054              
1055             C<Str>, read-only. Default value is C<'MANIFEST'>.
1056              
1057             =head2 manifest_skip
1058              
1059             Name of manifest.skip file to write.
1060              
1061             C<Str>, read-only. Default value is C<'MANIFEST.SKIP'>.
1062              
1063             =head2 source_providers
1064              
1065             List of plugin names. Enlisted plugins are considered as source file providers. A file added to
1066             distribution by any of these plugins is considered as source file.
1067              
1068             C<ArrayRef[Str]>, read-only, default value is empty array. Init argument (and config file
1069             multi-value option) name is C<source_provider>. (C<BUILDARGS> also handles C<source_providers>
1070             option.)
1071              
1072             =head2 metainfo_providers
1073              
1074             Like C<source_providers> but enlists meta info file providers.
1075              
1076             C<ArrayRef[Str]>, read-only, default value is C<CPANFile>, C<Manifest>, C<MetaYAML>, C<MetaJSON>,
1077             and the plugin itself. Init argument (and config file multi-value option) name is
1078             C<metainfo_provider>. (C<BUILDARGS> also handles C<metainfo_providers> option.)
1079              
1080             Note: Do not confuse C<Manifest::Write>'s term I<metainfo providers> with C<Dist::Zilla>'s
1081             C<MetaProvider> role. Plugins do C<MetaProvider> role provide I<metadata>, while C<Manifest::Write>
1082             is interested in plugins which adds I<files> containing metadata to the distribution (such plugins
1083             do C<FileInjector> role, not C<MetaProvider>).
1084              
1085             =head2 strict
1086              
1087             Strictness of checking source and metainfo provider names: -1 (no checks), 0 (some mistakes are
1088             fatal, some are not), or 1 (all mistakes are fatal).
1089              
1090             C<Int>, read-only. Default is 1.
1091              
1092             See L<Dist::Zilla::Plugin::Manifest::Write::Manual/"strict">.
1093              
1094             =head2 show_mungers
1095              
1096             If C<1>, file mungers will be included into annotation. By default mungers are not included.
1097              
1098             C<Bool>, read-only. Default is C<0>.
1099              
1100             =head2 deeds
1101              
1102             This attribute maps internal file deed constants (C<SOURCE>, C<META>, C<OTHER>) to user-visible
1103             names used in manifest (project name, C<metainfo>, and C<3rd party> respectively).
1104              
1105             C<HashRef[Str]>, read-only.
1106              
1107             =head2 breeds
1108              
1109             This attribute maps internal file deed constants (C<$ADDED> and C<$BUILT>) to user-visible names
1110             used in manifest. By default user-visible breed names are the same as internal identifiers.
1111              
1112             C<HashRef[Str]>, read-only.
1113              
1114             =head2 _providers
1115              
1116             This attribute maps provider names to file deeds. It makes C<_file_deed> method implementation
1117             simpler and faster.
1118              
1119             C<HashRef[Str]>, read-only, not an init arg.
1120              
1121             =head2 _dw
1122              
1123             Max length of user-visible deed names.
1124              
1125             C<Int>, read-only, not an init arg.
1126              
1127             =head1 OBJECT METHODS
1128              
1129             =head2 before_build
1130              
1131             This method is called by C<Dist::Zilla> automatically before build. The method checks validity of
1132             source and metainfo provider names.
1133              
1134             =head2 before_archive
1135              
1136             This method is called by C<Dist::Zilla> automatically before build the archive. The method prunes
1137             files found by file finders specified in the C<exclude_files> option.
1138              
1139             =head2 gather_files
1140              
1141             This is the main method of the class. It adds a file with name C<< $self->manifest >> to the
1142             distribution. File content is specified by C<CodeRef> to postpone actual file creation. Being
1143             evaluated, the code iterates through all the files in distribution in alphabetical order, and
1144             fulfills the manifest with filenames and comments.
1145              
1146             =head2 _file_name
1147              
1148             $str = $self->_file_name( $file );
1149              
1150             Returns filename to be used in manifest. If filename does not include special characters (spaces,
1151             backslashes (C<\>), apostrophes (C<'>), hashes (C<#>)), it is the same as real filename, otherwise
1152             filename encoded like Perl single-quoted string: backslashes and apostrophes are escaped, and
1153             entire filename is enclosed into apostrophes.
1154              
1155             =head2 _file_comment
1156              
1157             $str = $self->_file_comment( $file ); # Without leading sharp.
1158              
1159             The method returns comment to be used with the specified file. Comment should not include leading
1160             sharp character (C<#>).
1161              
1162             =head2 _file_history
1163              
1164             $arrayref = $self->_file_history( $file );
1165              
1166             The method calls C<_file_added_by> then does post-processing: all C<filename set> records are
1167             filtered out as insignificant and makes sure the log is not empty.
1168              
1169             =head2 _file_added_by
1170              
1171             $arrayref = $self->_file_added_by( $file );
1172              
1173             The method parses file's C<added_by> log. Internally, C<added_by> log is a list of strings. Here
1174             are few examples:
1175              
1176             content added by COPYING (Dist::Zilla::Plugin::GenerateFile line 114)
1177             filename set by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 125)
1178             encoded_content added by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 126)
1179             text from coderef added by MetaJSON (Dist::Zilla::Plugin::MetaJSON line 83)
1180             content set by TemplateFiles (Dist::Zilla::Plugin::TemplateFiles line 35)
1181             content set by OurPkgVersion (Dist::Zilla::Plugin::OurPkgVersion line 82)
1182             content set by PodWeaver (Dist::Zilla::Plugin::PodWeaver line 175)
1183              
1184             Thus, each string in C<added_by> log follows the format:
1185              
1186             <action> by <name> (<package> line <number>)
1187              
1188             The method parses these strings and returns a more convenient for further processing form:
1189              
1190             [ { action => …, name => …, package => …, line => … }, { … }, … ]
1191              
1192             Do not call this method directly, use C<_file_history> instead.
1193              
1194             =head2 _file_deed
1195              
1196             $str = $self->_file_deed( $file, $history ); # $SOURCE, $META, or $OTHER.
1197              
1198             Returns internal identifier of file deed.
1199              
1200             =head2 _file_breed
1201              
1202             $str = $self->_file_breed( $file, $history ); # ADDED or BUILT.
1203              
1204             Returns internal identifier of file breed, either C<$ADDED> or C<$BUILT>.
1205              
1206             Current implementation checks file object class: if it is a C<Dist::Zilla::File::OnDisk>, the file
1207             is added to distribution, otherwise the file is built.
1208              
1209             =head2 _file_adder
1210              
1211             $str = $self->_file_adder( $file, $history );
1212              
1213             Returns moniker of the plugin added the file to the distribution.
1214              
1215             =head2 _file_mungers
1216              
1217             @list = $self->_file_mungers( $file, $history );
1218              
1219             If C<show_mungers> attribute is C<true>, returns list of monikers of the plugins munged the file.
1220             Otherwise returns empty list.
1221              
1222             =head2 _file_munger
1223              
1224             $str = $self->_file_munger( $file, $history->[ $n ] );
1225              
1226             The method is supposed to return a moniker of plugin munged the file. But… see
1227             L<Dist::Zilla::Plugin::Manifest::Write/"Correctness of Information">.
1228              
1229             =head2 mvp_multivalue_args
1230              
1231             This method tells C<Dist::Zilla> that C<source_provider>, C<source_providers>,
1232             C<metainfo_provider>, and C<metainfo_providers> are multi-value options (i. e. can be specified in
1233             several times).
1234              
1235             =head1 FUNCTIONS
1236              
1237             I would expect to find these functions in C<Dist::Zilla>. Actually, C<Dist::Zilla::Util> defines
1238             the function C<expand_config_package_name>, but that function "is likely to change or go away" and
1239             there is no reverse transformation.
1240              
1241             =head2 __plugin_moniker
1242              
1243             $str = __plugin_moniker( 'Dist::Zilla::Plugin::Name' ); # 'Name'
1244             $str = __plugin_moniker( 'Non::Standard::Name' ); # '=Non::Standard::Name'
1245             $str = __plugin_moniker( $plugin );
1246              
1247             The function takes either reference to a plugin object or a string, package name, and returns
1248             C<Dist::Zilla> plugin moniker: If its package name begins with C<Dist::Zilla::Plugin::>, this
1249             common prefix is dropped, otherwise the package name prepended with C<=>.
1250              
1251             =head2 __package_name
1252              
1253             $str = __package_name( 'Name' ); # returns 'Dist::Zilla::Plugin::Name'
1254             $str = __package_name( '=Name' ); # returns 'Name'
1255             $str = __package_name( $plugin );
1256              
1257             This is operation opposite to C<__plugin_moniker>. It takes either reference to plugin object, or
1258             string, plugin moniker, and returns package name.
1259              
1260             This function is similar to C<expand_config_package_name> from C<Dist::Zilla::Util>, with minor
1261             difference: this function works with plugins only (not with plugin bundles and stashes), and
1262             accepts also reference to plugin object.
1263              
1264             =head1 EXAMPLES
1265              
1266             =head2 Manifest with File Size
1267              
1268             A module shown in Synopsis is a real example. Its result looks like:
1269              
1270             # This file was generated with ManifestWithFileSize 0.007.
1271             MANIFEST # metainfo file built by =ManifestWithFileSize
1272             dist.ini # Dummy file added by GatherDir (239 bytes)
1273             lib/Dummy.pm # Dummy file added by GatherDir (22 bytes)
1274              
1275             =head1 SEE ALSO
1276              
1277             =over 4
1278              
1279             =item L<Dist::Zilla>
1280              
1281             =item L<Dist::Zilla::Role>
1282              
1283             =item L<Dist::Zilla::Role::Plugin>
1284              
1285             =item L<Dist::Zilla::Role::FileInjector>
1286              
1287             =item L<Dist::Zilla::Role::FileGatherer>
1288              
1289             =item L<Dist::Zilla::Plugin::Manifest>
1290              
1291             =item L<Dist::Zilla::Plugin::Manifest::Write::Manual>
1292              
1293             =back
1294              
1295             =head1 AUTHOR
1296              
1297             Van de Bugger <van.de.bugger@gmail.com>
1298              
1299             =head1 COPYRIGHT AND LICENSE
1300              
1301             Copyright (C) 2015, 2016 Van de Bugger
1302              
1303             License GPLv3+: The GNU General Public License version 3 or later
1304             <http://www.gnu.org/licenses/gpl-3.0.txt>.
1305              
1306             This is free software: you are free to change and redistribute it. There is
1307             NO WARRANTY, to the extent permitted by law.
1308              
1309             =cut