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   3462296 use Moose; # Let `perlcritic` shut up: it complains on code (`$VERSION`) before `strict`.
  2         4  
  2         13  
56 2     2   10319 use namespace::autoclean;
  2         4  
  2         17  
57              
58             # PODNAME: Dist::Zilla::Plugin::Manifest::Write
59             # ABSTRACT: Have annotated distribution manifest
60             our $VERSION = 'v0.9.7'; # 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   1447 use Dist::Zilla::File::FromCode;
  2         109519  
  2         96  
72 2     2   24 use ExtUtils::Manifest qw{};
  2         2  
  2         33  
73 2     2   11 use List::Util;
  2         3  
  2         140  
74 2     2   1325 use Module::Util qw{ is_valid_module_name };
  2         2928  
  2         138  
75 2     2   11 use Path::Tiny qw{};
  2         3  
  2         31  
76 2     2   1041 use Readonly;
  2         6543  
  2         114  
77 2     2   14 use Set::Object qw{};
  2         4  
  2         32  
78 2     2   9 use String::RewritePrefix;
  2         3  
  2         24  
79              
80 2     2   483 use Dist::Zilla::Role::File 5.023 (); # Hint for `AutoPrereqs`.
  2         49  
  2         5555  
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   126 my ( $arg ) = @_;
128 98 50       368 if ( my $blessed = blessed( $arg ) ) {
129 98         138 $arg = $blessed;
130             };
131 98         428 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   27 my ( $self ) = @_;
212 20         1069 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   46 my ( $self ) = @_;
241 20         599 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   762405 my @list;
247 20         95 my $files = Set::Object->new( @{ $zilla->files } );
  20         562  
248 20         455 $files->remove( @{ $self->found_files } );
  20         115  
249             # Process all files in alphbetical order.
250 20         43 for my $file ( sort( { $a->name cmp $b->name } @{ $files } ) ) {
  141         10994  
  20         1451  
251 97         1672 push( @list, {
252             name => $self->_file_name( $file ),
253             comment => $self->_file_comment( $file )
254             } );
255             };
256 20         255 $self->abort_if_error(); # `_file_comment` methods may generate errors.
257             # Find width of filename column.
258 20         951 my $width = List::Util::max( map( { length( $_->{ name } ) } @list ) );
  97         177  
