File Coverage

blib/lib/Dist/Zilla/PluginBundle/Author/RWSTAUNER.pm
Criterion Covered Total %
statement 27 30 90.0
branch 4 6 66.6
condition 3 6 50.0
subroutine 11 13 84.6
pod n/a
total 45 55 81.8


line stmt bran cond sub pod time code
1             # vim: set ts=2 sts=2 sw=2 expandtab smarttab:
2             #
3             # This file is part of Dist-Zilla-PluginBundle-Author-RWSTAUNER
4             #
5             # This software is copyright (c) 2010 by Randy Stauner.
6             #
7             # This is free software; you can redistribute it and/or modify it under
8             # the same terms as the Perl 5 programming language system itself.
9             #
10 1     1   537 use strict;
  1         1  
  1         22  
11 1     1   3 use warnings;
  1         2  
  1         44  
12              
13             package Dist::Zilla::PluginBundle::Author::RWSTAUNER;
14             # git description: v4.213-1-ge2e9747
15              
16             our $AUTHORITY = 'cpan:RWSTAUNER';
17             $Dist::Zilla::PluginBundle::Author::RWSTAUNER::VERSION = '6.001';
18             # ABSTRACT: RWSTAUNER's Dist::Zilla config
19              
20 1     1   3 use Moose;
  1         1  
  1         7  
21 1     1   4469 use List::Util qw(first); # core
  1         1  
  1         59  
22 1     1   4 use Moose::Util::TypeConstraints 1.01;
  1         19  
  1         6  
