File Coverage

blib/lib/Dist/Zilla/PluginBundle/Author/VDB.pm
Criterion Covered Total %
statement 76 77 98.7
branch 26 36 72.2
condition 2 2 100.0
subroutine 19 19 100.0
pod 1 2 50.0
total 124 136 91.1


line stmt bran cond sub pod time code
1             # ---------------------------------------------------------------------- copyright and license ---
2             #
3             # file: lib/Dist/Zilla/PluginBundle/Author/VDB.pm
4             #
5             # Copyright © 2015 Van de Bugger
6             #
7             # This file is part of perl-Dist-Zilla-PluginBundle-Author-VDB.
8             #
9             # perl-Dist-Zilla-PluginBundle-Author-VDB 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-PluginBundle-Author-VDB 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-PluginBundle-Author-VDB. If not, see <http://www.gnu.org/licenses/>.
19             #
20             # ---------------------------------------------------------------------- copyright and license ---
21              
22             #pod =head1 DESCRIPTION
23             #pod
24             #pod It is unlikely that someone else will want to use it, so I will not bother with documenting it, at
25             #pod least for now.
26             #pod
27             #pod =for Pod::Coverage configure
28             #pod
29             #pod =cut
30              
31             package Dist::Zilla::PluginBundle::Author::VDB;
32              
33 1     1   2224584 use Moose;
  1         2  
  1         6  
34 1     1   5040 use namespace::autoclean;
  1         2  
  1         9  
35 1     1   74 use version 0.77;
  1         28  
  1         8  
36              
37             # PODNAME: Dist::Zilla::PluginBundle::Author::VDB
38             # ABSTRACT: VDB's plugin bundle
39             our $VERSION = 'v0.11.2_06'; # TRIAL VERSION
40              
41             with 'Dist::Zilla::Role::PluginBundle::Easy';
42              
43             # These modules used by the bundle directly.
44 1     1   90 use Carp qw{ croak };
  1         2  
  1         61  
45 1     1   545 use Dist::Zilla::File::InMemory;
  1         67382  
  1         37  
46 1     1   8 use Dist::Zilla::File::OnDisk;
  1         1  
  1         22  
47 1     1   3 use Path::Tiny;
  1         2  
  1         69  
48 1     1   6 use Sub::Exporter::ForMethods qw{ method_installer };
  1         1  
  1         14  
49 1     1   326 use Data::Section { installer => method_installer }, -setup;
  1         2  
  1         4  
50              
51             # These modules are used by hooks. Require all the modules explicitly now to avoid unexpected
52             # failures in the middle of build or release.
53 1     1   1249 use App::Prove ();
  1         27814  
  1         26  
54 1     1   9 use File::pushd ();
  1         2  
  1         13  
55 1     1   551 use IPC::Run3 ();
  1         8021  
  1         23  
56 1     1   587 use IPC::System::Simple ();
  1         3573  
  1         29  
57 1     1   7 use Path::Tiny 0.070 ();
  1         22  
  1         1713  