259             # Output formats.
260 20         35 my $body = "%*s # %s";
261             return
262             join(
263             "\n",
264             $self->_heading,
265 20         811 map( { sprintf( $body, - $width, $_->{ name }, $_->{ comment } ) } @list ),
  97         513  
266             ) . "\n";
267             },
268 20         871 } );
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   36 my ( $self ) = @_;
298 20 100       765 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   15374 my $default = Path::Tiny::path( $ExtUtils::Manifest::DEFAULT_MSKIP );
304             return join( "\n",
305             $self->_heading,
306             '',
307 19         1053 map( { "^" . quotemeta( $_->name ) . "\$" } @{ $self->found_files } ),
  25         303  
  19         71  
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         721 } );
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   32 my ( $self ) = @_;
372 17         524 my @list = ( qw{ CPANFile Manifest MetaYAML MetaJSON }, $self->plugin_name );
373 17 50       674 if ( $self->strict >= 0 ) {
374 17         41 @list = grep( { $self->_is_injector( $_ ) } @list );
  85         759  
375             };
376 17         1337 return \@list;
377             };
378              
379             sub _is_injector {
380 85     85   111 my ( $self, $name ) = @_;
381 85         2350 my $plugin = $self->zilla->plugin_named( $name );
382 85   66     25476 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   33 my ( $self ) = @_;
441             return {
442 20         626 $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   35 my ( $self ) = @_;
469             return {
470 20         91 $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   34 my ( $self ) = @_;
497 21         40 my $providers = {};
498 21         39 for my $provider ( @{ $self->source_providers } ) {
  21         796  
499 29         246 $providers->{ $provider } = $SOURCE;
500             };
501 21         105 for my $provider ( @{ $self->metainfo_providers } ) {
  21         881  
502 36 100 66     168 if ( exists( $providers->{ $provider } ) and $providers->{ $provider } != $META ) {
503             # The same plugin name may be specified in the same option multiple times.
504 1         10 $self->log_error( [
505             "%s cannot be a source provider and a metainfo provider simultaneously",
506             $provider
507             ] );
508             } else {
509 35         121 $providers->{ $provider } = $META;
510             };
511             };
512 21         1094 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   37 my ( $self ) = @_;
535 20         32 return List::Util::max( map( { length( $_ ) } values( %{ $self->deeds } ) ) );
  60         903  
  20         778  
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 1289686 my ( $self ) = @_;
558 21 100       899 if ( $self->strict >= 0 ) {
559 20 100       729 my $log_warning = $self->strict > 0 ? 'log_error' : 'log';
560 20         585 my $zilla = $self->zilla;
561 20         124 for my $provider ( @{ $self->source_providers }, @{ $self->metainfo_providers } ) {
  20         774  
  20         826  
562 62 100       3617 if ( my $plugin = $zilla->plugin_named( $provider ) ) {
563 58 100       5655 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         1660 $self->$log_warning( [ "%s is not a plugin", $provider ] );
568             };
569             };
570 20         1662 $self->_providers(); # Initiate building the attribute. It can report errors.
571 20         111 $self->abort_if_error();
572             };
573 20         851 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 6778 my ( $self ) = @_;
587 2         69 my $zilla = $self->zilla;
588 2         12 for my $file ( @{ $self->found_files } ) {
  2         7  
589 5         203 $zilla->prune_file( $file );
590             };
591 2         164 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 157996 my ( $self, $arg ) = @_;
607 20         857 $self->add_file( $self->_manifest_file );
608 20 100       7203 $self->add_file( $self->_manifest_skip_file ) if defined $self->_manifest_skip_file;
609 20         5941 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   135 my ( $self, $file ) = @_;
627 97         283 my $name = $file->name;
628 97 100       4150 if ( $name =~ m{[\ '\\#]}x ) {
629 5         16 $name =~ s{([\\'])}{\\$1}gx;
630 5         11 $name = "'" . $name . "'";
631             };
632 97         269 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   124 my ( $self, $file ) = @_;
648 97         218 my $history = $self->_file_history( $file );
649 97         186 my $deed = $self->_file_deed( $file, $history );
650 97         205 my $breed = $self->_file_breed( $file, $history );
651 97         156 my $adder = $self->_file_adder( $file, $history );
652 97         237 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     3464 $self->breeds->{ $breed } || $breed || '(*UNKNOWN*)',
      50        
659             $adder
660             ) .
661             (
662             @mungers ? (
663             ' and munged by ' . join( ', ', @mungers )
664             ) : (
665             ''
666             )
667             );
668 97         553 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   111 my ( $self, $file ) = @_;
684 97         146 my $added_by = $file->{ added_by };
685 97         197 my $history = $self->_file_added_by( $file );
686             # Filter out 'filename set' entries.
687 97         142 $history = [ grep( { $_->{ action } ne 'filename set' } @$history ) ];
  146         347  
688             # Just in case make sure history is not empty.
689 97 50       258 if ( not @$history ) {
690 0         0 $self->log_error( [ '%s file history is empty', $file->name ] );
691             };
692 97         126 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   82 my ( $self, $file ) = @_;
726 97         113 my $added_by = $file->{ added_by };
727             # ^ Do not use accessor — it will convert array of strings into single string.
728 97         139 my $history = [];
729 97         103 my $n = 0;
730 97         171 for my $entry ( @$added_by ) {
731 146         133 ++ $n;
732 146 50       1251 if ( $entry =~ m{\A (.*?) \s by \s (.*) \s \( ([a-z_0-9:]+) \s line \s (\d+) \) \z}ix ) {
733 146         568 my ( $action, $name, $package, $line ) = ( $1, $2, $3, $4 );
734 146         607 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         150 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   110 my ( $self, $file, $history ) = @_;
767 97         81 my $deed;
768 97 50       211 if ( my $first = $history->[ 0 ] ) {
769 97   66     3870 $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         214 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   110 my ( $self, $file, $history ) = @_;
791 97         83 my $breed;
792 97 100       510 if ( $file->isa( 'Dist::Zilla::File::OnDisk' ) ) {
793 43         134 $breed = $ADDED;
794             } else {
795 54         210 $breed = $BUILT;
796             };
797 97         352 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   101 my ( $self, $file, $history ) = @_;
812 97         100 my $adder = '(*UNKNOWN*)';
813 97 50       160 if ( my $first = $history->[ 0 ] ) {
814 97         109 my $name = $first->{ name };
815 97 50       2929 if ( my $plugin = $self->zilla->plugin_named( $name ) ) {
816 97         10199 $adder = __plugin_moniker( $plugin );
817             # Just in case make sure found plugin does `FileInjector` role.
818 97 50       4570 $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         6707 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   134 my ( $self, $file, $history ) = @_;
846 97         85 my @mungers;
847 97 100       4196 if ( $self->show_mungers ) {
848 4         14 for my $i ( 1 .. @$history - 1 ) {
849 1         5 push( @mungers, $self->_file_munger( $file, $history->[ $i ] ) );
850             };
851             };
852 97         241 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       30 if ( my $plugin = $self->zilla->plugin_named( $entry->{ name } ) ) {
870             # Bingo! Return (correct) plugin moniker.
871 1         202 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.7, released on 2016-12-14 22:51 UTC.
991              
992             =head1 WHAT?
993              
994             C<Dist-Zilla-Plugin-Manifest-Write> (or C<Manifest::Write> for brevity) is a plugin for C<Dist::Zilla>, a replacement
995             for standard plugin C<Manifest>. C<Manifest::Write> writes I<annotated> distribution manifest: each
996             filename is followed by a comment explaining origin of the file: if it is a part of software, meta
997             information, or 3rd-party file. Also it can B<I<exclude> built files from distribution>, e. g.
998             extra tests have to be built (to run) but need not be distributed.
999              
1000             This is C<Dist::Zilla::Plugin::Manifest::Write> module documentation. Read this if you are going to hack or
1001             extend C<Manifest::Write>.
1002              
1003             If you want to have annotated distribution manifest, read the L<plugin user
1004             manual|Dist::Zilla::Plugin::Manifest::Write::Manual>. General topics like getting source, building, installing, bug
1005             reporting and some others are covered in the F<README>.
1006              
1007             =head1 SYNOPSIS
1008              
1009             package ManifestWithFileSize;
1010              
1011             use Moose;
1012             use namespace::autoclean;
1013             extends 'Dist::Zilla::Plugin::Manifest::Write';
1014             our $VERSION = '0.007';
1015              
1016             # Overload any method or modify it with all the Moose power, e. g.:
1017             around _file_comment => sub {
1018             my ( $orig, $self, $file ) = @_;
1019             my $comment = $self->$orig( $file );
1020             if ( $file->name ne $self->manifest ) { # Avoid infinite recursion.
1021             $comment .= sprintf( ' (%d bytes)', length( $file->encoded_content ) );
1022             };
1023             return $comment;
1024             };
1025              
1026             __PACKAGE__->meta->make_immutable;
1027             1;
1028              
1029             =head1 DESCRIPTION
1030              
1031             In order to add a manifest file to the distribution, C<Dist::Zilla::Plugin::Manifest::Write> class consumes
1032             C<Dist::Zilla::Role::FileGatherer> role. To meet the role requirements, the class implements
1033             C<gather_files> method. Other methods are supporting helpers for this one.
1034              
1035             Most of attributes are initialized by builders for easier customization by subclassing. Code is
1036             also divided into small methods for the same purpose.
1037              
1038             =head1 CLASS METHODS
1039              
1040             =head2 BUILDARGS
1041              
1042             The method splits values of C<source_providers> option into separate plugin names using whitespaces
1043             as delimiters, combines result of splitting with C<source_provider> option values, then filters out
1044             empty values. Resulting C<ArrayRef> saved as C<source_providers> options.
1045              
1046             The same for C<metainfo_providers> and C<metainfo_provider> options.
1047              
1048             =head1 OBJECT ATTRIBUTES
1049              
1050             =head2 manifest
1051              
1052             Name of manifest file to write.
1053              
1054             C<Str>, read-only. Default value is C<'MANIFEST'>.
1055              
1056             =head2 manifest_skip
1057              
1058             Name of manifest.skip file to write.
1059              
1060             C<Str>, read-only. Default value is C<'MANIFEST.SKIP'>.
1061              
1062             =head2 source_providers
1063              
1064             List of plugin names. Enlisted plugins are considered as source file providers. A file added to
1065             distribution by any of these plugins is considered as source file.
1066              
1067             C<ArrayRef[Str]>, read-only, default value is empty array. Init argument (and config file
1068             multi-value option) name is C<source_provider>. (C<BUILDARGS> also handles C<source_providers>
1069             option.)
1070              
1071             =head2 metainfo_providers
1072              
1073             Like C<source_providers> but enlists meta info file providers.
1074              
1075             C<ArrayRef[Str]>, read-only, default value is C<CPANFile>, C<Manifest>, C<MetaYAML>, C<MetaJSON>,
1076             and the plugin itself. Init argument (and config file multi-value option) name is
1077             C<metainfo_provider>. (C<BUILDARGS> also handles C<metainfo_providers> option.)
1078              
1079             Note: Do not confuse C<Manifest::Write>'s term I<metainfo providers> with C<Dist::Zilla>'s
1080             C<MetaProvider> role. Plugins do C<MetaProvider> role provide I<metadata>, while C<Manifest::Write>
1081             is interested in plugins which adds I<files> containing metadata to the distribution (such plugins
1082             do C<FileInjector> role, not C<MetaProvider>).
1083              
1084             =head2 strict
1085              
1086             Strictness of checking source and metainfo provider names: -1 (no checks), 0 (some mistakes are
1087             fatal, some are not), or 1 (all mistakes are fatal).
1088              
1089             C<Int>, read-only. Default is 1.
1090              
1091             See L<Dist::Zilla::Plugin::Manifest::Write::Manual/"strict">.
1092              
1093             =head2 show_mungers
1094              
1095             If C<1>, file mungers will be included into annotation. By default mungers are not included.
1096              
1097             C<Bool>, read-only. Default is C<0>.
1098              
1099             =head2 deeds
1100              
1101             This attribute maps internal file deed constants (C<SOURCE>, C<META>, C<OTHER>) to user-visible
1102             names used in manifest (project name, C<metainfo>, and C<3rd party> respectively).
1103              
1104             C<HashRef[Str]>, read-only.
1105              
1106             =head2 breeds
1107              
1108             This attribute maps internal file deed constants (C<$ADDED> and C<$BUILT>) to user-visible names
1109             used in manifest. By default user-visible breed names are the same as internal identifiers.
1110              
1111             C<HashRef[Str]>, read-only.
1112              
1113             =head2 _providers
1114              
1115             This attribute maps provider names to file deeds. It makes C<_file_deed> method implementation
1116             simpler and faster.
1117              
1118             C<HashRef[Str]>, read-only, not an init arg.
1119              
1120             =head2 _dw
1121              
1122             Max length of user-visible deed names.
1123              
1124             C<Int>, read-only, not an init arg.
1125              
1126             =head1 OBJECT METHODS
1127              
1128             =head2 before_build
1129              
1130             This method is called by C<Dist::Zilla> automatically before build. The method checks validity of
1131             source and metainfo provider names.
1132              
1133             =head2 before_archive
1134              
1135             This method is called by C<Dist::Zilla> automatically before build the archive. The method prunes
1136             files found by file finders specified in the C<exclude_files> option.
1137              
1138             =head2 gather_files
1139              
1140             This is the main method of the class. It adds a file with name C<< $self->manifest >> to the
1141             distribution. File content is specified by C<CodeRef> to postpone actual file creation. Being
1142             evaluated, the code iterates through all the files in distribution in alphabetical order, and
1143             fulfills the manifest with filenames and comments.
1144              
1145             =head2 _file_name
1146              
1147             $str = $self->_file_name( $file );
1148              
1149             Returns filename to be used in manifest. If filename does not include special characters (spaces,
1150             backslashes (C<\>), apostrophes (C<'>), hashes (C<#>)), it is the same as real filename, otherwise
1151             filename encoded like Perl single-quoted string: backslashes and apostrophes are escaped, and
1152             entire filename is enclosed into apostrophes.
1153              
1154             =head2 _file_comment
1155              
1156             $str = $self->_file_comment( $file ); # Without leading sharp.
1157              
1158             The method returns comment to be used with the specified file. Comment should not include leading
1159             sharp character (C<#>).
1160              
1161             =head2 _file_history
1162              
1163             $arrayref = $self->_file_history( $file );
1164              
1165             The method calls C<_file_added_by> then does post-processing: all C<filename set> records are
1166             filtered out as insignificant and makes sure the log is not empty.
1167              
1168             =head2 _file_added_by
1169              
1170             $arrayref = $self->_file_added_by( $file );
1171              
1172             The method parses file's C<added_by> log. Internally, C<added_by> log is a list of strings. Here
1173             are few examples:
1174              
1175             content added by COPYING (Dist::Zilla::Plugin::GenerateFile line 114)
1176             filename set by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 125)
1177             encoded_content added by GatherFromManifest (Dist::Zilla::Plugin::GatherFromManifest line 126)
1178             text from coderef added by MetaJSON (Dist::Zilla::Plugin::MetaJSON line 83)
1179             content set by TemplateFiles (Dist::Zilla::Plugin::TemplateFiles line 35)
1180             content set by OurPkgVersion (Dist::Zilla::Plugin::OurPkgVersion line 82)
1181             content set by PodWeaver (Dist::Zilla::Plugin::PodWeaver line 175)
1182              
1183             Thus, each string in C<added_by> log follows the format:
1184              
1185             <action> by <name> (<package> line <number>)
1186              
1187             The method parses these strings and returns a more convenient for further processing form:
1188              
1189             [ { action => …, name => …, package => …, line => … }, { … }, … ]
1190              
1191             Do not call this method directly, use C<_file_history> instead.
1192              
1193             =head2 _file_deed
1194              
1195             $str = $self->_file_deed( $file, $history ); # $SOURCE, $META, or $OTHER.
1196              
1197             Returns internal identifier of file deed.
1198              
1199             =head2 _file_breed
1200              
1201             $str = $self->_file_breed( $file, $history ); # ADDED or BUILT.
1202              
1203             Returns internal identifier of file breed, either C<$ADDED> or C<$BUILT>.
1204              
1205             Current implementation checks file object class: if it is a C<Dist::Zilla::File::OnDisk>, the file
1206             is added to distribution, otherwise the file is built.
1207              
1208             =head2 _file_adder
1209              
1210             $str = $self->_file_adder( $file, $history );
1211              
1212             Returns moniker of the plugin added the file to the distribution.
1213              
1214             =head2 _file_mungers
1215              
1216             @list = $self->_file_mungers( $file, $history );
1217              
1218             If C<show_mungers> attribute is C<true>, returns list of monikers of the plugins munged the file.
1219             Otherwise returns empty list.
1220              
1221             =head2 _file_munger
1222              
1223             $str = $self->_file_munger( $file, $history->[ $n ] );
1224              
1225             The method is supposed to return a moniker of plugin munged the file. But… see
1226             L<Dist::Zilla::Plugin::Manifest::Write/"Correctness of Information">.
1227              
1228             =head2 mvp_multivalue_args
1229              
1230             This method tells C<Dist::Zilla> that C<source_provider>, C<source_providers>,
1231             C<metainfo_provider>, and C<metainfo_providers> are multi-value options (i. e. can be specified in
1232             several times).
1233              
1234             =head1 FUNCTIONS
1235              
1236             I would expect to find these functions in C<Dist::Zilla>. Actually, C<Dist::Zilla::Util> defines
1237             the function C<expand_config_package_name>, but that function "is likely to change or go away" and
1238             there is no reverse transformation.
1239              
1240             =head2 __plugin_moniker
1241              
1242             $str = __plugin_moniker( 'Dist::Zilla::Plugin::Name' ); # 'Name'
1243             $str = __plugin_moniker( 'Non::Standard::Name' ); # '=Non::Standard::Name'
1244             $str = __plugin_moniker( $plugin );
1245              
1246             The function takes either reference to a plugin object or a string, package name, and returns
1247             C<Dist::Zilla> plugin moniker: If its package name begins with C<Dist::Zilla::Plugin::>, this
1248             common prefix is dropped, otherwise the package name prepended with C<=>.
1249              
1250             =head2 __package_name
1251              
1252             $str = __package_name( 'Name' ); # returns 'Dist::Zilla::Plugin::Name'
1253             $str = __package_name( '=Name' ); # returns 'Name'
1254             $str = __package_name( $plugin );
1255              
1256             This is operation opposite to C<__plugin_moniker>. It takes either reference to plugin object, or
1257             string, plugin moniker, and returns package name.
1258              
1259             This function is similar to C<expand_config_package_name> from C<Dist::Zilla::Util>, with minor
1260             difference: this function works with plugins only (not with plugin bundles and stashes), and
1261             accepts also reference to plugin object.
1262              
1263             =head1 EXAMPLES
1264              
1265             =head2 Manifest with File Size
1266              
1267             A module shown in Synopsis is a real example. Its result looks like:
1268              
1269             # This file was generated with ManifestWithFileSize 0.007.
1270             MANIFEST # metainfo file built by =ManifestWithFileSize
1271             dist.ini # Dummy file added by GatherDir (239 bytes)
1272             lib/Dummy.pm # Dummy file added by GatherDir (22 bytes)
1273              
1274             =head1 SEE ALSO
1275              
1276             =over 4
1277              
1278             =item L<Dist::Zilla>
1279              
1280             =item L<Dist::Zilla::Role>
1281              
1282             =item L<Dist::Zilla::Role::Plugin>
1283              
1284             =item L<Dist::Zilla::Role::FileInjector>
1285              
1286             =item L<Dist::Zilla::Role::FileGatherer>
1287              
1288             =item L<Dist::Zilla::Plugin::Manifest>
1289              
1290             =item L<Dist::Zilla::Plugin::Manifest::Write::Manual>
1291              
1292             =back
1293              
1294             =head1 AUTHOR
1295              
1296             Van de Bugger <van.de.bugger@gmail.com>
1297              
1298             =head1 COPYRIGHT AND LICENSE
1299              
1300             Copyright (C) 2015, 2016 Van de Bugger
1301              
1302             License GPLv3+: The GNU General Public License version 3 or later
1303             <http://www.gnu.org/licenses/gpl-3.0.txt>.
1304              
1305             This is free software: you are free to change and redistribute it. There is
1306             NO WARRANTY, to the extent permitted by law.
1307              
1308             =cut