23              
24             with qw(
25             Dist::Zilla::Role::PluginBundle::Easy
26             Dist::Zilla::Role::PluginBundle::Config::Slicer
27             Dist::Zilla::Role::PluginBundle::PluginRemover
28             );
29             # Dist::Zilla::Role::DynamicConfig is not necessary: payload is already dynamic
30              
31             # don't require it in case it won't install somewhere
32             my $spelling_tests = eval { require Dist::Zilla::Plugin::Test::PodSpelling; };
33              
34             # cannot use $self->name for class methods
35             sub _bundle_name {
36 41 50 33 41   124   my $class = @_ ? ref $_[0] || $_[0] : __PACKAGE__;
37 41         219   join('', '@', ($class =~ /^.+::PluginBundle::(.+)$/));
38             }
39              
40             sub mvp_multivalue_args { qw(
41             copy_files
42             ) }
43              
44             sub _config {
45 552     552   612   my ($self, $key, $default) = @_;
46 552 100       12965   exists $self->payload->{$key} ? $self->payload->{$key} : $default;
47             }
48              
49             has authority => (
50               is => 'ro',
51               isa => 'Str',
52               lazy => 1,
53               default => sub {
54                 $_[0]->_config(authority => $_[0]->_default_authority);
55               },
56             );
57              
58             sub _default_authority {
59 41 50 66 41   294   (ref($_[0]) || $_[0]) =~ /Author::(\w+)/ ? 'cpan:'.$1 : undef;
60             }
61              
62             has auto_prereqs => (
63               is => 'ro',
64               isa => 'Bool',
65               lazy => 1,
66               default => sub {
67                 $_[0]->_config(auto_prereqs => 1);
68               }
69             );
70              
71             has copy_files => (
72               is => 'ro',
73               isa => 'ArrayRef[Str]',
74               lazy => 1,
75               default => sub {
76                 [ qw( LICENSE ),
77                   map { /(\S+)/g } @{ $_[0]->_config(copy_files => []) } ]
78               },
79             );
80              
81             has fake_release => (
82               is => 'ro',
83               isa => 'Bool',
84               lazy => 1,
85               default => sub {
86                 $_[0]->_config(fake_release => $ENV{DZIL_FAKERELEASE});
87               }
88             );
89              
90             has install_command => (
91               is => 'ro',
92               isa => 'Str',
93               lazy => 1,
94               default => sub {
95             # cpanm will choose the best place to install
96                 $_[0]->_config(install_command => 'cpanm -v -i .');
97               }
98             );
99              
100             has is_task => (
101               is => 'ro',
102               isa => 'Bool',
103               lazy => 1,
104               default => sub {
105                 $_[0]->_config(is_task => 0);
106               }
107             );
108              
109             has max_target_perl => (
110               is => 'ro',
111               isa => 'Str',
112               lazy => 1,
113               default => sub {
114                 $_[0]->_config(max_target_perl => '5.008');
115               }
116             );
117              
118             has open_source => (
119               is => 'ro',
120               isa => 'Bool',
121               lazy => 1,
122               default => sub {
123                 $_[0]->_config(open_source => 1);
124               }
125             );
126              
127             has placeholder_comments => (
128               is => 'ro',
129               isa => 'Bool',
130               lazy => 1,
131               default => sub {
132                 $_[0]->_config(placeholder_comments => 0);
133               }
134             );
135              
136             has releaser => (
137               is => 'ro',
138               isa => 'Str',
139               lazy => 1,
140               default => sub {
141                 $_[0]->_config('releaser', $_[0]->open_source ? 'UploadToCPAN' : '');
142               },
143             );
144              
145             has readme_phase => (
146               is => 'ro',
147               isa => 'Str',
148               lazy => 1,
149               default => sub {
150                 $_[0]->_config(readme_phase => $ENV{DZIL_README_PHASE} || 'release');
151               }
152             );
153              
154             has skip_plugins => (
155               is => 'ro',
156               isa => 'Maybe[Regexp]',
157               lazy => 1,
158               default => sub {
159                 my $skip = $_[0]->_config(skip_plugins => '');
160                 return $skip ? qr/$skip/x : undef;
161               }
162             );
163              
164             has use_git_bundle => (
165               is => 'ro',
166               isa => 'Bool',
167               lazy => 1,
168               default => sub {
169                 $_[0]->_config(use_git_bundle => 1);
170               }
171             );
172              
173             has weaver_config => (
174               is => 'ro',
175               isa => 'Str',
176               lazy => 1,
177               default => sub {
178                 $_[0]->_config(weaver_config => $_[0]->_bundle_name);
179               }
180             );
181              
182             around BUILDARGS => sub {
183               my ($orig, $class, @args) = @_;
184               my $attr = $class->$orig(@args);
185              
186             # removed attributes
187               my %removed = (
188                 builder => '-remove',
189                 disable_tests => '-remove',
190                 skip_prereqs => 'AutoPrereqs.skip',
191               );
192               while( my ($old, $new) = each %removed ){
193                 if( exists $attr->{payload}{ $old } ){
194                   die "$class no longer supports '$old'.\n Please use '$new' instead.\n";
195                 }
196               }
197               return $attr;
198             };
199              
200             # Alter configuration after setup.
201             after configure => sub {
202               my ($self) = @_;
203              
204             # TODO: accept this from ENV
205               my $skip = $self->skip_plugins;
206              
207               my $dynamic = $self->payload;
208             # sneak this config in behind @TestingMania's back
209               $dynamic->{'Test::Compile.fake_home'} = 1
210                 unless first { /Test::Compile\W+fake_home/ } keys %$dynamic;
211              
212               my $plugins = $self->plugins;
213              
214               my $i = -1;
215               while( ++$i < @$plugins ){
216                 my $spec = $plugins->[$i] or next;
217             # NOTE: $conf retains its reference (modifications alter $spec)
218                 my ($name, $class, $conf) = @$spec;
219              
220             # ignore the prefix (@Bundle/Name => Name) (DZP::Name => Name)
221                 my ($alias) = ($name =~ m#([^/]+)$#);
222                 my ($moniker) = ($class =~ m#^(?:Dist::Zilla::Plugin(?:Bundle)?::)?(.+)$#);
223              
224             # exclude any plugins that match 'skip_plugins'
225                 if( $skip ){
226             # match on full name or plugin class (regexp should use \b not \A)
227                   if( $name =~ $skip || $class =~ $skip ){
228                     splice(@$plugins, $i, 1);
229                     redo;
230                   }
231                 }
232               }
233               if ( $ENV{DZIL_BUNDLE_DEBUG} ) {
234                 eval {
235                   require YAML::Tiny; # dzil requires this
236                   $self->log( YAML::Tiny::Dump( $self->plugins ) );
237                 };
238                 warn $@ if $@;
239               }
240             };
241              
242             around add_bundle => sub {
243               my ($orig, $self, $name, @args) = @_;
244               return if $self->skip_plugins && $self->skip_plugins =~ $name;
245               $self->$orig($name, @args);
246             };
247              
248             # Configure plugins.
249             sub configure {
250               my ($self) = @_;
251              
252               $self->log_fatal("you must not specify both weaver_config and is_task")
253                 if $self->is_task and $self->weaver_config ne $self->_bundle_name;
254              
255               $self->add_plugins(
256              
257             # provide version
258             #'Git::DescribeVersion',
259                 'Git::NextVersion',
260              
261             # gather and prune
262                 $self->_generate_manifest_skip,
263                 [ GatherDir => { exclude_filename => [ @{ $self->copy_files } ] } ],
264                 qw(
265             PruneCruft
266             ManifestSkip
267             ),
268             # Devel::Cover db does not need to be packaged with distribution
269                 [ PruneFiles => 'PruneDevelCoverDatabase' => { match => '^(cover_db/.+)' } ],
270             # Code::Stat report
271                 [ PruneFiles => 'PruneCodeStatCollection' => { match => '^codestat\.out' } ],
272             # generated tags file... useful for development but noisy to commit
273                 [ PruneFiles => 'PruneTags' => { match => '^tags$' } ],
274              
275             # We could specify default binary files
276             # but I can't think of any that are commonly included in dists.
277             # I don't mind being explicit if the case is rare.
278             #[ Encoding => 'DefaultBinaryFiles' =>
279             #{ encoding => 'binary', match => '\.(?x: tar\.(gz|bz2) | sqlite | jpg )$' }],
280              
281             # munge files
282             # Do PkgVersion first so other mungers don't eat the blank line after package.
283                 ($self->placeholder_comments ? 'OurPkgVersion' : 'PkgVersion'),
284                 [
285                   Authority => {
286                     ':version' => '1.005', # accepts any non-whitespace + locate_comment
287                     authority => $self->authority,
288                     do_munging => 1,
289                     do_metadata => 1,
290                     locate_comment => $self->placeholder_comments,
291                   }
292                 ],
293                 [
294                   NextRelease => {
295             # w3cdtf
296                     time_zone => 'UTC',
297                     format => q[%-9V %{yyyy-MM-dd'T'HH:mm:ss'Z'}d],
298                   }
299                 ],
300                 'Git::Describe',
301                 [
302                   Prepender => {
303                     ':version' => '1.112280', # 'skip' attribute
304             # don't prepend to tests
305                     skip => '^x?t/.+',
306                   }
307                 ],
308                 ( $self->is_task
309                   ? 'TaskWeaver'
310             # TODO: detect weaver.ini and skip 'config_plugin'?
311                   : [ 'PodWeaver' => { config_plugin => $self->weaver_config } ]
312                 ),
313              
314             # generated distribution files
315                 qw(
316             License
317             Readme
318             ),
319               );
320              
321               $self->add_plugins(
322                 [
323             # Generate README in repo root for github.
324                   ReadmeAnyFromPod => {
325                     ':version' => '0.142180', # 'phase'
326                     type => 'markdown', # L<> to metacpan
327                     location => 'root',
328                     phase => $self->readme_phase,
329                   }
330                 ],
331                 [
332             # ... and add status badges to it.
333                   'GitHubREADME::Badge' => {
334                     ':version' => '0.16', # 'phase', svg
335                     phase => $self->readme_phase,
336                     badges => [qw(
337             travis
338             coveralls
339             cpants
340             )],
341                   }
342                 ],
343                 [ CopyFilesFromRelease => { filename => [ @{ $self->copy_files } ] } ],
344              
345             # metadata
346                 [
347                   AutoMetaResources => {
348                     'bugtracker.rt' => 1,
349             # Currently GithubMeta sets the homepage and this conflicts.
350             #'homepage' => 'http://metacpan.org/release/%{dist}',
351                   }
352                 ],
353                 [ GithubMeta => { ':version' => '0.10' } ],
354                 [ 'Git::Contributors' ],
355               ) if $self->open_source;
356              
357               $self->add_plugins('AutoPrereqs')
358                 if $self->auto_prereqs;
359              
360               $self->add_plugins(
361             # [ 'MetaData::BuiltWith' => { show_uname => 1 } ], # currently DZ::Util::EmulatePhase causes problems
362                 [
363                   MetaNoIndex => {
364                     ':version' => 1.101130,
365             # could use grep { -d $_ } but that will miss any generated files
366                     directory => [
367             # By default skip all directories that PAUSE skips:
368                       't', # skip "t" - libraries in ./t are test libraries!
369                       'xt', # skip "xt" - libraries in ./xt are author test libraries!
370                       'inc', # skip "inc" - libraries in ./inc are usually install libraries
371                       'local', # skip "local" - somebody shipped his carton setup!
372                       'perl5', # skip 'perl5" - somebody shipped her local::lib!
373                       'fatlib', # skip 'fatlib' - somebody shipped their fatpack lib!
374             # Also skip a few other directories commonly used for other things.
375                       'corpus', # Documentation and/or test data.
376                       'examples', # Example
377                       'share', # File::ShareDir... misc files distributed with release.
378                     ],
379                     namespace => [qw(Local t::lib)],
380                     'package' => [qw(DB)],
381                   }
382                 ],
383                 [ # AFTER MetaNoIndex
384                   'MetaProvides::Package' => {
385                     ':version' => '1.14000001',
386                     meta_noindex => 1
387                   }
388                 ],
389              
390                 [ MinimumPerl => { ':version' => '1.003' } ],
391                 qw(
392             MetaConfig
393             MetaYAML
394             MetaJSON
395             ),
396              
397             # I prefer to be explicit about required versions when loading, but this is a handy example:
398             # [
399             # Prereqs => 'TestMoreWithSubtests' => {
400             # -phase => 'test',
401             # -type => 'requires',
402             # 'Test::More' => '0.96'
403             # }
404             # ],
405              
406             # build system
407                 qw(
408             ExecDir
409             ShareDir
410             MakeMaker
411             ),
412               );
413              
414               $self->add_plugins(
415             # generated t/ tests
416                 [ 'Test::ReportPrereqs' => { ':version' => '0.004' } ], # include/exclude
417               );
418              
419             # generated xt/ tests
420             # Test::Pod::Spelling::CommonMistakes ?
421             #Test::Pod::No404s # removed since it's rarely useful
422              
423               if ( $spelling_tests ) {
424                 $self->add_plugins('Test::PodSpelling');
425               }
426               else {
427                 $self->log("Test::PodSpelling Plugin failed to load. Pleese dunt mayke ani misteaks.\n");
428               }
429              
430             # TestingMania is primarily code/dist quality checks.
431               if( $self->open_source ){
432             # NOTE: A newer TestingMania might duplicate plugins if new tests are added
433                 $self->add_bundle('@TestingMania' => {
434                   ':version' => '0.22', # max_target_perl, Test::NoTabs
435                   max_target_perl => $self->max_target_perl,
436                 });
437               }
438             # These are for your own protection.
439               else {
440                 $self->add_plugins(
441                   qw(
442             Test::Compile
443             Test::MinimumVersion
444             PodSyntaxTests
445             ),
446                 );
447               }
448              
449               $self->add_plugins(
450             # manifest: must come after all generated files
451                 'Manifest',
452              
453             # before release
454                 qw(
455             CheckExtraTests
456             ),
457               );
458              
459               $self->add_plugins(
460                 [ CheckChangesHasContent => { ':version' => '0.006' } ], # version-TRIAL
461                 qw(
462             CheckMetaResources
463             CheckPrereqsIndexed
464             )
465               ) if $self->open_source;
466              
467               $self->add_plugins(
468                 qw(
469             TestRelease
470             ),
471               );
472              
473             # defaults: { tag_format => '%v', push_to => [ qw(origin) ] }
474               $self->add_bundle('@Git' => {
475                 ':version' => '2.004', # improved changelog parsing
476                 allow_dirty => [
477                   qw(Changes README.mkdn README.pod),
478                   @{ $self->copy_files }
479                 ],
480                 commit_msg => 'v%v%t%n%n%c'
481               })
482                 if $self->use_git_bundle;
483              
484               $self->add_plugins(
485                 qw(
486             ConfirmRelease
487             ),
488               );
489              
490             # release
491               my $releaser = $self->fake_release ? 'FakeRelease' : $self->releaser;
492             # ignore releaser if it's set to empty string
493               $self->add_plugins($releaser)
494                 if $releaser;
495              
496               $self->add_plugins(
497                 [ InstallRelease => { ':version' => '0.006', install_command => $self->install_command } ]
498               )
499                 if $self->install_command;
500              
501             }
502              
503             # As of Dist::Zilla 4.102345 pluginbundles don't have log and log_fatal methods
504             foreach my $method ( qw(log log_fatal) ){
505               unless( __PACKAGE__->can($method) ){
506 1     1   2449     no strict 'refs'; ## no critic (NoStrict)
  1         1  
  1         121  
507                 *$method = $method =~ /fatal/
508 0     0   0       ? sub { die($_[1]) }
509 0     0   0       : sub { warn("[${\$_[0]->_bundle_name}] $_[1]") };
  0         0  
510               }
511             }
512              
513             sub _generate_manifest_skip {
514             # include a default MANIFEST.SKIP for the tests and/or historical reasons
515               return [
516 40     40   179     GenerateFile => 'GenerateManifestSkip' => {
517                   filename => 'MANIFEST.SKIP',
518                   is_template => 1,
519                   content => <<'EOF_MANIFEST_SKIP',
520            
521             \B\.git\b
522             \B\.gitignore$
523             ^[\._]build
524             ^blib/
525             ^(Build|Makefile)$
526             \bpm_to_blib$
527             ^MYMETA\.
528             ^cover_db/
529            
530             EOF_MANIFEST_SKIP
531                 }
532               ];
533             }
534              
535 1     1   5 no Moose;
  1         1  
  1         4  
536             __PACKAGE__->meta->make_immutable;
537             1;
538              
539             __END__
540            
541             =pod
542            
543             =encoding UTF-8
544            
545             =for :stopwords Randy Stauner ACKNOWLEDGEMENTS RWSTAUNER's PluginBundle cpan testmatrix url
546             annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata
547             placeholders metacpan
548            
549             =head1 NAME
550            
551             Dist::Zilla::PluginBundle::Author::RWSTAUNER - RWSTAUNER's Dist::Zilla config
552            
553             =head1 VERSION
554            
555             version 6.001
556            
557             =head1 SYNOPSIS
558            
559             # dist.ini
560            
561             [@Author::RWSTAUNER]
562            
563             =head1 DESCRIPTION
564            
565             This is an Author
566             L<Dist::Zilla::PluginBundle|Dist::Zilla::Role::PluginBundle::Easy>
567             that I use for building my distributions.
568            
569             =for Pod::Coverage configure
570             log log_fatal
571            
572             =head1 CONFIGURATION
573            
574             Possible options and their default values:
575            
576             authority = cpan:RWSTAUNER
577             auto_prereqs = 1 ; enable AutoPrereqs
578             copy_files = ; space-separated list of additional files to copy from build
579             fake_release = 0 ; if true will use FakeRelease instead of 'releaser'
580             install_command = cpanm -v -i . (passed to InstallRelease)
581             is_task = 0 ; set to true to use TaskWeaver instead of PodWeaver
582             open_source = 1 ; include plugins for cpan/meta/repo/xt/change log, etc
583             placeholder_comments = 0 ; use '# VERSION' and '# AUTHORITY' comments
584             releaser = UploadToCPAN
585             skip_plugins = ; default empty; a regexp of plugin names to exclude
586             weaver_config = @Author::RWSTAUNER
587            
588             The C<fake_release> option also respects C<$ENV{DZIL_FAKERELEASE}>.
589            
590             B<NOTE>:
591             This bundle consumes L<Dist::Zilla::Role::PluginBundle::Config::Slicer>
592             so you can also specify attributes for any of the bundled plugins.
593             The option should be the plugin name and the attribute separated by a dot:
594            
595             [@Author::RWSTAUNER]
596             AutoPrereqs.skip = Bad::Module
597            
598             B<Note> that this is different than
599            
600             [@Author::RWSTAUNER]
601             [AutoPrereqs]
602             skip = Bad::Module
603            
604             which will load the plugin a second time.
605             The first example actually alters the plugin configuration
606             as it is included by the Bundle.
607            
608             See L<Config::MVP::Slicer/CONFIGURATION SYNTAX> for more information.
609            
610             If your situation is more complicated you can use the C<-remove> attribute
611             (courtesy of L<Dist::Zilla::Role::PluginBundle::PluginRemover>)
612             to have the Bundle ignore that plugin
613             and then you can add it yourself:
614            
615             [MetaNoIndex]
616             directory = one-dir
617             directory = another-dir
618             [@Author::RWSTAUNER]
619             -remove = MetaNoIndex
620            
621             C<-remove> can be specified multiple times.
622            
623             Alternatively you can use the C<skip_plugins> attribute (only once)
624             which is a regular expression that matches plugin name or package.
625            
626             [@Author::RWSTAUNER]
627             skip_plugins = MetaNoIndex|SomethingElse
628            
629             =head1 ROUGHLY EQUIVALENT
630            
631             This bundle is roughly equivalent to the following (generated) F<dist.ini>:
632            
633             [Git::NextVersion]
634            
635             [GenerateFile / GenerateManifestSkip]
636             content = \B\.git\b
637             content = \B\.gitignore$
638             content = ^[\._]build
639             content = ^blib/
640             content = ^(Build|Makefile)$
641             content = \bpm_to_blib$
642             content = ^MYMETA\.
643             content = ^cover_db/
644             filename = MANIFEST.SKIP
645             is_template = 1
646            
647             [GatherDir]
648             exclude_filename = LICENSE
649            
650             [PruneCruft]
651             [ManifestSkip]
652            
653             [PruneFiles / PruneDevelCoverDatabase]
654             match = ^(cover_db/.+)
655            
656             [PruneFiles / PruneCodeStatCollection]
657             match = ^codestat\.out
658            
659             [PruneFiles / PruneTags]
660             match = ^tags$
661            
662             [PkgVersion]
663            
664             [Authority]
665             :version = 1.005
666             authority = cpan:RWSTAUNER
667             do_metadata = 1
668             do_munging = 1
669             locate_comment = 0
670            
671             [NextRelease]
672             format = %-9V %{yyyy-MM-dd'T'HH:mm:ss'Z'}d
673             time_zone = UTC
674            
675             [Git::Describe]
676            
677             [Prepender]
678             :version = 1.112280
679             skip = ^x?t/.+
680            
681             [PodWeaver]
682             config_plugin = @Author::RWSTAUNER
683            
684             [License]
685             [Readme]
686            
687             [ReadmeAnyFromPod]
688             :version = 0.142180
689             location = root
690             phase = release
691             type = markdown
692            
693             [GitHubREADME::Badge]
694             :version = 0.16
695             badges = travis
696             badges = coveralls
697             badges = cpants
698             phase = release
699            
700             [CopyFilesFromRelease]
701             filename = LICENSE
702            
703             [AutoMetaResources]
704             bugtracker.rt = 1
705            
706             [GithubMeta]
707             :version = 0.10
708            
709             [Git::Contributors]
710             [AutoPrereqs]
711            
712             [MetaNoIndex]
713             :version = 1.10113
714             directory = t
715             directory = xt
716             directory = inc
717             directory = local
718             directory = perl5
719             directory = fatlib
720             directory = corpus
721             directory = examples
722             directory = share
723             namespace = Local
724             namespace = t::lib
725             package = DB
726            
727             [MetaProvides::Package]
728             :version = 1.14000001
729             meta_noindex = 1
730            
731             [MinimumPerl]
732             :version = 1.003
733            
734             [MetaConfig]
735             [MetaYAML]
736             [MetaJSON]
737             [ExecDir]
738             [ShareDir]
739             [MakeMaker]
740            
741             [Test::ReportPrereqs]
742             :version = 0.004
743            
744             [Test::PodSpelling]
745            
746             [@TestingMania]
747             :version = 0.22
748             max_target_perl = 5.008
749            
750             [Manifest]
751             [CheckExtraTests]
752            
753             [CheckChangesHasContent]
754             :version = 0.006
755            
756             [CheckMetaResources]
757             [CheckPrereqsIndexed]
758             [TestRelease]
759            
760             [@Git]
761             :version = 2.004
762             allow_dirty = Changes
763             allow_dirty = README.mkdn
764             allow_dirty = README.pod
765             allow_dirty = LICENSE
766             commit_msg = v%v%t%n%n%c
767            
768             [ConfirmRelease]
769             [UploadToCPAN]
770            
771             [InstallRelease]
772             :version = 0.006
773             install_command = cpanm -v -i .
774            
775             =head1 SEE ALSO
776            
777             =over 4
778            
779             =item *
780            
781             L<Dist::Zilla>
782            
783             =item *
784            
785             L<Dist::Zilla::Role::PluginBundle::Easy>
786            
787             =item *
788            
789             L<Dist::Zilla::Role::PluginBundle::Config::Slicer>
790            
791             =item *
792            
793             L<Dist::Zilla::Role::PluginBundle::PluginRemover>
794            
795             =item *
796            
797             L<Pod::Weaver>
798            
799             =back
800            
801             =head1 SUPPORT
802            
803             =head2 Perldoc
804            
805             You can find documentation for this module with the perldoc command.
806            
807             perldoc Dist::Zilla::PluginBundle::Author::RWSTAUNER
808            
809             =head2 Websites
810            
811             The following websites have more information about this module, and may be of help to you. As always,
812             in addition to those websites please use your favorite search engine to discover more resources.
813            
814             =over 4
815            
816             =item *
817            
818             MetaCPAN
819            
820             A modern, open-source CPAN search engine, useful to view POD in HTML format.
821            
822             L<http://metacpan.org/release/Dist-Zilla-PluginBundle-Author-RWSTAUNER>
823            
824             =back
825            
826             =head2 Bugs / Feature Requests
827            
828             Please report any bugs or feature requests by email to C<bug-dist-zilla-pluginbundle-author-rwstauner at rt.cpan.org>, or through
829             the web interface at L<https://rt.cpan.org/Public/Bug/Report.html?Queue=Dist-Zilla-PluginBundle-Author-RWSTAUNER>. You will be automatically notified of any
830             progress on the request by the system.
831            
832             =head2 Source Code
833            
834            
835             L<https://github.com/rwstauner/Dist-Zilla-PluginBundle-Author-RWSTAUNER>
836            
837             git clone https://github.com/rwstauner/Dist-Zilla-PluginBundle-Author-RWSTAUNER.git
838            
839             =head1 AUTHOR
840            
841             Randy Stauner <rwstauner@cpan.org>
842            
843             =head1 CONTRIBUTORS
844            
845             =for stopwords Karen Etheridge Sergey Romanov
846            
847             =over 4
848            
849             =item *
850            
851             Karen Etheridge <ether@cpan.org>
852            
853             =item *
854            
855             Sergey Romanov <complefor@rambler.ru>
856            
857             =back
858            
859             =head1 COPYRIGHT AND LICENSE
860            
861             This software is copyright (c) 2010 by Randy Stauner.
862            
863             This is free software; you can redistribute it and/or modify it under
864             the same terms as the Perl 5 programming language system itself.
865            
866             =cut
867