File Coverage

blib/lib/Module/Starter/Simple.pm
Criterion Covered Total %
statement 396 440 90.0
branch 68 118 57.6
condition 17 34 50.0
subroutine 53 61 86.8
pod 37 37 100.0
total 571 690 82.7


line stmt bran cond sub pod time code
1             package Module::Starter::Simple;
2              
3 4     4   277887 use 5.008003;
  4         18  
4 4     4   27 use strict;
  4         8  
  4         131  
5 4     4   31 use warnings;
  4         7  
  4         275  
6              
7 4     4   25 use Cwd 'cwd';
  4         24  
  4         368  
8 4     4   30 use File::Path qw( make_path );
  4         8  
  4         310  
9 4     4   27 use File::Spec ();
  4         7  
  4         207  
10 4     4   25 use Carp qw( carp confess croak );
  4         8  
  4         359  
11 4     4   1778 use Module::Runtime qw( require_module );
  4         4564  
  4         30  
12              
13 4     4   2580 use Module::Starter::BuilderSet;
  4         14  
  4         35275  
14              
15             =head1 NAME
16              
17             Module::Starter::Simple - a simple, comprehensive Module::Starter plugin
18              
19             =head1 VERSION
20              
21             version 1.82
22              
23             =cut
24              
25             our $VERSION = '1.82';
26              
27             =head1 SYNOPSIS
28              
29             use Module::Starter qw(Module::Starter::Simple);
30              
31             Module::Starter->create_distro(%args);
32              
33             =head1 DESCRIPTION
34              
35             Module::Starter::Simple is a plugin for Module::Starter that will perform all
36             the work needed to create a distribution. Given the parameters detailed in
37             L, it will create content, create directories, and populate
38             the directories with the required files.
39              
40             =head1 CLASS METHODS
41              
42             =head2 C<< new(%args) >>
43              
44             This method is called to construct and initialize a new Module::Starter object.
45             It is never called by the end user, only internally by C, which
46             creates ephemeral Module::Starter objects. It's documented only to call it to
47             the attention of subclass authors.
48              
49             =cut
50              
51             sub new {
52 71     71 1 302947 my $class = shift;
53 71         739 return bless { @_ } => $class;
54             }
55              
56             =head1 OBJECT METHODS
57              
58             All the methods documented below are object methods, meant to be called
59             internally by the ephemeral objects created during the execution of the class
60             method C above.
61              
62             =head2 postprocess_config
63              
64             A hook to do any work after the configuration is initially processed.
65              
66             =cut
67              
68 0     0 1 0 sub postprocess_config { 1 };
69              
70             =head2 pre_create_distro
71              
72             A hook to do any work right before the distro is created.
73              
74             =cut
75              
76 0     0 1 0 sub pre_create_distro { 1 };
77              
78             =head2 C<< create_distro(%args) >>
79              
80             This method works as advertised in L.
81              
82             =cut
83              
84             sub create_distro {
85 69     69 1 52084470 my $either = shift;
86              
87 69 100       561 ( ref $either ) or $either = $either->new( @_ );
88              
89 69         163 my $self = $either;
90 69   50     324 my $modules = $self->{modules} || [];
91 69         140 my @modules = map { split /,/ } @{$modules};
  529         1496  
  69         193  
92 69 50       298 croak "No modules specified.\n" unless @modules;
93 69         236 for (@modules) {
94 529 50       2343 croak "Invalid module name: $_" unless /\A[a-z_]\w*(?:::[\w]+)*\Z/i;
95             }
96              
97 69 50 33     156 if ( ( not @{ $self->{author} } ) && ( $^O ne 'MSWin32' ) ) {
  69         361  
98 0         0 ( $self->{author} ) = split /,/, ( getpwuid $> )[6];
99             $self->{author} = [
100             exists $ENV{EMAIL}
101             ? "$self->{author} <$ENV{EMAIL}>"
102             : $self->{author}
103 0 0       0 ] if defined $self->{author};
    0          
104             }
105              
106             croak "Must specify one or more authors\n"
107             unless defined $self->{author}
108             && ref($self->{author}) eq 'ARRAY'
109 69 50 33     670 && @{$self->{author}} > 0;
  69   33     304  
110              
111             croak "author strings must be in the format: 'Author Name '"
112             if grep {
113 70         2545 $_ !~ /
114             \A
115             (?>
116             (?: # Author
117             [^\s<>]+
118             \s+
119             )+
120             )
121             <[^<>]+> # Email
122             \s*
123             \z
124             /x;
125 69 100       156 } @{$self->{author}};
  69         220  
126            
127 56   50     245 $self->{license} ||= 'artistic2';
128 56   100     183 $self->{minperl} ||= '5.008003';
129 56   100     176 $self->{ignores_type} ||= ['generic'];
130 56         136 $self->{manifest_skip} = !! grep { /manifest/ } @{ $self->{ignores_type} };
  218         710  
  56         169  
131            
132 56         281 $self->{license_record} = $self->_license_record();
133              
134 56         806 $self->{main_module} = $modules[0];
135 56 50 33     370 if ( not defined $self->{distro} or not length $self->{distro} ) {
136 0         0 $self->{distro} = $self->{main_module};
137 0         0 $self->{distro} =~ s/::/-/g;
138             }
139              
140 56   33     259 $self->{basedir} = $self->{dir} || $self->{distro};
141 56         282 $self->create_basedir;
142              
143 56         95 my @files;
144 56         281 push @files, $self->create_modules( @modules );
145              
146 56         398 push @files, $self->create_t( @modules );
147 56         351 push @files, $self->create_ignores;
148 56         266 my %build_results = $self->create_build();
149 56         177 push(@files, @{ $build_results{files} } );
  56         179  
150              
151 56         437 push @files, $self->create_Changes;
152 56         287 push @files, $self->create_README( $build_results{instructions} );
153 56 50       390 push @files, $self->create_LICENSE if $self->{genlicense};
154              
155 56 100       276 $self->create_MANIFEST( $build_results{'manifest_method'} ) unless ( $self->{manifest_skip} );
156             # TODO: put files to ignore in a more standard form?
157              
158 56         2732 return @files;
159             }
160              
161             =head2 post_create_distro
162              
163             A hook to do any work after creating the distribution.
164              
165             =cut
166              
167 0     0 1 0 sub post_create_distro { 1 };
168              
169             =head2 pre_exit
170              
171             A hook to do any work right before exit time.
172              
173             =cut
174              
175             sub pre_exit {
176 0     0 1 0 print "Created starter directories and files\n";
177             }
178              
179             =head2 create_basedir
180              
181             Creates the base directory for the distribution. If the directory already
182             exists, and I<$force> is true, then the existing directory will get erased.
183              
184             If the directory can't be created, or re-created, it dies.
185              
186             =cut
187              
188             sub create_basedir {
189 58     58 1 1851 my $self = shift;
190              
191             # Make sure there's no directory
192 58 100       3484 if ( -e $self->{basedir} ) {
193             warn( "$self->{basedir} already exists. ".
194             "Will not overwrite files unless --force is used.\n"
195 28 50       187 ) unless $self->{force};
196             }
197              
198             CREATE_IT: {
199 58         144 $self->progress( "Created $self->{basedir}" );
  58         481  
200              
201 58         13811 make_path $self->{basedir};
202              
203 58 50       997 die "Couldn't create $self->{basedir}: $!\n" unless -d $self->{basedir};
204             }
205              
206 58         143 return;
207             }
208              
209             =head2 create_modules( @modules )
210              
211             This method will create a starter module file for each module named in
212             I<@modules>.
213              
214             =cut
215              
216             sub create_modules {
217 56     56 1 1321 my $self = shift;
218 56         342 my @modules = @_;
219              
220 56         102 my @files;
221              
222 56         183 for my $module ( @modules ) {
223 516         1421 my $rtname = lc $module;
224 516         2967 $rtname =~ s/::/-/g;
225 516         1673 push @files, $self->_create_module( $module, $rtname );
226             }
227              
228 56         618 return @files;
229             }
230              
231             =head2 module_guts( $module, $rtname )
232              
233             This method returns the text which should serve as the contents for the named
234             module. I<$rtname> is the email suffix which rt.cpan.org will use for bug
235             reports. (This should, and will, be moved out of the parameters for this
236             method eventually.)
237              
238             =cut
239              
240             our $LICENSES = {
241             perl => 'Perl_5',
242             artistic => 'Artistic_1_0',
243             artistic2 => 'Artistic_2_0',
244             mozilla => 'Mozilla_1_1',
245             mozilla2 => 'Mozilla_2_0',
246             bsd => 'BSD',
247             freebsd => 'FreeBSD',
248             cc0 => 'CC0_1_0',
249             gpl => 'GPL_2',
250             lgpl => 'LGPL_2_1',
251             gpl3 => 'GPL_3',
252             lgpl3 => 'LGPL_3_0',
253             agpl3 => 'AGPL_3',
254             apache => 'Apache_2_0',
255             qpl => 'QPL_1_0',
256             };
257              
258             sub _license_record {
259 56     56   117 my $self = shift;
260 56         293 my $key = $LICENSES->{ $self->{license} };
261 56 50       168 $key = $self->{license} unless defined $key;
262 56 50       331 my $class = $key =~ m/::/ ? $key : "Software::License::$key";
263             {
264 56         97 local $@;
  56         133  
265 56 50 33     132 undef $class unless eval { require_module $class; 1 } and $class->can('new');
  56         348  
  56         67126  
266             }
267 56 50       235 unless (defined $class) {
268 0         0 require Software::LicenseUtils;
269 0         0 ($class) = Software::LicenseUtils->guess_license_from_meta_key($key);
270 0 0       0 return undef unless defined $class;
271             }
272 56         133 my $author = join ',', @{$self->{author}};
  56         249  
273 56         532 return $class->new( { holder => $author } );
274             }
275              
276             sub _license_blurb {
277 572     572   803 my $self = shift;
278              
279 572         1146 my $record = $self->{license_record};
280 572 50       2858 my $license_blurb = defined($record) ?
281             $record->notice :
282             <<"EOT";
283 0         0 This software is Copyright (c) @{[ $self->_thisyear ]} by @{[ join ',', @{ $self->{author} } ]}.
  0         0  
  0         0  
284              
285             This program is released under the following license:
286              
287             $self->{license}
288             EOT
289              
290 572         856028 chomp $license_blurb;
291 572         1896 return $license_blurb;
292             }
293              
294             # _create_module: used by create_modules to build each file and put data in it
295              
296             sub _create_module {
297 516     516   1017 my $self = shift;
298 516         760 my $module = shift;
299 516         717 my $rtname = shift;
300              
301 516         1712 my @parts = split( /::/, $module );
302 516         1080 my $filepart = (pop @parts) . '.pm';
303 516         1865 my @dirparts = ( $self->{basedir}, 'lib', @parts );
304 516         823 my $SLASH = q{/};
305 516         2260 my $manifest_file = join( $SLASH, 'lib', @parts, $filepart );
306 516 50       1256 if ( @dirparts ) {
307 516         6276 my $dir = File::Spec->catdir( @dirparts );
308 516 100       16479 if ( not -d $dir ) {
309 213         90029 make_path $dir;
310 213         1431 $self->progress( "Created $dir" );
311             }
312             }
313              
314 516         6487 my $module_file = File::Spec->catfile( @dirparts, $filepart );
315              
316 516         5217 $self->{module_file}{$module} = File::Spec->catfile('lib', @parts, $filepart);
317 516         2213 $self->create_file( $module_file, $self->module_guts( $module, $rtname ) );
318 516         3223 $self->progress( "Created $module_file" );
319              
320 516         3313 return $manifest_file;
321             }
322              
323             sub _thisyear {
324 0     0   0 return (localtime())[5] + 1900;
325             }
326              
327             sub _module_to_pm_file {
328 572     572   859 my $self = shift;
329 572         833 my $module = shift;
330              
331 572         1517 my @parts = split( /::/, $module );
332 572         1071 my $pm = pop @parts;
333 572         5330 my $pm_file = File::Spec->catfile( 'lib', @parts, "${pm}.pm" );
334 572         1409 $pm_file =~ s{\\}{/}g; # even on Win32, use forward slash
335              
336 572         2022 return $pm_file;
337             }
338              
339             sub _reference_links {
340             return (
341 572     572   5122 { nickname => 'RT',
342             title => 'CPAN\'s request tracker (report bugs here)',
343             link => 'https://rt.cpan.org/NoAuth/Bugs.html?Dist=%s',
344             },
345             { title => 'GitHub issue tracker',
346             link => 'https://github.com/%s/%s/issues',
347             option => 'github',
348             },
349             { title => 'Search CPAN',
350             link => 'https://metacpan.org/release/%s',
351             },
352             );
353             }
354              
355             =head2 create_Makefile_PL( $main_module )
356              
357             This will create the Makefile.PL for the distribution, and will use the module
358             named in I<$main_module> as the main module of the distribution.
359              
360             =cut
361              
362             sub create_Makefile_PL {
363 32     32 1 96 my $self = shift;
364 32         81 my $main_module = shift;
365 32         102 my $builder_name = 'ExtUtils::MakeMaker';
366 32         139 my $output_file =
367             Module::Starter::BuilderSet->new()->file_for_builder($builder_name);
368 32         721 my $fname = File::Spec->catfile( $self->{basedir}, $output_file );
369              
370 32         169 $self->create_file(
371             $fname,
372             $self->Makefile_PL_guts(
373             $main_module,
374             $self->_module_to_pm_file($main_module),
375             ),
376             );
377              
378 32         258 $self->progress( "Created $fname" );
379              
380 32         83 return $output_file;
381             }
382              
383             =head2 create_MI_Makefile_PL( $main_module )
384              
385             This will create a Module::Install Makefile.PL for the distribution, and will
386             use the module named in I<$main_module> as the main module of the distribution.
387              
388             =cut
389              
390             sub create_MI_Makefile_PL {
391 0     0 1 0 my $self = shift;
392 0         0 my $main_module = shift;
393 0         0 my $builder_name = 'Module::Install';
394 0         0 my $output_file =
395             Module::Starter::BuilderSet->new()->file_for_builder($builder_name);
396 0         0 my $fname = File::Spec->catfile( $self->{basedir}, $output_file );
397              
398 0         0 $self->create_file(
399             $fname,
400             $self->MI_Makefile_PL_guts(
401             $main_module,
402             $self->_module_to_pm_file($main_module),
403             ),
404             );
405              
406 0         0 $self->progress( "Created $fname" );
407              
408 0         0 return $output_file;
409             }
410              
411             =head2 Makefile_PL_guts( $main_module, $main_pm_file )
412              
413             This method is called by create_Makefile_PL and returns text used to populate
414             Makefile.PL; I<$main_pm_file> is the filename of the distribution's main
415             module, I<$main_module>.
416              
417             =cut
418              
419             sub Makefile_PL_guts {
420 32     32 1 61 my $self = shift;
421 32         65 my $main_module = shift;
422 32         69 my $main_pm_file = shift;
423              
424             my $author = '[' .
425 32         72 join(',', map { (my $x = $_) =~ s/'/\'/g; "'$x'" } @{$self->{author}})
  32         120  
  32         161  
  32         150  
426             . ']';
427            
428 32 50       4333 my $slname = $self->{license_record} ? $self->{license_record}->meta2_name : $self->{license};
429              
430 32 50       301 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
431              
432 32         118 my $meta_merge = $self->Makefile_PL_meta_merge;
433              
434 32         454 return <<"HERE";
435             use $self->{minperl};
436             use strict;
437             use $warnings
438             use ExtUtils::MakeMaker;
439              
440             my %WriteMakefileArgs = (
441             NAME => '$main_module',
442             AUTHOR => $author,
443             VERSION_FROM => '$main_pm_file',
444             ABSTRACT_FROM => '$main_pm_file',
445             LICENSE => '$slname',
446             MIN_PERL_VERSION => '$self->{minperl}',
447             CONFIGURE_REQUIRES => {
448             'ExtUtils::MakeMaker' => '0',
449             },
450             TEST_REQUIRES => {
451             'Test::More' => '0',
452             },
453             PREREQ_PM => {
454             #'ABC' => '1.6',
455             #'Foo::Bar::Module' => '5.0401',
456             },
457             dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
458             clean => { FILES => '$self->{distro}-*' },
459             $meta_merge);
460              
461             # Compatibility with old versions of ExtUtils::MakeMaker
462             unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
463             my \$test_requires = delete \$WriteMakefileArgs{TEST_REQUIRES} || {};
464             \@{\$WriteMakefileArgs{PREREQ_PM}}{keys %\$test_requires} = values %\$test_requires;
465             }
466              
467             unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
468             my \$build_requires = delete \$WriteMakefileArgs{BUILD_REQUIRES} || {};
469             \@{\$WriteMakefileArgs{PREREQ_PM}}{keys %\$build_requires} = values %\$build_requires;
470             }
471              
472             delete \$WriteMakefileArgs{CONFIGURE_REQUIRES}
473             unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
474             delete \$WriteMakefileArgs{MIN_PERL_VERSION}
475             unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
476             delete \$WriteMakefileArgs{LICENSE}
477             unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };
478              
479             WriteMakefile(%WriteMakefileArgs);
480             HERE
481              
482             }
483              
484             =head2 Makefile_PL_meta_merge
485              
486             Method called by Makefile_PL_guts. Returns the C section - currently
487             only if the option C is set, in which case the C<< resources => repository >>
488             entry is created.
489              
490             =cut
491              
492             sub Makefile_PL_meta_merge {
493 32     32 1 76 my $self = shift;
494 32 50       180 return '' unless defined $self->{github};
495              
496 0         0 my $username = $self->{github};
497 0         0 my $repository = $self->{distro};
498              
499 0         0 return <<"HERE";
500             META_MERGE => {
501             'meta-spec' => { version => 2 },
502             resources => {
503             repository => {
504             type => 'git',
505             url => 'https://github.com/$username/$repository.git',
506             web => 'https://github.com/$username/$repository',
507             },
508             bugtracker => {
509             web => 'https://github.com/$username/$repository/issues',
510             },
511             },
512             },
513             HERE
514             }
515              
516             =head2 MI_Makefile_PL_guts( $main_module, $main_pm_file )
517              
518             This method is called by create_MI_Makefile_PL and returns text used to populate
519             Makefile.PL; I<$main_pm_file> is the filename of the distribution's main
520             module, I<$main_module>.
521              
522             =cut
523              
524             sub MI_Makefile_PL_guts {
525 0     0 1 0 my $self = shift;
526 0         0 my $main_module = shift;
527 0         0 my $main_pm_file = shift;
528              
529 0         0 my $author = join ',', @{$self->{author}};
  0         0  
530 0         0 $author =~ s/'/\'/g;
531              
532 0 0       0 my $license_url = $self->{license_record} ? $self->{license_record}->url : '';
533              
534             # if there is more than one author, select the first one as
535             # the repository owner
536 0         0 my ($repo_author) = (split /\s*\{author}->[0])[0];
537              
538 0 0       0 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
539              
540 0         0 return <<"HERE";
541             use $self->{minperl};
542             use strict;
543             use $warnings
544             use inc::Module::Install;
545              
546             name '$self->{distro}';
547             all_from '$main_pm_file';
548             author q{$author};
549             license '$self->{license}';
550              
551             perl_version '$self->{minperl}';
552              
553             tests_recursive('t');
554              
555             resources (
556             #homepage => 'http://yourwebsitehere.com',
557             #IRC => 'irc://irc.perl.org/#$self->{distro}',
558             license => '$license_url',
559             #repository => 'git://github.com/$repo_author/$self->{distro}.git',
560             #repository => 'https://bitbucket.org/$repo_author/$self->{distro}',
561             bugtracker => 'https://rt.cpan.org/NoAuth/Bugs.html?Dist=$self->{distro}',
562             );
563              
564             configure_requires (
565             'Module::Install' => '0',
566             );
567              
568             test_requires (
569             'Test::More' => '0',
570             );
571              
572             requires (
573             #'ABC' => '1.6',
574             #'Foo::Bar::Module' => '5.0401',
575             );
576              
577             install_as_cpan;
578             auto_install;
579             WriteAll;
580             HERE
581              
582             }
583              
584             =head2 create_Build_PL( $main_module )
585              
586             This will create the Build.PL for the distribution, and will use the module
587             named in I<$main_module> as the main module of the distribution.
588              
589             =cut
590              
591             sub create_Build_PL {
592 24     24 1 50 my $self = shift;
593 24         48 my $main_module = shift;
594 24         58 my $builder_name = 'Module::Build';
595 24         70 my $output_file =
596             Module::Starter::BuilderSet->new()->file_for_builder($builder_name);
597 24         499 my $fname = File::Spec->catfile( $self->{basedir}, $output_file );
598              
599 24         119 $self->create_file(
600             $fname,
601             $self->Build_PL_guts(
602             $main_module,
603             $self->_module_to_pm_file($main_module),
604             ),
605             );
606              
607 24         195 $self->progress( "Created $fname" );
608              
609 24         55 return $output_file;
610             }
611              
612             =head2 Build_PL_guts( $main_module, $main_pm_file )
613              
614             This method is called by create_Build_PL and returns text used to populate
615             Build.PL; I<$main_pm_file> is the filename of the distribution's main module,
616             I<$main_module>.
617              
618             =cut
619              
620             sub Build_PL_guts {
621 24     24 1 49 my $self = shift;
622 24         51 my $main_module = shift;
623 24         49 my $main_pm_file = shift;
624              
625             my $author = '[' .
626 24         55 join(',', map { (my $x = $_) =~ s/'/\'/g; "'$x'" } @{$self->{author}})
  25         90  
  25         107  
  24         116  
627             . ']';
628              
629 24 50       203 my $slname = $self->{license_record} ? $self->{license_record}->meta2_name : $self->{license};
630            
631 24 50       192 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
632              
633 24         84 my $meta_merge = $self->Build_PL_meta_merge;
634              
635 24         225 return <<"HERE";
636             use $self->{minperl};
637             use strict;
638             use $warnings
639             use Module::Build;
640             Module::Build->VERSION('0.4004');
641              
642             my \$builder = Module::Build->new(
643             module_name => '$main_module',
644             license => '$slname',
645             dist_author => $author,
646             dist_version_from => '$main_pm_file',
647             release_status => 'stable',
648             configure_requires => {
649             'Module::Build' => '0.4004',
650             },
651             test_requires => {
652             'Test::More' => '0',
653             },
654             requires => {
655             #'ABC' => '1.6',
656             #'Foo::Bar::Module' => '5.0401',
657             },
658             add_to_cleanup => [ '$self->{distro}-*' ],
659             $meta_merge);
660              
661             \$builder->create_build_script();
662             HERE
663              
664             }
665              
666             =head2 Build_PL_meta_merge
667              
668             Method called by Build_PL_guts. Returns the C section - currently
669             only if the option C is set, in which case the C<< resources => repository >>
670             entry is created.
671              
672             =cut
673              
674             sub Build_PL_meta_merge {
675 24     24 1 93 my $self = shift;
676 24 50       134 return '' unless defined $self->{github};
677              
678 0         0 my $username = $self->{github};
679 0         0 my $repository = $self->{distro};
680              
681 0         0 return <<"HERE";
682             meta_merge => {
683             resources => {
684             repository => 'https://github.com/$username/$repository',
685             bugtracker => 'https://github.com/$username/$repository/issues',
686             },
687             },
688             HERE
689             }
690              
691             =head2 create_Changes( )
692              
693             This method creates a skeletal Changes file.
694              
695             =cut
696              
697             sub create_Changes {
698 59     59 1 2952 my $self = shift;
699              
700 59         949 my $fname = File::Spec->catfile( $self->{basedir}, 'Changes' );
701 59         287 $self->create_file( $fname, $self->Changes_guts() );
702 59         390 $self->progress( "Created $fname" );
703              
704 59         179 return 'Changes';
705             }
706              
707             =head2 Changes_guts
708              
709             Called by create_Changes, this method returns content for the Changes file.
710              
711             =cut
712              
713             sub Changes_guts {
714 59     59 1 111 my $self = shift;
715              
716 59         383 return <<"HERE";
717             Revision history for $self->{distro}
718              
719             0.01 Date/time
720             First version, released on an unsuspecting world.
721              
722             HERE
723             }
724              
725             =head2 create_LICENSE
726              
727             This method creates the distribution's LICENSE file.
728              
729             =cut
730              
731             sub create_LICENSE {
732 56     56 1 98 my $self = shift;
733            
734 56   50     202 my $record = $self->{license_record} || return ();
735 56         941 my $fname = File::Spec->catfile( $self->{basedir}, 'LICENSE' );
736 56         461 $self->create_file( $fname, $record->license );
737 56         676 $self->progress( "Created $fname" );
738            
739 56         246 return 'LICENSE';
740             }
741              
742             =head2 create_README( $build_instructions )
743              
744             This method creates the distribution's README file.
745              
746             =cut
747              
748             sub create_README {
749 56     56 1 112 my $self = shift;
750 56         108 my $build_instructions = shift;
751              
752 56         885 my $fname = File::Spec->catfile( $self->{basedir}, 'README' );
753 56         287 $self->create_file( $fname, $self->README_guts($build_instructions) );
754 56         387 $self->progress( "Created $fname" );
755              
756 56         235 return 'README';
757             }
758              
759             =head2 README_guts
760              
761             Called by create_README, this method returns content for the README file.
762              
763             =cut
764              
765             sub _README_intro {
766 56     56   106 my $self = shift;
767              
768 56         144 return <<"HERE";
769             The README is used to introduce the module and provide instructions on
770             how to install the module, any machine dependencies it may have (for
771             example C compilers and installed libraries) and any other information
772             that should be provided before the module is installed.
773              
774             A README file is required for CPAN modules since CPAN extracts the README
775             file from a module distribution so that people browsing the archive
776             can use it to get an idea of the module's uses. It is usually a good idea
777             to provide version information here so that people can decide whether
778             fixes for the module are worth downloading.
779             HERE
780             }
781              
782             sub _README_information {
783 56     56   101 my $self = shift;
784              
785 56         155 my @reference_links = _reference_links();
786              
787 56         140 my $content = "You can also look for information at:\n";
788              
789 56         149 foreach my $ref (@reference_links){
790 168 100 66     707 next if $ref->{option} && !$self->{$ref->{option}};
791              
792 112         161 my $title;
793 112 100       343 $title = "$ref->{nickname}, " if exists $ref->{nickname};
794 112         285 $title .= $ref->{title};
795 112 50       484 my $link = sprintf($ref->{link}, $ref->{option} ? $self->{$ref->{option}} : (), $self->{distro});
796              
797 112         442 $content .= qq[
798             $title
799             $link
800             ];
801             }
802              
803 56         270 return $content;
804             }
805              
806             sub _README_license {
807 56     56   94 my $self = shift;
808              
809 56         179 my $license_blurb = $self->_license_blurb();
810 56         286 return <<"HERE";
811             LICENSE AND COPYRIGHT
812              
813             $license_blurb
814             HERE
815             }
816              
817             sub README_guts {
818 56     56 1 114 my $self = shift;
819 56         97 my $build_instructions = shift;
820              
821 56         164 my $intro = $self->_README_intro();
822 56         185 my $information = $self->_README_information();
823 56         226 my $license = $self->_README_license();
824              
825 56         838 return <<"HERE";
826             $self->{distro}
827              
828             $intro
829              
830             INSTALLATION
831              
832             $build_instructions
833              
834             SUPPORT AND DOCUMENTATION
835              
836             After installing, you can find documentation for this module with the
837             perldoc command.
838              
839             perldoc $self->{main_module}
840              
841             $information
842              
843             $license
844             HERE
845             }
846              
847             =head2 create_t( @modules )
848              
849             This method creates a bunch of *.t files. I<@modules> is a list of all modules
850             in the distribution.
851              
852             =cut
853              
854             sub create_t {
855 56     56 1 115 my $self = shift;
856 56         347 my @modules = @_;
857              
858 56         318 my %t_files = $self->t_guts(@modules);
859 56         257 my %xt_files = $self->xt_guts(@modules);
860              
861 56         125 my @files;
862 56         225 push @files, map { $self->_create_t('t', $_, $t_files{$_}) } keys %t_files;
  224         733  
863 56         298 push @files, map { $self->_create_t('xt', $_, $xt_files{$_}) } keys %xt_files;
  56         181  
864              
865 56         606 return @files;
866             }
867              
868             =head2 t_guts( @modules )
869              
870             This method is called by create_t, and returns a description of the *.t files
871             to be created.
872              
873             The return value is a hash of test files to create. Each key is a filename and
874             each value is the contents of that file.
875              
876             =cut
877              
878             sub t_guts {
879 56     56 1 107 my $self = shift;
880 56         211 my @modules = @_;
881              
882 56         97 my %t_files;
883 56         170 my $minperl = $self->{minperl};
884 56 50       303 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
885              
886 56         245 my $header = <<"EOH";
887             #!perl
888             use $minperl;
889             use strict;
890             use $warnings
891             use Test::More;
892              
893             EOH
894            
895 56         247 $t_files{'pod.t'} = $header.<<'HERE';
896             unless ( $ENV{RELEASE_TESTING} ) {
897             plan( skip_all => "Author tests not required for installation" );
898             }
899              
900             # Ensure a recent version of Test::Pod
901             my $min_tp = 1.22;
902             eval "use Test::Pod $min_tp";
903             plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
904              
905             all_pod_files_ok();
906             HERE
907              
908 56         192 $t_files{'manifest.t'} = $header.<<'HERE';
909             unless ( $ENV{RELEASE_TESTING} ) {
910             plan( skip_all => "Author tests not required for installation" );
911             }
912              
913             my $min_tcm = 0.9;
914             eval "use Test::CheckManifest $min_tcm";
915             plan skip_all => "Test::CheckManifest $min_tcm required" if $@;
916              
917             ok_manifest();
918             HERE
919              
920 56         223 $t_files{'pod-coverage.t'} = $header.<<'HERE';
921             unless ( $ENV{RELEASE_TESTING} ) {
922             plan( skip_all => "Author tests not required for installation" );
923             }
924              
925             # Ensure a recent version of Test::Pod::Coverage
926             my $min_tpc = 1.08;
927             eval "use Test::Pod::Coverage $min_tpc";
928             plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
929             if $@;
930              
931             # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
932             # but older versions don't recognize some common documentation styles
933             my $min_pc = 0.18;
934             eval "use Pod::Coverage $min_pc";
935             plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
936             if $@;
937              
938             all_pod_coverage_ok();
939             HERE
940              
941 56         134 my $nmodules = @modules;
942 56         154 my $main_module = $modules[0];
943             my $use_lines = join(
944 56         179 "\n", map { qq{ use_ok( '$_' ) || print "Bail out!\\n";} } @modules
  516         1265  
945             );
946              
947 56         466 $t_files{'00-load.t'} = $header.<<"HERE";
948             plan tests => $nmodules;
949              
950             BEGIN {
951             $use_lines
952             }
953              
954             diag( "Testing $main_module \$${main_module}::VERSION, Perl \$], \$^X" );
955             HERE
956              
957 56         429 return %t_files;
958             }
959              
960             =head2 xt_guts( @modules )
961              
962             This method is called by create_t, and returns a description of the author
963             only *.t files to be created in the xt directory.
964              
965             The return value is a hash of test files to create. Each key is a filename and
966             each value is the contents of that file.
967              
968             =cut
969              
970             sub xt_guts {
971 56     56 1 101 my $self = shift;
972 56         194 my @modules = @_;
973              
974 56         87 my %xt_files;
975 56         164 my $minperl = $self->{minperl};
976 56 50       228 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
977              
978 56         206 my $header = <<"EOH";
979             #!perl
980             use $minperl;
981             use strict;
982             use $warnings
983             use Test::More;
984              
985             EOH
986              
987 56         92 my $module_boilerplate_tests;
988             $module_boilerplate_tests .=
989 56         256 " module_boilerplate_ok('".$self->_module_to_pm_file($_)."');\n" for @modules;
990              
991 56         139 my $boilerplate_tests = @modules + 2;
992 56         507 $xt_files{'boilerplate.t'} = $header.<<"HERE";
993             plan tests => $boilerplate_tests;
994              
995             sub not_in_file_ok {
996             my (\$filename, \%regex) = \@_;
997             open( my \$fh, '<', \$filename )
998             or die "couldn't open \$filename for reading: \$!";
999              
1000             my \%violated;
1001              
1002             while (my \$line = <\$fh>) {
1003             while (my (\$desc, \$regex) = each \%regex) {
1004             if (\$line =~ \$regex) {
1005             push \@{\$violated{\$desc}||=[]}, \$.;
1006             }
1007             }
1008             }
1009              
1010             if (\%violated) {
1011             fail("\$filename contains boilerplate text");
1012             diag "\$_ appears on lines \@{\$violated{\$_}}" for keys \%violated;
1013             } else {
1014             pass("\$filename contains no boilerplate text");
1015             }
1016             }
1017              
1018             sub module_boilerplate_ok {
1019             my (\$module) = \@_;
1020             not_in_file_ok(\$module =>
1021             'the great new \$MODULENAME' => qr/ - The great new /,
1022             'boilerplate description' => qr/Quick summary of what the module/,
1023             'stub function definition' => qr/function[12]/,
1024             );
1025             }
1026              
1027             TODO: {
1028             local \$TODO = "Need to replace the boilerplate text";
1029              
1030             not_in_file_ok(README =>
1031             "The README is used..." => qr/The README is used/,
1032             "'version information here'" => qr/to provide version information/,
1033             );
1034              
1035             not_in_file_ok(Changes =>
1036             "placeholder date/time" => qr(Date/time)
1037             );
1038              
1039             $module_boilerplate_tests
1040              
1041             }
1042              
1043             HERE
1044              
1045 56         321 return %xt_files;
1046             }
1047              
1048             sub _create_t {
1049 280     280   512 my $self = shift;
1050 280         491 my $directory = shift; # 't' or 'xt'
1051 280         532 my $filename = shift;
1052 280         454 my $content = shift;
1053              
1054 280         761 my @dirparts = ( $self->{basedir}, $directory );
1055 280         2784 my $tdir = File::Spec->catdir( @dirparts );
1056 280 100       10743 if ( not -d $tdir ) {
1057 58         12753 make_path $tdir;
1058 58         430 $self->progress( "Created $tdir" );
1059             }
1060              
1061 280         2890 my $fname = File::Spec->catfile( @dirparts, $filename );
1062 280         1148 $self->create_file( $fname, $content );
1063 280         1597 $self->progress( "Created $fname" );
1064              
1065 280         1708 return join('/', $directory, $filename );
1066             }
1067              
1068             =head2 create_MB_MANIFEST
1069              
1070             This methods creates a MANIFEST file using Module::Build's methods.
1071              
1072             =cut
1073              
1074             sub create_MB_MANIFEST {
1075 2     2 1 4 my $self = shift;
1076 2         16 $self->create_EUMM_MANIFEST;
1077             }
1078              
1079             =head2 create_MI_MANIFEST
1080              
1081             This method creates a MANIFEST file using Module::Install's methods.
1082              
1083             Currently runs ExtUtils::MakeMaker's methods.
1084              
1085             =cut
1086              
1087             sub create_MI_MANIFEST {
1088 0     0 1 0 my $self = shift;
1089 0         0 $self->create_EUMM_MANIFEST;
1090             }
1091              
1092             =head2 create_EUMM_MANIFEST
1093              
1094             This method creates a MANIFEST file using ExtUtils::MakeMaker's methods.
1095              
1096             =cut
1097              
1098             sub create_EUMM_MANIFEST {
1099 2     2 1 5 my $self = shift;
1100 2         13011 my $orig_dir = cwd();
1101              
1102             # create the MANIFEST in the correct path
1103 2 50       117 chdir $self->{'basedir'} || die "Can't reach basedir: $!\n";
1104              
1105 2         1288 require ExtUtils::Manifest;
1106 2         13753 $ExtUtils::Manifest::Quiet = 0;
1107 2         25 ExtUtils::Manifest::mkmanifest();
1108              
1109             # return to our original path, wherever it was
1110 2 50       7872 chdir $orig_dir || die "Can't return to original dir: $!\n";
1111             }
1112              
1113             =head2 create_MANIFEST( $method )
1114              
1115             This method creates the distribution's MANIFEST file. It must be run last,
1116             because all the other create_* functions have been returning the functions they
1117             create.
1118              
1119             It receives a method to run in order to create the MANIFEST file. That way it
1120             can create a MANIFEST file according to the builder used.
1121              
1122             =cut
1123              
1124             sub create_MANIFEST {
1125 2     2 1 7 my ( $self, $manifest_method ) = @_;
1126 2         32 my $fname = File::Spec->catfile( $self->{basedir}, 'MANIFEST' );
1127              
1128 2         15 $self->$manifest_method();
1129 2         53 $self->filter_lines_in_file(
1130             $fname,
1131             qr/^xt\/boilerplate\.t$/,
1132             qr/^ignore\.txt$/,
1133             );
1134              
1135 2         31 $self->progress( "Created $fname" );
1136              
1137 2         12 return 'MANIFEST';
1138             }
1139              
1140             =head2 get_builders( )
1141              
1142             This methods gets the correct builder(s).
1143              
1144             It is called by C, and returns an arrayref with the builders.
1145              
1146             =cut
1147              
1148             sub get_builders {
1149 56     56 1 89 my $self = shift;
1150              
1151             # pass one: pull the builders out of $self->{builder}
1152             my @tmp =
1153 0         0 ref $self->{'builder'} eq 'ARRAY' ? @{ $self->{'builder'} }
1154 56 50       351 : $self->{'builder'};
1155              
1156 56         143 my @builders;
1157 56         109 my $COMMA = q{,};
1158             # pass two: expand comma-delimited builder lists
1159 56         134 foreach my $builder (@tmp) {
1160 56         1724 push( @builders, split( $COMMA, $builder ) );
1161             }
1162              
1163 56         251 return \@builders;
1164             }
1165              
1166             =head2 create_build( )
1167              
1168             This method creates the build file(s) and puts together some build
1169             instructions. The builders currently supported are:
1170              
1171             ExtUtils::MakeMaker
1172             Module::Build
1173             Module::Install
1174              
1175             =cut
1176              
1177             sub create_build {
1178 56     56 1 118 my $self = shift;
1179              
1180             # get the builders
1181 56         142 my @builders = @{ $self->get_builders };
  56         184  
1182 56         723 my $builder_set = Module::Starter::BuilderSet->new();
1183              
1184             # Remove mutually exclusive and unsupported builders
1185 56         297 @builders = $builder_set->check_compatibility( @builders );
1186              
1187             # compile some build instructions, create a list of files generated
1188             # by the builders' create_* methods, and call said methods
1189              
1190 56         184 my @build_instructions;
1191             my @files;
1192 56         0 my $manifest_method;
1193              
1194 56         123 foreach my $builder ( @builders ) {
1195 56 50       166 if ( !@build_instructions ) {
1196 56         126 push( @build_instructions,
1197             'To install this module, run the following commands:'
1198             );
1199             }
1200             else {
1201 0         0 push( @build_instructions,
1202             "Alternatively, to install with $builder, you can ".
1203             "use the following commands:"
1204             );
1205             }
1206 56         154 push( @files, $builder_set->file_for_builder($builder) );
1207 56         220 my @commands = $builder_set->instructions_for_builder($builder);
1208 56         167 push( @build_instructions, join("\n", map { "\t$_" } @commands) );
  224         629  
1209              
1210 56         238 my $build_method = $builder_set->method_for_builder($builder);
1211 56         475 $self->$build_method($self->{main_module});
1212              
1213 56         290 $manifest_method = $builder_set->manifest_method($builder);
1214             }
1215              
1216             return(
1217 56         1152 files => [ @files ],
1218             instructions => join( "\n\n", @build_instructions ),
1219             manifest_method => $manifest_method,
1220             );
1221             }
1222              
1223              
1224             =head2 create_ignores()
1225              
1226             This creates a text file for use as MANIFEST.SKIP, .cvsignore,
1227             .gitignore, or whatever you use.
1228              
1229             =cut
1230              
1231             sub create_ignores {
1232 56     56 1 102 my $self = shift;
1233 56         206 my $type = $self->{ignores_type};
1234 56         524 my %names = (
1235             generic => 'ignore.txt',
1236             cvs => '.cvsignore',
1237             git => '.gitignore',
1238             hg => '.hgignore',
1239             manifest => 'MANIFEST.SKIP',
1240             );
1241              
1242             my $create_file = sub {
1243 218     218   475 my $type = shift;
1244 218         506 my $name = $names{$type};
1245 218         3218 my $fname = File::Spec->catfile( $self->{basedir}, $names{$type} );
1246 218         792 $self->create_file( $fname, $self->ignores_guts($type) );
1247 218         1272 $self->progress( "Created $fname" );
1248 56         487 };
1249              
1250 56 50       220 if ( ref $type eq 'ARRAY' ) {
    0          
1251 56         130 foreach my $single_type ( @{$type} ) {
  56         262  
1252 218         492 $create_file->($single_type);
1253             }
1254             } elsif ( ! ref $type ) {
1255 0         0 $create_file->($type);
1256             }
1257              
1258 56         613 return; # Not a file that goes in the MANIFEST
1259             }
1260              
1261             =head2 ignores_guts()
1262              
1263             Called by C, this method returns the contents of the
1264             ignore file.
1265              
1266             =cut
1267              
1268             sub ignores_guts {
1269 218     218 1 521 my ($self, $type) = @_;
1270              
1271 218 100       679 my $ms = $self->{manifest_skip} ? "MANIFEST\nMANIFEST.bak\n" : '';
1272 218         1165 my $guts = {
1273             generic => $ms.<<"EOF",
1274             Makefile
1275             Makefile.old
1276             Build
1277             Build.bat
1278             META.*
1279             MYMETA.*
1280             .build/
1281             _build/
1282             cover_db/
1283             blib/
1284             inc/
1285             .lwpcookies
1286             .last_cover_stats
1287             nytprof.out
1288             pod2htm*.tmp
1289             pm_to_blib
1290             $self->{distro}-*
1291             $self->{distro}-*.tar.gz
1292             EOF
1293             # make this more restrictive, since MANIFEST tends to be less noticeable
1294             # (also, manifest supports REs.)
1295             manifest => <<'EOF',
1296             # Top-level filter (only include the following...)
1297             ^(?!(?:script|examples|lib|inc|t|xt|maint)/|(?:(?:Makefile|Build)\.PL|README|LICENSE|MANIFEST|Changes|META\.(?:yml|json))$)
1298              
1299             # Avoid version control files.
1300             \bRCS\b
1301             \bCVS\b
1302             ,v$
1303             \B\.svn\b
1304             \b_darcs\b
1305             # (.git or .hg only in top-level, hence it's blocked above)
1306              
1307             # Avoid temp and backup files.
1308             ~$
1309             \.tmp$
1310             \.old$
1311             \.bak$
1312             \..*?\.sw[po]$
1313             \#$
1314             \b\.#
1315              
1316             # avoid OS X finder files
1317             \.DS_Store$
1318              
1319             # ditto for Windows
1320             \bdesktop\.ini$
1321             \b[Tt]humbs\.db$
1322              
1323             # Avoid patch remnants
1324             \.orig$
1325             \.rej$
1326             EOF
1327             };
1328 218         3957 $guts->{hg} = $guts->{cvs} = $guts->{git} = $guts->{generic};
1329            
1330 218         1116 return $guts->{$type};
1331             }
1332              
1333             =head1 HELPER METHODS
1334              
1335             =head2 verbose
1336              
1337             C tells us whether we're in verbose mode.
1338              
1339             =cut
1340              
1341 1572     1572 1 5417 sub verbose { return shift->{verbose} }
1342              
1343             =head2 create_file( $fname, @content_lines )
1344              
1345             Creates I<$fname>, dumps I<@content_lines> in it, and closes it.
1346             Dies on any error.
1347              
1348             =cut
1349              
1350             sub create_file {
1351 1241     1241 1 494075 my $self = shift;
1352 1241         2035 my $fname = shift;
1353              
1354 1241 100       43185 if ( -f $fname ) {
1355 608 100       2682 if ( !$self->{'force'} ) {
1356 1         35 warn "Will not overwrite '$fname' (--force option not enabled)";
1357 1         6 return;
1358             }
1359             }
1360              
1361 1240         3921 my @content = @_;
1362 1240 50       153875 open( my $fh, '>', $fname ) or confess "Can't create $fname: $!\n";
1363 1240         4056 print {$fh} @content;
  1240         9929  
1364 1240 50       158559 close $fh or die "Can't close $fname: $!\n";
1365              
1366 1240         10197 return;
1367             }
1368              
1369             =head2 progress( @list )
1370              
1371             C prints the given progress message if we're in verbose mode.
1372              
1373             =cut
1374              
1375             sub progress {
1376 1572     1572 1 2720 my $self = shift;
1377 1572 50       4274 print @_, "\n" if $self->verbose;
1378              
1379 1572         3403 return;
1380             }
1381              
1382             =head2 filter_lines_in_file( $filename, @compiled_regexes )
1383              
1384             C goes over a file and removes lines with the received
1385             regexes.
1386              
1387             For example, removing t/boilerplate.t in the MANIFEST.
1388              
1389             =cut
1390              
1391             sub filter_lines_in_file {
1392 2     2 1 12 my ( $self, $file, @regexes ) = @_;
1393 2         3 my @read_lines;
1394 2 50       83 open my $fh, '<', $file or die "Can't open file $file: $!\n";
1395 2         99 @read_lines = <$fh>;
1396 2 50       27 close $fh or die "Can't close file $file: $!\n";
1397              
1398 2         6 chomp @read_lines;
1399              
1400 2 50       154 open $fh, '>', $file or die "Can't open file $file: $!\n";
1401 2         13 foreach my $line (@read_lines) {
1402 28         33 my $found;
1403              
1404 28         32 foreach my $regex (@regexes) {
1405 56 100       177 if ( $line =~ $regex ) {
1406 4         9 $found++;
1407             }
1408             }
1409              
1410 28 100       74 $found or print {$fh} "$line\n";
  24         77  
1411             }
1412 2 50       401 close $fh or die "Can't close file $file: $!\n";
1413             }
1414              
1415             =head1 BUGS
1416              
1417             Please report any bugs or feature requests to the bugtracker for this project
1418             on GitHub at: L. I will be
1419             notified, and then you'll automatically be notified of progress on your bug
1420             as I make changes.
1421              
1422             =head1 AUTHOR
1423              
1424             Dan Book, L<< >>
1425              
1426             Sawyer X, C<< >>
1427              
1428             Andy Lester, C<< >>
1429              
1430             C.J. Adams-Collier, C<< >>
1431              
1432             =head1 Copyright & License
1433              
1434             Copyright 2005-2009 Andy Lester and C.J. Adams-Collier, All Rights Reserved.
1435              
1436             Copyright 2010 Sawyer X, All Rights Reserved.
1437              
1438             This program is free software; you can redistribute it and/or modify it
1439             under the same terms as Perl itself.
1440              
1441             Please note that these modules are not products of or supported by the
1442             employers of the various contributors to the code.
1443              
1444             =cut
1445              
1446             sub _module_header {
1447 516     516   748 my $self = shift;
1448 516         689 my $module = shift;
1449 516         745 my $rtname = shift;
1450 516 50       2569 my $warnings = sprintf 'warnings%s;', ($self->{fatalize} ? " FATAL => 'all'" : '');
1451              
1452 516         2605 my $content = <<"HERE";
1453             package $module;
1454              
1455             use $self->{minperl};
1456             use strict;
1457             use $warnings
1458              
1459             \=head1 NAME
1460              
1461             $module - The great new $module!
1462              
1463             \=head1 VERSION
1464              
1465             Version 0.01
1466              
1467             \=cut
1468              
1469             our \$VERSION = '0.01';
1470             HERE
1471 516         1364 return $content;
1472             }
1473              
1474             sub _module_bugs {
1475 516     516   798 my $self = shift;
1476 516         849 my $module = shift;
1477 516         808 my $rtname = shift;
1478              
1479 516         1491 my $bug_email = "bug-\L$self->{distro}\E at rt.cpan.org";
1480 516         868 my $bug_link =
1481             "https://rt.cpan.org/NoAuth/ReportBug.html?Queue=$self->{distro}";
1482              
1483 516         1339 my $content = <<"HERE";
1484             \=head1 BUGS
1485              
1486             Please report any bugs or feature requests to C<$bug_email>, or through
1487             the web interface at L<$bug_link>. I will be notified, and then you'll
1488             automatically be notified of progress on your bug as I make changes.
1489              
1490             HERE
1491              
1492 516         1283 return $content;
1493             }
1494              
1495             sub _module_support {
1496 516     516   828 my $self = shift;
1497 516         765 my $module = shift;
1498 516         871 my $rtname = shift;
1499              
1500 516         945 my $content = qq[
1501             \=head1 SUPPORT
1502              
1503             You can find documentation for this module with the perldoc command.
1504              
1505             perldoc $module
1506             ];
1507 516         1203 my @reference_links = _reference_links();
1508              
1509 516 50       1551 return undef unless @reference_links;
1510 516         933 $content .= qq[
1511              
1512             You can also look for information at:
1513              
1514             \=over 4
1515             ];
1516              
1517 516         1169 foreach my $ref (@reference_links) {
1518 1548 100 66     4882 next if $ref->{option} && !$self->{$ref->{option}};
1519              
1520 1032         1413 my $title;
1521 1032 50       3551 my $link = sprintf($ref->{link}, $ref->{option} ? $self->{$ref->{option}} : (), $self->{distro});
1522              
1523 1032 100       2322 $title = "$ref->{nickname}: " if exists $ref->{nickname};
1524 1032         2059 $title .= $ref->{title};
1525 1032         2183 $content .= qq[
1526             \=item * $title
1527              
1528             L<$link>
1529             ];
1530             }
1531 516         823 $content .= qq[
1532             \=back
1533             ];
1534 516         2894 return $content;
1535             }
1536              
1537             sub _module_license {
1538 516     516   744 my $self = shift;
1539              
1540 516         746 my $module = shift;
1541 516         675 my $rtname = shift;
1542              
1543 516         1344 my $license_blurb = $self->_license_blurb();
1544 516         1510 my $content = qq[
1545             \=head1 LICENSE AND COPYRIGHT
1546              
1547             $license_blurb
1548             ];
1549              
1550 516         1468 return $content;
1551             }
1552              
1553             sub module_guts {
1554 516     516 1 825 my $self = shift;
1555 516         761 my $module = shift;
1556 516         814 my $rtname = shift;
1557              
1558             # Sub-templates
1559 516         1255 my $header = $self->_module_header($module, $rtname);
1560 516         1526 my $bugs = $self->_module_bugs($module, $rtname);
1561 516         1303 my $support = $self->_module_support($module, $rtname);
1562 516         1452 my $license = $self->_module_license($module, $rtname);
1563 516         960 my $author_string = join ',', @{$self->{author}};
  516         1934  
1564            
1565 516         4497 my $content = <<"HERE";
1566             $header
1567              
1568             \=head1 SYNOPSIS
1569              
1570             Quick summary of what the module does.
1571              
1572             Perhaps a little code snippet.
1573              
1574             use $module;
1575              
1576             my \$foo = $module->new();
1577             ...
1578              
1579             \=head1 EXPORT
1580              
1581             A list of functions that can be exported. You can delete this section
1582             if you don't export anything, such as for a purely object-oriented module.
1583              
1584             \=head1 SUBROUTINES/METHODS
1585              
1586             \=head2 function1
1587              
1588             \=cut
1589              
1590             sub function1 {
1591             }
1592              
1593             \=head2 function2
1594              
1595             \=cut
1596              
1597             sub function2 {
1598             }
1599              
1600             \=head1 AUTHOR
1601              
1602             $author_string
1603              
1604             $bugs
1605              
1606             $support
1607              
1608             \=head1 ACKNOWLEDGEMENTS
1609              
1610             $license
1611              
1612             \=cut
1613              
1614             1; # End of $module
1615             HERE
1616 516         2305 return $content;
1617             }
1618              
1619             1;
1620              
1621             # vi:et:sw=4 ts=4