58              
59             # --------------------------------------------------------------------------------------------------
60              
61             #pod =option minimum_perl
62             #pod
63             #pod Optional, default value C<5.006>.
64             #pod
65             #pod =cut
66              
67             has minimum_perl => (
68             is => 'ro',
69             isa => 'Str',
70             lazy => 1,
71             default => sub {
72             my ( $self ) = @_;
73             return $self->payload->{ minimum_perl } // '5.006';
74             },
75             );
76              
77             # --------------------------------------------------------------------------------------------------
78              
79             #pod =option copying
80             #pod
81             #pod Name of POD file to generate distribution F<COPYING> text file. Empty value disables generation
82             #pod F<COPYING> file.
83             #pod
84             #pod C<Str>, optional, default value C<doc/copying.pod>.
85             #pod
86             #pod =cut
87              
88             has copying => (
89             is => 'ro',
90             isa => 'Str',
91             lazy => 1,
92             default => sub {
93             my ( $self ) = @_;
94             return $self->payload->{ copying } // 'doc/copying.pod';
95             },
96             );
97              
98             # --------------------------------------------------------------------------------------------------
99              
100             #pod =option readme
101             #pod
102             #pod Names of POD files to generate distribution F<README> text file. This is a multi-value option.
103             #pod Empty values are ignored. Empty list disables generating F<README> file.
104             #pod
105             #pod C<ArrayRef[Str]>, optional, default value C<[ 'doc/what.pod', 'doc/why.pod', 'doc/naming.pod', 'doc/forms.pod', 'doc/source.pod', 'doc/distribution.pod', 'doc/installing.pod', 'doc/hacking.pod', 'doc/documentation.pod', 'doc/feedback.pod', 'doc/glossary.pod' ]>.
106             #pod
107             #pod =cut
108              
109             has readme => (
110             is => 'ro',
111             isa => 'Maybe[ArrayRef[Str]]',
112             lazy => 1,
113             default => sub {
114             my ( $self ) = @_;
115             my $readme = $self->payload->{ readme } // [ 'doc/what.pod', 'doc/why.pod', 'doc/naming.pod', 'doc/forms.pod', 'doc/source.pod', 'doc/distribution.pod', 'doc/installing.pod', 'doc/hacking.pod', 'doc/documentation.pod', 'doc/feedback.pod', 'doc/glossary.pod' ];
116             $readme = [ grep( { $_ ne '' } @$readme ) ]; # Ignore empty items.
117             if ( not @$readme ) {
118             $readme = undef;
119             };
120             return $readme;
121             },
122             );
123              
124             # --------------------------------------------------------------------------------------------------
125              
126             #pod =option local_release
127             #pod
128             #pod If true, release will be a local one, i. e. no external operations will be done: C<UploadToCPAN>
129             #pod and C<hg push> will be skipped, <hg tag> will create a local tag.
130             #pod
131             #pod Option can be set trough F<dist.ini> file or with C<DZIL_LOCAL_RELEASE> environment variable.
132             #pod
133             #pod Optional, default value is 0.
134             #pod
135             #pod =cut
136              
137             has local_release => (
138             is => 'ro',
139             isa => 'Bool',
140             lazy => 1,
141             default => sub {
142             my ( $self ) = @_;
143             return $self->payload->{ local_release } // $ENV{ DZIL_LOCAL_RELEASE };
144             },
145             );
146              
147             # --------------------------------------------------------------------------------------------------
148              
149             #pod =option archive
150             #pod
151             #pod Directory to archive files to. If empty, release will not be archived. If such directory does not
152             #pod exist, it will be created before release.
153             #pod
154             #pod Optional, default value C<".releases">.
155             #pod
156             #pod =cut
157              
158             has archive => (
159             is => 'ro',
160             isa => 'Str',
161             lazy => 1,
162             default => sub {
163             my ( $self ) = @_;
164             return $self->payload->{ archive } // ".releases";
165             },
166             );
167              
168             # --------------------------------------------------------------------------------------------------
169              
170             #pod =option templates
171             #pod
172             #pod This option will be passed to C<Templates> plugin. If you no not want C<Templates> to process
173             #pod files, specify C<:NoFiles>. This is multi-value option (i. e. may be specified several times).
174             #pod
175             #pod Optional, default value C<[ ':InstallModules' ]>.
176             #pod
177             #pod =cut
178              
179             has templates => (
180             is => 'ro',
181             isa => 'Maybe[ArrayRef[Str]]',
182             lazy => 1,
183             default => sub {
184             my ( $self ) = @_;
185             my $templates = $self->payload->{ templates } // [ ':InstallModules' ];
186             $templates = [ grep( { $_ ne '' } @$templates ) ]; # Ignore empty items.
187             if ( not @$templates ) {
188             $templates = undef;
189             };
190             return $templates;
191             },
192             );
193              
194             # --------------------------------------------------------------------------------------------------
195              
196             #pod =option unwanted_module
197             #pod
198             #pod =option unwanted_modules
199             #pod
200             #pod TODO C<[ qw{ DDP Data::Printer } ]>.
201             #pod
202             #pod =cut
203              
204             has unwanted_modules => (
205             isa => 'ArrayRef[Str]',
206             is => 'ro',
207             lazy => 1,
208             default => sub {
209             my ( $self ) = @_;
210             my $p = $self->payload;
211             my $u1 = $p->{ unwanted_module };
212             my $u2 = $p->{ unwanted_modules };
213             return $u1 || $u2 ? [ $u1 ? @$u1 : (), $u2 ? @$u2 : () ] : [ qw{ DDP Data::Printer } ];
214             },
215             );
216              
217             # --------------------------------------------------------------------------------------------------
218              
219             #pod =option spellchecker
220             #pod
221             #pod Command to run spellchecker. Spellchecker command is expected to read text from stdin, and print to
222             #pod stdout misspelled words. If empty, spellchecking will be skipped. This involve C<Test::PodSpelling>
223             #pod plugin and internally implemented checking the F<Changes> file.
224             #pod
225             #pod Optional, default value C<aspell list -l en -p ./xt/aspell-en.pws>.
226             #pod
227             #pod =cut
228              
229             has spellchecker => (
230             is => 'ro',
231             isa => 'Str',
232             lazy => 1,
233             default => sub {
234             my ( $self ) = @_;
235             return $self->payload->{ spellchecker } // 'aspell list -l en -p ./xt/aspell-en.pws';
236             # Leading dot (in `./xt/aspell.en.pws`) is important! Whitout the dot `aspell`
237             # fails to find the dictionary.
238             },
239             );
240              
241             # --------------------------------------------------------------------------------------------------
242              
243             #pod =option repository
244             #pod
245             #pod Mercurial repository to push changes after release to. Option may be specified multiple times to
246             #pod push changes into several repositories. By default changes are pushed to one repository C<default>.
247             #pod
248             #pod =cut
249              
250             has repository => (
251             isa => 'ArrayRef[Str]',
252             is => 'ro',
253             lazy => 1,
254             default => sub {
255             my ( $self ) = @_;
256             return $self->payload->{ repository } // [ 'default' ];
257             },
258             );
259              
260             # --------------------------------------------------------------------------------------------------
261              
262             #pod =option installer
263             #pod
264             #pod TODO
265             #pod
266             #pod =cut
267              
268             has installer => (
269             isa => 'Str',
270             is => 'ro',
271             lazy => 1,
272             default => sub {
273             my ( $self ) = @_;
274             return $self->payload->{ installer } // 'ModuleBuildTiny';
275             },
276             );
277              
278             # --------------------------------------------------------------------------------------------------
279              
280             #pod =method mvp_multivalue_args
281             #pod
282             #pod =cut
283              
284             sub mvp_multivalue_args {
285 8     8 1 1254649 return qw{ templates unwanted_module unwanted_modules readme repository };
286             };
287              
288             # --------------------------------------------------------------------------------------------------
289              
290             #pod =method _quote
291             #pod
292             #pod Convert an attribute to a form suitable for using in source. C<Str> attribute is converted into a
293             #pod string literal, C<ArrayRef> attribute is converted to a list of string literals.
294             #pod
295             #pod =cut
296              
297             sub _quote {
298 22     22   39 my ( $self, @args ) = @_;
299 22         28 my @names;
300 22         48 for my $arg ( @args ) {
301 22 100       70 for ( ref( $arg ) eq 'ARRAY' ? @$arg : $arg ) {
302 91         84 my $name = $_;
303 91         110 $name =~ s{([\\'])}{\$1}gx;
304 91         185 push( @names, "'$name'" );
305             };
306             };
307 22         1053 return join( ', ', @names );
308             };
309              
310             # --------------------------------------------------------------------------------------------------
311              
312             # Helper func: Iterate through distribution prerequisities.
313              
314             sub MY::prereqs($$) { ## no critic ( ProhibitSubroutinePrototypes )
315 16     16   7704526 my ( $plugin, $callback ) = @_;
316 16         577 my $prereqs = $plugin->zilla->prereqs->cpan_meta_prereqs;
317 16         967 for my $phase ( $prereqs->__legal_phases ) {
318 80         207 for my $type ( $prereqs->__legal_types ) {
319 320 50       884 my $reqs = $prereqs->requirements_for( $phase, $type ) or next;
320 320         6890 for my $module ( keys( %{ $reqs->{ requirements } } ) ) {
  320         913  
321 736         2294 $callback->( $plugin, $module, $phase, $type, $reqs );
322             };
323             };
324             };
325 16         247 return;
326             };
327              
328             sub MY::file {
329 75     75   1378986 my ( $plugin, $name ) = @_;
330 75         136 our $Self; ## no critic ( ProhibitPackageVars )
331 75         372 my $data = $Self->merged_section_data;
332 75         17425 my $root = path( $plugin->zilla->root );
333 75         5875 my $file;
334 75 100       266 if ( $root->child( $name )->exists ) {
    50          
335 21         2221 $file = Dist::Zilla::File::OnDisk->new( {
336             name => $name,
337             } );
338             } elsif ( $data->{ $name } ) {
339             $file = Dist::Zilla::File::InMemory->new( {
340             name => $name,
341 54         3651 content => ${ $data->{ $name } },
  54         2443  
342             } );
343             } else {
344 0         0 croak "$name: file not found";
345             };
346 75         22200 return $file;
347             };
348              
349             # --------------------------------------------------------------------------------------------------
350              
351             sub configure {
352              
353 8     8 0 43 my ( $self ) = @_;
354 8         20 our $Self = $self; ## no critic ( ProhibitPackageVars )
355 8         270 my $name = $self->name;
356              
357             $self->add_plugins(
358              
359             [ 'Hook' => 'prologue' => {
360             # DOES NOT WORK because plugin name will be '$name/prologue'.
361             'hook' => [ q{
362             use autodie ':all';
363             use IPC::System::Simple qw{ capture };
364             use Path::Tiny;
365             } ],
366             } ],
367              
368             [ 'Author::VDB::Version::Read', ],
369              
370             [ 'Hook::Init' => 'init stuff' => {
371             'hook' => [ q[
372             $dist->license->{ program } = 'perl-' . $dist->name;
373             { pack] . q[age MY; # Hide declaration from `new-version.t`.
374             our $name = $dist->name;
375             ( our $package = $name ) =~ s{-}{::}g;
376             our $version = $dist->version;
377             our $Abstract = $dist->abstract;
378             our $abstract = lcfirst( $Abstract );
379             our $author = $dist->authors->[ -1 ];
380             our $metacpan = "https://metacpan.org/release/$name";
381             our $cpan_rt_mailto = "mailto:bug-$name\@rt.cpan.org";
382             our $cpan_rt_browse = "https://rt.cpan.org/Public/Dist/Display.html?Name=$name";
383             our $cpan_rt_report = "https://rt.cpan.org/Public/Bug/Report.html?Queue=$name";
384             our $repo_type ||= "hg";
385             our $repo_host ||= "fedorapeople.org";
386             our $repo_url ||= "https://vandebugger.$repo_host/hg/perl-$name";
387             our $repo_web ||= undef;
388             our $repo_clone = "$repo_type clone $repo_url" .
389             ( $repo_url =~ m{/\Qperl-$name\E\z} ? '' : " \\\\\\n perl-$name" );
390             our $bundle = $Dist::Zilla::PluginBundle::Author::VDB::Self;
391             };
392             $ENV{ 'TEST_FIX' . 'ME_FORMAT' } = 'perl'; # Hide keyword from `fixme.t`.
393             ] ],
394             } ],
395              
396             #
397             # Files to include
398             #
399              
400             [ 'Manifest::Read' ], # REQUIRED VERSION: v0.5.0
401             # Colon-prefixed file finders (e. g. 'Manifest::Read/:AllFiles') are used.
402              
403             #
404             # Generated files
405             #
406              
407             $self->copying ne '' ? (
408             [ 'GenerateFile' => 'COPYING' => {
409             'filename' => 'COPYING',
410             'content' => [
411             q[{] . q[{],
412             q[ include( MY::file( $plugin, ] . $self->_quote( $self->copying ) . q[ ) ) ],
413             q[ ->fill_in ],
414             q[ ->pod2text( width => 80, indent => 0, loose => 1, quotes => 'none' ) ],
415             q[ ->chomp; ],
416             # Resulting file may have one or two empty lines at the end, it affects
417             # testing. Let's try to chomp empty lines to avoid it.
418             q[}] . q[}], # One newline will be added there.
419             ],
420             } ],
421             ) : (
422             ),
423              
424             $self->readme ? (
425             [ 'GenerateFile' => 'README' => {
426             'filename' => 'README',
427             'content' => [
428             q[{] . q[{],
429             q[join( ],
430             q[ "\n\n", ],
431             q[ map( ],
432             q[ { ],
433             q[ include( MY::file( $plugin, $_ ) ) ],
434             q[ ->fill_in ],
435             q[ ->pod2text( width => 80, indent => 0, loose => 1, quotes => 'none' ) ],
436             q[ ->chomp ],
437             q[ } ],
438             q[ ] . $self->_quote( $self->readme ) . q[ ],
439             q[ ) ],
440             q[); ],
441             q[}] . q[}], # One newline will be added there.
442             ],
443             } ],
444             ) : (
445             ),
446              
447             [ 'Manifest::Write' => { # REQUIRED VERSION: v0.9.7
448             # `Manifest::Write` v0.9.0 strictly requires plugin names, not monikers.
449             # `Manifest::Write` v0.9.6 provides `exclude_files` option.
450             # `Manifest::Write` v0.9.7 provides `manifest_skip` option and feature.
451             'source_provider' => [
452             "$name/Manifest::Read",
453             $self->copying ne '' ? "$name/COPYING" : (),
454             $self->readme ? "$name/README" : (),
455             ],
456             'metainfo_provider' => [
457             # Defaults are not suitable because they are just `MetaJSON` and `MetaYAML`.
458             "$name/Manifest::Write",
459             "$name/MetaJSON",
460             "$name/MetaYAML",
461             ],
462             'exclude_files' => [
463             ":ExtraTestFiles", # REQUIRE: Dist::Zilla 5.038
464             ],
465             } ],
466              
467             #
468             # File mungers
469             #
470              
471             [ 'Templates' => { # REQUIRED VERSION: v0.5.0 # for including `Dist::Zilla::File` objects.
472             'templates' => [
473             "$name/src doc",
474 8 100 100     477 @{ $self->templates // [] },
  8 100       321  
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
475             ],
476             } ],
477              
478             [ 'OurPkgVersion' ],
479              
480             [ 'SurgicalPodWeaver' => {
481             'config_plugin' => '@Author::VDB', # REQUIRE: Pod::Weaver::PluginBundle::Author::VDB
482             'replacer' => 'replace_with_comment',
483             } ],
484              
485             [ 'FileFinder::ByName' => 'src doc' => {
486             # Plugin name will be `$name/doc`.
487             'file' => [
488             $self->copying ne '' ? ( 'COPYING' ) : (),
489             $self->readme ? ( 'README' ) : (),
490             ],
491             } ],
492              
493             #
494             # Update sources
495             #
496              
497             # Copy built doc files back to source directory.
498             [ 'Hook::AfterBuild' => 'update src doc' => {
499             'hook' => [ q{
500             use Path::Tiny;
501             my $files = $zilla->plugin_named( '} . $name . q{/src doc' )->find_files();
502             my $build = path( $arg->{ build_root } );
503             my $root = path( $dist->root );
504             for my $file ( @$files ) {
505             my $new_file = $build->child( $file->name );
506             my $old_file = $root->child( $file->name );
507             my $new_bulk = $new_file->slurp;
508             my $old_bulk = $old_file->exists ? $old_file->slurp : undef;
509             if ( not defined( $old_bulk ) or $new_bulk ne $old_bulk ) {
510             $self->log( [ 'updating %s', $file->name ] );
511             $old_file->append( { truncate => 1 }, $new_bulk );
512             # `append` is not atomic, but does not reset file mode.
513             };
514             };
515             } ],
516             } ],
517              
518             #
519             # Tests
520             #
521              
522             [ 'Test::DiagINC' ],
523              
524             # Files
525              
526             [ 'Test::Portability' ], # Checks filenames.
527              
528             [ 'Test::EOL' => {
529             'finder' => "$name/Manifest::Read/:AllFiles",
530             } ],
531              
532             [ 'Test::NoTabs' => {
533             'finder' => "$name/Manifest::Read/:AllFiles",
534             } ],
535              
536             [ 'MojibakeTests' ],
537              
538             # Code
539              
540             [ 'Test::Compile' => {
541             'fake_home' => 1,
542             } ],
543              
544             [ 'Test::Version' => { # All modules have version.
545             finder => "$name/Manifest::Read/:InstallModules",
546             # REQUIRE: Dist::Zilla::Plugin::Manifest::Read v0.4.0 # want `/:InstallModules`.
547             is_strict => 0, # Strict version test fails in trial releases.
548             } ],
549              
550             # I would like to set `Test::Version`'s `is_strict` option to `1`, but it will fail for
551             # trial releases. To avoid that let's do a trick: set `is_strict` to `1` only in case of
552             # non-trial release.
553             [ 'Hook::BeforeBuild' => 'hack Test::Version' => {
554             'hook' => [ q{
555             my $tv = $zilla->plugin_named( '} . $name . q{/Test::Version' );
556             $tv->{ is_strict } = $dist->is_trial ? '0' : '1';
557             } ],
558             } ],
559              
560             [ 'Test::NewVersion' ], # This is not a version already uploaded to CPAN.
561              
562             [ 'Test::MinimumVersion' => {
563             'max_target_perl' => $self->minimum_perl,
564             } ],
565              
566             [ 'Test::Fixme' ],
567              
568             [ 'Test::Perl::Critic' => {
569             'critic_config' => 'xt/perlcritic.ini',
570             # The test does not check tests. TODO: How to fix?
571             } ],
572              
573             # POD
574              
575             [ 'PodSyntaxTests' ], # `Dist-Zilla`-bundled test, uses `Test::Pod`.
576              
577             [ 'PodCoverageTests' ], # `Dist-Zilla`-bundled test, uses `Pod::Coverage::TrustPod`.
578              
579             $self->spellchecker ? (
580             [ 'Test::PodSpelling' => {
581             'spell_cmd' => $self->spellchecker,
582             } ],
583             ) : (
584             ),
585              
586             [ 'Test::Pod::LinkCheck' ],
587              
588             [ 'Test::Pod::No404s' ], # No dead URLs.
589              
590             [ 'Test::Synopsis' ],
591              
592             # Metadata
593              
594             [ 'MetaTests' ], # `Dist-Zilla`-bundled test, uses `Test::CPAN::Meta`, checks `META.yml`.
595              
596             [ 'Test::CPAN::Meta::JSON' ], # Uses `Test::CPAN::Meta::JSON`.
597              
598             [ 'Test::CPAN::Changes' ],
599             # Does not check that `Changes` has a record for current version, see
600             # <https://github.com/doherty/Dist-Zilla-Plugin-Test-CPAN-Changes/issues/6>.
601              
602             [ 'Test::DistManifest' ],
603              
604             # Overall
605              
606             [ 'Test::Kwalitee' ],
607              
608             #
609             # Metainfo
610             #
611              
612             [ 'MinimumPerl' ],
613              
614             [ 'AutoPrereqs' => {
615             'extra_scanners' => 'Hint', # REQUIRE: Perl::PrereqScanner::Scanner::Hint
616             } ],
617              
618             # `Prereqs::AuthorDeps` has a problem:
619             # <https://github.com/dagolden/Dist-Zilla-Plugin-Prereqs-AuthorDeps/issues/1>
620             # It adds local plugins (e. g. tools::GenerateHooks) to the dependencies,
621             # which obviously are not indexed on CPAN.
622             [ 'Prereqs::AuthorDeps' => {
623             #~ 'exclude' => [
624             #~ # Exclude option requires a list of specific files, while I want to ignore all
625             #~ # files in specific directory.
626             #~ ],
627             } ],
628              
629             # TODO: Remove when possible.
630             # This is a dirty hack. Remove it when `Prereqs::AuthorDeps` allows me to ignore all the
631             # modules from `tools/` directory. Meanwhile, find and remove all the dependencies on
632             # modules with `tools::` prefix.
633             [ 'Hook::PrereqSource' => 'tools' => {
634             'hook' => [ q{
635             MY::prereqs( $self, sub {
636             my ( $self, $module, $phase, $type, $reqs ) = @_;
637             if ( $module =~ m{^tools::} ) {
638             $self->log_debug( [
639             'found dependency on module %s (phase %s, type %s), deleting it',
640             $module, $phase, $type
641             ] );
642             delete( $reqs->{ requirements }->{ $module } );
643             };
644              
645             } );
646             } ],
647             } ],
648              
649             # `use autodie ':all';` implicitly requires `IPC::System::Simple` module, but this
650             # dependency is not detected by `AutoPrereqs`. If there is dependency on `autodie`, let
651             # us add dependency on `IPC::System::Simple`.
652             [ 'Hook::PrereqSource' => 'autodie' => {
653             'hook' => [ q{
654             MY::prereqs( $self, sub {
655             my ( $self, $module, $phase, $type ) = @_;
656             if ( $module eq 'autodie' ) {
657             $self->log_debug( [
658             'found dependency on module %s (phase %s, type %s), ' .
659             'adding dependency on IPC::System::Simple',
660             $module, $phase, $type
661             ] );
662             $dist->register_prereqs(
663             { phase => $phase, type => $type },
664             'IPC::System::Simple' => 0,
665             );
666             };
667             } );
668             } ],
669             } ],
670              
671             [ 'MetaProvides::Package' ],
672              
673             [ 'MetaResources::Template' => {
674             'delimiters' => '{ }',
675             'homepage' => '{$MY::metacpan}',
676             'license' => '{$dist->license->url}',
677             'repository.type' => '{$MY::repo_type}',
678             'repository.url' => '{$MY::repo_url}',
679             'repository.web' => '{$MY::repo_web}',
680             'bugtracker.mailto' => '{$MY::cpan_rt_mailto}',
681             'bugtracker.web' => '{$MY::cpan_rt_browse}',
682             } ],
683              
684             [ 'MetaYAML' ], # Generate `META.yml`.
685              
686             [ 'MetaJSON' ], # Generate `META.json`.
687              
688             #
689             # Installer
690             #
691              
692             $self->installer ? (
693             [ $self->installer ],
694             ) : (
695             ),
696              
697             #
698             # Release
699             #
700              
701             $self->archive ? (
702             # Make sure archive directory exists. Do it in the very beginnig of release because
703             # it is simple and fast operation. It will be annoying to pass all the tests and
704             # stop release because `dzil` fails to create archive directory.
705             [ 'Hook::BeforeRelease' => 'archive directory' => {
706             'hook' => [ q{
707             my $root = path( $self->zilla->root . '' );
708             my $dir = path( "} . $self->archive . q{" );
709             if ( $dir->is_absolute ) {
710             $self->log_error( [ 'bad archive directory: %s', "$dir" ] );
711             $self->log_error( [ 'absolute path not allowed' ] );
712             $self->abort();
713             };
714             if ( not $dir->is_dir ) {
715             $self->log( [ 'creating archive directory %s', "$dir" ] );
716             $dir->mkpath();
717             };
718             } ],
719             } ]
720             ) : (
721             ),
722              
723             # I want to run xtest before release. Neither RunExtraTests nor CheckExtraTests work for
724             # me. The first one executes extra test when user runs `dzil test`. I do not want it,
725             # because it slows down regular testing. The second one unpacks tarball, builds it, and
726             # run extra tests… But tarball does not include extra tests.
727              
728             [ 'Hook::BeforeRelease' => 'xtest' => {
729             'hook' => [ q{
730             use File::pushd;
731             my $wd = pushd( $zilla->ensure_built );
732             $zilla->_ensure_blib();
733             use App::Prove;
734             local $ENV{ AUTHOR_TESTING } = 1;
735             local $ENV{ RELEASE_TESTING } = 1;
736             my $prove = App::Prove->new({
737             blib => 1,
738             recurse => 1,
739             argv => [ 'xt' ],
740             });
741             $prove->run() or $self->log_error( "xtest failed" );
742             $self->abort_if_errors();
743             } ],
744             } ],
745              
746             [ 'TestRelease' ], # Unpack tarball and run tests.
747              
748             # Make sure the distro does not depend on unwanted modules. Unwanted module, for example,
749             # is `Data::Printer`. I use it often for debugging purposes and forget to remove
750             # debugging code.
751             [ 'Hook::BeforeRelease' => 'unwanted deps' => {
752             'hook' => [ q{
753             my @unwanted = (} . $self->_quote( $self->unwanted_modules ) . q{);
754             my %unwanted = map( { $_ => 1 } @unwanted );
755             my $heading = 'unwanted modules found:';
756             MY::prereqs( $self, sub {
757             my ( $self, $module, $phase, $type ) = @_;
758             if ( $unwanted{ $module } ) {
759             if ( $heading ) {
760             $self->log_error( $heading );
761             $heading = undef;
762             };
763             $self->log_error( [
764             ' %s (phase %s, type %s)', $module, $phase, $type
765             ] );
766             };
767             } );
768             $self->abort_if_error();
769             } ],
770             } ],
771              
772             [ 'CheckPrereqsIndexed' ], # Make sure all prereqs are published in CPAN.
773              
774             [ 'CheckChangesHasContent' ],
775              
776             $self->spellchecker ? (
777             [ 'Hook::BeforeRelease' => 'spellcheck changes' => {
778             'hook' => [ q{
779             $self->log( 'spellchecking Changes' );
780             use File::pushd;
781             my $wd = pushd( $zilla->built_in );
782             #
783             # Run spellchecker, collect list of unknown words.
784             #
785             use IPC::Run3;
786             my @list;
787             run3( '} . $self->spellchecker . q{', 'Changes', \@list );
788             if ( $? > 0 ) {
789             $self->abort();
790             };
791             chomp( @list );
792             #
793             # Steal list of words to ignore from `PodSpelling` plugin.
794             #
795             my $podspelling = $zilla->plugin_named( '} . $name . q{/Test::PodSpelling' );
796             my %ignore = map( { $_ => 1 } @{ $podspelling->stopwords } );
797             #
798             # Add all module names.
799             #
800             my $prereqs = $dist->prereqs->cpan_meta_prereqs;
801             for my $phase ( $prereqs->__legal_phases ) {
802             for my $type ( $prereqs->__legal_types ) {
803             my $reqs = $prereqs->requirements_for( $phase, $type ) or next;
804             for my $module ( keys( %{ $reqs->{ requirements } } ) ) {
805             $ignore{ $_ } = 1 for split( '::', $module );
806             };
807             };
808             };
809             #
810             # Build maps: word => count and count => word.
811             #
812             my %w2c; # word => count
813             $w2c{ $_ } += 1 for grep( { not $ignore{ $_ } and not $ignore{ lc( $_ ) } } @list );
814             my %c2w; # count => word
815             push( @{ $c2w{ $w2c{ $_ } } }, $_ ) for keys( %w2c );
816             #
817             # Now print the list of spelling errors.
818             #
819             for my $count ( sort( { $b <=> $a } keys( %c2w ) ) ) {
820             printf( "%2d: %s\n", $count, join( ', ', sort( @{ $c2w{ $count } } ) ) );
821             };
822             if ( %w2c ) {
823             $self->abort( 'spelling errors found in Changes' );
824             };
825             } ],
826             } ],
827             ) : (
828             ),
829              
830             [ 'Author::VDB::Hg::Tag::Check', ],
831              
832             [ 'Author::VDB::Hg::Status', ],
833              
834             $self->local_release ? (
835             [ 'Hook::BeforeRelease' => 'release note' => {
836             'hook' => [ q{
837             $self->log( '*** Preparing to *local* release ***' );
838             } ],
839             } ],
840             ) : (
841             ),
842             [ 'ConfirmRelease' ], # Ask confirmation before uploading the release.
843              
844             [ 'Hook::Releaser' => 'tgz' => {
845             'hook' => [ q{
846             $MY::tgz = $arg;
847             } ],
848             } ],
849              
850             # `Archive` is a good plugin, but I need to copy, not move tarball, because I want to
851             # archive the tarball first, and then upload it to CPAN.
852             $self->archive ? (
853             [ 'Hook::Releaser' => 'archive release' => {
854             'hook' => [ q{
855             use Path::Tiny;
856             my $tgz = path( $arg );
857             my $dir = path( "} . $self->archive . q{" );
858             $self->log( [ 'copying %s to %s', "$tgz", "$dir" ] );
859             $tgz->copy( $dir->child( $tgz->basename ) );
860             } ],
861             } ],
862             ) : (
863             ),
864              
865             $self->local_release ? (
866             # No need in `FakeRelease`: we have at least one releaser, it is enough.
867             ) : (
868             [ 'UploadToCPAN' ],
869             ),
870              
871             [ 'Author::VDB::Hg::Tag::Add', ],
872              
873             [ 'NextRelease' => {
874             'format' => '%V @ %{yyyy-MM-dd HH:mm zzz}d',
875             'time_zone' => 'UTC',
876             } ],
877              
878             [ 'Author::VDB::Version::Bump', ],
879              
880             [ 'Author::VDB::Hg::Commit', {
881             'files' => [
882             '.hgtags', # Changed by `Hg::Tag::Add`.
883             'Changes', # Changed by `NextRelease`.
884             'VERSION', # Changed by `Version::Bump`.
885             ],
886             } ],
887              
888             $self->local_release ? (
889             ) : (
890             [ 'Author::VDB::Hg::Push', {
891             repository => $self->repository,
892             } ],
893             ),
894              
895             [ 'Hook::AfterRelease' => 'install' => {
896             'hook' => [ q{
897             use autodie ':all';
898             use File::pushd;
899             $self->log( [ 'installing %s-%s', $dist->name, $dist->version ] );
900             my $wd = pushd( $zilla->built_in );
901             system( 'cpanm', '--notest', '.' );
902             # ^ We run the tests on unpacked tarball before release, no need in running
903             # tests one more time.
904             } ],
905             } ],
906              
907             [ 'Hook::AfterRelease' => 'clean' => {
908             'hook' => [ q{
909             $zilla->clean();
910             } ],
911             } ],
912              
913             );
914              
915 8         9537 return;
916              
917             };
918              
919             __PACKAGE__->meta->make_immutable();
920              
921             1;
922              
923             #pod =head1 COPYRIGHT AND LICENSE
924             #pod
925             #pod Copyright (C) 2015 Van de Bugger
926             #pod
927             #pod License GPLv3+: The GNU General Public License version 3 or later
928             #pod <http://www.gnu.org/licenses/gpl-3.0.txt>.
929             #pod
930             #pod This is free software: you are free to change and redistribute it. There is
931             #pod NO WARRANTY, to the extent permitted by law.
932             #pod
933             #pod
934             #pod =cut
935              
936             # ------------------------------------------------------------------------------------------------
937             #
938             # file: doc/what.pod
939             #
940             # This file is part of perl-Dist-Zilla-PluginBundle-Author-VDB.
941             #
942             # ------------------------------------------------------------------------------------------------
943              
944             #pod =encoding UTF-8
945             #pod
946             #pod =head1 WHAT?
947             #pod
948             #pod C<Dist-Zilla-PluginBundle-Author-VDB> (or just C<@Author::VDB>) is a C<Dist-Zilla> plugin bundle used by VDB.
949             #pod
950             #pod =cut
951              
952             # end of file #
953             # ------------------------------------------------------------------------------------------------
954             #
955             # doc/why.pod
956             #
957             # This file is part of perl-Dist-Zilla-PluginBundle-Author-VDB.
958             #
959             # ------------------------------------------------------------------------------------------------
960              
961             #pod =encoding UTF-8
962             #pod
963             #pod =head1 WHY?
964             #pod
965             #pod I have published few distributions on CPAN. Every distribution have F<dist.ini> file. All the
966             #pod F<dist.ini> files are very similar. Maintaining multiple very similar F<dist.ini> files is boring.
967             #pod Plugin bundle solves the problem.
968             #pod
969             #pod =cut
970              
971             # end of file #
972              
973             =pod
974              
975             =encoding UTF-8
976              
977             =head1 NAME
978              
979             Dist::Zilla::PluginBundle::Author::VDB - VDB's plugin bundle
980              
981             =head1 VERSION
982              
983             Version v0.11.2_06, released on 2016-12-15 22:13 UTC.
984             This is a B<trial release>.
985              
986             =head1 WHAT?
987              
988             C<Dist-Zilla-PluginBundle-Author-VDB> (or just C<@Author::VDB>) is a C<Dist-Zilla> plugin bundle used by VDB.
989              
990             =head1 DESCRIPTION
991              
992             It is unlikely that someone else will want to use it, so I will not bother with documenting it, at
993             least for now.
994              
995             =head1 OBJECT METHODS
996              
997             =head2 mvp_multivalue_args
998              
999             =head2 _quote
1000              
1001             Convert an attribute to a form suitable for using in source. C<Str> attribute is converted into a
1002             string literal, C<ArrayRef> attribute is converted to a list of string literals.
1003              
1004             =head1 OPTIONS
1005              
1006             =head2 minimum_perl
1007              
1008             Optional, default value C<5.006>.
1009              
1010             =head2 copying
1011              
1012             Name of POD file to generate distribution F<COPYING> text file. Empty value disables generation
1013             F<COPYING> file.
1014              
1015             C<Str>, optional, default value C<doc/copying.pod>.
1016              
1017             =head2 readme
1018              
1019             Names of POD files to generate distribution F<README> text file. This is a multi-value option.
1020             Empty values are ignored. Empty list disables generating F<README> file.
1021              
1022             C<ArrayRef[Str]>, optional, default value C<[ 'doc/what.pod', 'doc/why.pod', 'doc/naming.pod', 'doc/forms.pod', 'doc/source.pod', 'doc/distribution.pod', 'doc/installing.pod', 'doc/hacking.pod', 'doc/documentation.pod', 'doc/feedback.pod', 'doc/glossary.pod' ]>.
1023              
1024             =head2 local_release
1025              
1026             If true, release will be a local one, i. e. no external operations will be done: C<UploadToCPAN>
1027             and C<hg push> will be skipped, <hg tag> will create a local tag.
1028              
1029             Option can be set trough F<dist.ini> file or with C<DZIL_LOCAL_RELEASE> environment variable.
1030              
1031             Optional, default value is 0.
1032              
1033             =head2 archive
1034              
1035             Directory to archive files to. If empty, release will not be archived. If such directory does not
1036             exist, it will be created before release.
1037              
1038             Optional, default value C<".releases">.
1039              
1040             =head2 templates
1041              
1042             This option will be passed to C<Templates> plugin. If you no not want C<Templates> to process
1043             files, specify C<:NoFiles>. This is multi-value option (i. e. may be specified several times).
1044              
1045             Optional, default value C<[ ':InstallModules' ]>.
1046              
1047             =head2 unwanted_module
1048              
1049             =head2 unwanted_modules
1050              
1051             TODO C<[ qw{ DDP Data::Printer } ]>.
1052              
1053             =head2 spellchecker
1054              
1055             Command to run spellchecker. Spellchecker command is expected to read text from stdin, and print to
1056             stdout misspelled words. If empty, spellchecking will be skipped. This involve C<Test::PodSpelling>
1057             plugin and internally implemented checking the F<Changes> file.
1058              
1059             Optional, default value C<aspell list -l en -p ./xt/aspell-en.pws>.
1060              
1061             =head2 repository
1062              
1063             Mercurial repository to push changes after release to. Option may be specified multiple times to
1064             push changes into several repositories. By default changes are pushed to one repository C<default>.
1065              
1066             =head2 installer
1067              
1068             TODO
1069              
1070             =head1 WHY?
1071              
1072             I have published few distributions on CPAN. Every distribution have F<dist.ini> file. All the
1073             F<dist.ini> files are very similar. Maintaining multiple very similar F<dist.ini> files is boring.
1074             Plugin bundle solves the problem.
1075              
1076             =for Pod::Coverage configure
1077              
1078             =head1 AUTHOR
1079              
1080             Van de Bugger <van.de.bugger@gmail.com>
1081              
1082             =head1 COPYRIGHT AND LICENSE
1083              
1084             Copyright (C) 2015 Van de Bugger
1085              
1086             License GPLv3+: The GNU General Public License version 3 or later
1087             <http://www.gnu.org/licenses/gpl-3.0.txt>.
1088              
1089             This is free software: you are free to change and redistribute it. There is
1090             NO WARRANTY, to the extent permitted by law.
1091              
1092             =cut
1093              
1094             __DATA__
1095              
1096             __[ not a real section, just a comment ]__
1097              
1098             # `perldoc` interprets POD even after `__DATA__`, so module documentation will include all the
1099             # sections below. To avoid this undesired behavour, prepend each POD directive with backslash —
1100             # it will be stripped by `Data::Section`.
1101              
1102             __[ doc/copying.pod ]__
1103              
1104             \=encoding UTF-8
1105              
1106             \=head1 COPYRIGHT AND LICENSE
1107              
1108             {{$dist->license->notice();}}
1109              
1110             C<perl-{{$MY::name}}> I<distribution> may contain files generated by C<Dist-Zilla> and/or its
1111             plugins from third-party templates; copyright and license specified above are I<not> applicable to
1112             that files.
1113              
1114             \=cut
1115              
1116             __[ doc/distribution.pod ]__
1117              
1118             \=encoding UTF-8
1119              
1120             \=head1 DISTRIBUTION
1121              
1122             C<{{$MY::name}}> distributions are published on L<CPAN|{{$MY::metacpan}}>.
1123              
1124             \=head2 Generated Files
1125              
1126             Distribution may contain files preprocessed or generated by C<Dist-Zilla> and its plugins. Some
1127             generated files are made from C<{{$MY::name}}> source, but some are generated from
1128             third-party templates. Files generated from third-party templates usually include a comment near
1129             the top of the file:
1130              
1131             This file was generated with NAME
1132              
1133             (where I<NAME> is a name of the plugin generated the file). Such files are I<not> part of
1134             C<{{$MY::name}}> source, and C<{{$MY::name}}> copyright and license are not applicable
1135             to such files.
1136              
1137             \=cut
1138              
1139             __[ doc/documentation.pod ]__
1140              
1141             \=encoding UTF-8
1142              
1143             \=head1 DOCUMENTATION
1144              
1145             \=head2 Online
1146              
1147             The easiest way is browsing the documentation L<online at meta::cpan|{{$MY::metacpan}}>.
1148              
1149             \=head2 Locally Installed
1150              
1151             If you have the distribution installed, use C<perldoc> tool to browse locally
1152             installed documentation:
1153              
1154             $ perldoc {{$MY::package}}::Manual
1155             $ perldoc {{$MY::package}}
1156              
1157             \=head2 Built from Source
1158              
1159             Build C<{{$MY::name}}> first (see L</"HACKING">), then:
1160              
1161             $ cd {{$MY::name}}-VERSION
1162             $ perldoc {{$MY::package}}::Manual
1163             $ perldoc {{$MY::package}}
1164              
1165             where I<VERSION> is a version of built distribution.
1166              
1167             \=cut
1168              
1169             __[ doc/feedback.pod ]__
1170              
1171             \=encoding UTF-8
1172              
1173             \=head1 FEEDBACK
1174              
1175             \=head2 CPAN Request Tracker
1176              
1177             The quickest way to report a bug in C<{{$MY::name}}> is by sending email to
1178             bug-{{$MY::name}} [at] rt.cpan.org.
1179              
1180             CPAN request tracker can be used via web interface also:
1181              
1182             \=over
1183              
1184             \=item L<Browse bugs|{{$MY::cpan_rt_browse}}>
1185              
1186             Browsing bugs does not require authentication.
1187              
1188             \=item L<Report bugs|{{$MY::cpan_rt_report}}>
1189              
1190             You need to be a CPAN author, have a L<BitCard|https://www.bitcard.org/> account, or OpenID in
1191             order to report bugs via the web interface.
1192              
1193             (On 2015-04-27 I have logged in successfully with my LiveJournal OpenID, but my Google OpenID did
1194             not work for CPAN. I did not check other OpenID providers.)
1195              
1196             \=back
1197              
1198             \=head2 Send Email to Author
1199              
1200             As a last resort, send email to author: {{$MY::author}}. Please start message subject with
1201             "perl-{{$MY::name}}:".
1202              
1203             \=cut
1204              
1205             __[ doc/forms.pod ]__
1206              
1207             \=encoding UTF-8
1208              
1209             \=head1 FORMS
1210              
1211             You may face C<{{$MY::name}}> in I<source> or I<distribution> forms.
1212              
1213             If you are going to {{$MY::abstract}}, you will likely be interested in I<using>
1214             C<{{$MY::name}}> I<distribution>. If you are going to I<develop> (or I<hack>) the
1215             C<{{$MY::name}}> itself, you will likely need the I<source>, not distribution.
1216              
1217             Since Perl is an interpreting language, modules in the distribution I<look> like sources. Actually,
1218             they are Perl source files. But they are not I<actual> sources, because they are I<built>
1219             (preprocessed or generated) by L<Dist-Zilla>.
1220              
1221             How to distinguish source and distribution:
1222              
1223             \=over
1224              
1225             \=item *
1226              
1227             Source may contain Mercurial files and directories F<.hgignore>, F<.hgtags>, F<.hg/>, while
1228             distribution should not.
1229              
1230             \=item *
1231              
1232             Source should contain F<dist.ini> file, while distribution may not.
1233              
1234             \=item *
1235              
1236             Source should I<not> contain F<xt/> directory, while distribution should.
1237              
1238             \=item *
1239              
1240             Name of source directory does I<not> include version (e. g. C<{{$MY::name}}>), while name of
1241             distribution does (e. g. C<{{$MY::name}}-v0.7.1>).
1242              
1243             \=back
1244              
1245             \=cut
1246              
1247             __[ doc/glossary.pod ]__
1248              
1249             \=encoding UTF-8
1250              
1251             \=head1 GLOSSARY
1252              
1253             \=over
1254              
1255             \=item CPAN
1256              
1257             Comprehensive Perl Archive Network, a B<large> collection of Perl software and documentation. See
1258             L<cpan.org|http://www.cpan.org>, L<What is
1259             CPAN?|http://www.cpan.org/misc/cpan-faq.html#What_is_CPAN>.
1260              
1261             \=item Distribution
1262              
1263             Tarball, containing Perl modules and accompanying files (documentation, metainfo, tests). Usually
1264             distributions are uploaded to CPAN, and can be installed with dedicated tools (C<cpan>, C<cpanm>,
1265             and others).
1266              
1267             \=item Module
1268              
1269             Perl library file, usually with C<.pm> suffix. Usually contains one package. See
1270             L<perlmod|http://perldoc.perl.org/perlmod.html#Perl-Modules>.
1271              
1272             \=item Package
1273              
1274             Perl language construct. See L<package|http://perldoc.perl.org/functions/package.html> and
1275             L<perlmod|http://perldoc.perl.org/perlmod.html#Packages>.
1276              
1277             \=back
1278              
1279             \=cut
1280              
1281             __[ doc/hacking.pod ]__
1282              
1283             \=encoding UTF-8
1284              
1285             \=head1 HACKING
1286              
1287             For hacking, you will need Mercurial, Perl interpreter and C<Dist-Zilla> (with some plugins), and
1288             likely C<cpanm> to install missed parts.
1289              
1290             Clone the repository first:
1291              
1292             $ {{$MY::repo_clone}}
1293             $ cd perl-{{$MY::name}}
1294              
1295             To build a distribution from the source, run:
1296              
1297             $ dzil build
1298              
1299             If required C<Dist-Zilla> plugins are missed, the C<dzil> tool will warn you and show the command
1300             to install all the required plugins, e. g.:
1301              
1302             Required plugin Dist::Zilla::Plugin::Test::EOL isn't installed.
1303              
1304             Run 'dzil authordeps' to see a list of all required plugins.
1305             You can pipe the list to your CPAN client to install or update them:
1306              
1307             dzil authordeps --missing | cpanm
1308              
1309             To run the tests (to check primary software functionality):
1310              
1311             $ dzil test
1312              
1313             To run extended tests (to check source code style, documentation and other things which are not too
1314             important for software end users):
1315              
1316             $ dzil xtest
1317              
1318             To install the distribution:
1319              
1320             $ dzil install
1321              
1322             or
1323              
1324             $ cpanm ./{{$MY::name}}-VERSION.tar.gz
1325              
1326             where I<VERSION> is a version of built distribution.
1327              
1328             To clean the directory:
1329              
1330             $ dzil clean
1331              
1332             \=cut
1333              
1334             __[ doc/installing.pod ]__
1335              
1336             \=encoding UTF-8
1337              
1338             \=head1 INSTALLING
1339              
1340             \=head2 With C<cpanm>
1341              
1342             C<cpanm> tool is (probably) the easiest way to install distribution. It automates downloading,
1343             building, testing, installing, and uninstalling.
1344              
1345             To install the latest version from CPAN:
1346              
1347             $ cpanm {{$MY::package}}
1348              
1349             To install a specific version (e. g. I<v0.7.1>) from CPAN:
1350              
1351             $ cpanm {{$MY::package}}@v0.7.1
1352              
1353             To install locally available distribution (e. g. previously downloaded from CPAN or built from
1354             sources):
1355              
1356             $ cpanm ./{{$MY::name}}-v0.7.1.tar.gz
1357              
1358             To uninstall the distribution:
1359              
1360             $ cpanm -U {{$MY::package}}
1361              
1362             \=head2 Manually
1363              
1364             To install distribution tarball manually (let us assume you have version I<v0.7.1> of the
1365             distribution):
1366              
1367             $ tar xaf {{$MY::name}}-v0.7.1.tar.gz
1368             $ cd {{$MY::name}}-v0.7.1
1369             $ perl Build.PL
1370             $ ./Build build
1371             $ ./Build test
1372             $ ./Build install
1373              
1374             \=head2 See Also
1375              
1376             L<How to install CPAN modules|http://www.cpan.org/modules/INSTALL.html>
1377              
1378             \=cut
1379              
1380             __[ doc/naming.pod ]__
1381              
1382             \=encoding UTF-8
1383              
1384             \=head1 NAMING
1385              
1386             C<perl-{{$MY::name}}> is official software name.
1387              
1388             However, in Perl world prefix "perl-" is redundant and not used. For example, on
1389             L<meta::cpan|https://metacpan.org/> this software is named as C<{{$MY::name}}>. In the rest
1390             of the documentation shortened name C<{{$MY::name}}> is used as synonym for full name
1391             C<perl-{{$MY::name}}>. We are in the Perl world, aren't we?
1392              
1393             You may notice that name may be spelled with dashes (C<{{$MY::name}}>) or with double colons
1394             (C<{{$MY::package}}>). Strictly speaking, there is difference: the first one is software
1395             name, while the second is name of Perl package, but often these names are interchangeable
1396             especially if software consists of single package.
1397              
1398             \=cut
1399              
1400             __[ doc/source.pod ]__
1401              
1402             \=encoding UTF-8
1403              
1404             \=head1 SOURCE
1405              
1406             C<{{$MY::name}}> source is in Mercurial repository hosted on {{$MY::repo_host}}.
1407             {{$MY::repo_web ? "You can either L<browse the source online|{{$MY::repo_web}}> or " : "To
1408             "}} clone the entire repository:
1409              
1410             $ {{$MY::repo_clone}}
1411              
1412             \=head2 Source Files
1413              
1414             C<{{$MY::name}}> source files usually include a comment near the top of the file:
1415              
1416             This file is part of perl-{{$MY::name}}.
1417              
1418             Not all source files are included into distribution. Some source files are used at distribution
1419             build time only, and not required for installation.
1420              
1421             \=cut
1422              
1423             __END__
1424              
1425             # end of file #