File Coverage

blib/lib/Dist/Zilla/Plugin/AlienBase/Doc.pm
Criterion Covered Total %
statement 66 69 95.6
branch 16 24 66.6
condition n/a
subroutine 10 10 100.0
pod 0 5 0.0
total 92 108 85.1


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::AlienBase::Doc 0.32 {
2              
3 2     2   368403 use 5.014;
  2         16  
4 2     2   606 use Moose;
  2         460611  
  2         16  
5 2     2   14659 use Carp ();
  2         6  
  2         133  
6              
7             # ABSTRACT: Generate boilerplate documentation for Alien::Base subclass
8              
9              
10             with 'Dist::Zilla::Role::FileMunger';
11             with 'Dist::Zilla::Role::FileFinderUser' => { default_finders => [ ':InstallModules', ':ExecFiles' ] };
12             with 'Dist::Zilla::Role::PPI';
13             with 'Dist::Zilla::Role::TextTemplate';
14              
15 2     2   1229 use Sub::Exporter::ForMethods 'method_installer';
  2         2090  
  2         10  
16             use Data::Section 0.004 # fixed header_re
17 2     2   1560 { installer => method_installer }, '-setup';
  2         4094  
  2         14  
18              
19              
20             has class_name => (
21             is => 'ro',
22             isa => 'Str',
23             lazy => 1,
24             default => sub {
25             my($self) = @_;
26             my $name = $self->zilla->name;
27             $name =~ s{-}{::};
28             $name;
29             },
30             );
31              
32              
33             has min_version => (
34             is => 'ro',
35             isa => 'Str',
36             default => '0',
37             );
38              
39              
40             has type => (
41             is => 'ro',
42             isa => 'ArrayRef[Str]',
43             default => sub { [ 'library' ] },
44             );
45              
46              
47             has name => (
48             is => 'ro',
49             isa => 'Str',
50             required => 1,
51             );
52              
53              
54             has see_also => (
55             is => 'ro',
56             isa => 'ArrayRef[Str]',
57             default => sub { [ 'Alien', 'Alien::Base', 'Alien::Build::Manual::AlienUser' ] },
58             );
59              
60             around mvp_multivalue_args => sub {
61             my($orig, $self) = @_;
62             ($self->$orig, 'type', 'see_also');
63             };
64              
65             sub render_synopsis
66             {
67 4     4 0 62255 my($self) = @_;
68              
69 4         11 my $str = "\n=head1 SYNOPSIS";
70              
71 4         6 foreach my $type (@{ $self->type })
  4         154  
72             {
73 6         2451 my $template;
74              
75 6 100       54 if($type eq 'library')
    100          
    50          
76             {
77 2         14 $template = $self->section_data('__SYNOPSIS_LIBRARY__')
78             }
79             elsif($type eq 'tool')
80             {
81 2         54 $template = $self->section_data('__SYNOPSIS_TOOL__')
82             }
83             elsif($type eq 'ffi')
84             {
85 2         9 $template = $self->section_data('__SYNOPSIS_FFI__')
86             }
87             else
88             {
89 0         0 Carp::croak("unknown type: $type");
90             }
91              
92 6         3437 $template = $$template;
93 6         228 $template =~ s{\s*$}{};
94              
95 6         19 $str .= "\n\n";
96 6 50       244 $str .= $self->fill_in_string($template, {
97             class => $self->class_name,
98             name => $self->name,
99             version => $self->min_version,
100 0         0 optversion => $self->min_version ? " @{[ $self->min_version ]}" : '',
101             });
102             }
103              
104 4         4820 $str .= "\n\n=cut\n\n";
105              
106 4         23 $str;
107             }
108              
109             sub render_description
110             {
111 2     2 0 2092 my($self) = @_;
112              
113 2         7 my $template = $self->section_data('__DESCRIPTION__');
114              
115 2         99 $template = $$template;
116 2         100 $template =~ s{\s*$}{};
117              
118 2         6 my $str = "\n";
119              
120 2 50       85 $str .= $self->fill_in_string($template, {
121             class => $self->class_name,
122             name => $self->name,
123             version => $self->min_version,
124 0         0 optversion => $self->min_version ? " @{[ $self->min_version ]}" : '',
125             });
126              
127 2         1808 $str .= "\n\n";
128              
129 2         12 $str;
130             }
131              
132             sub render_see_also
133             {
134 2     2 0 13 my($self) = @_;
135              
136 2         5 my $str = "\n=head1 SEE ALSO\n\n";
137 2         5 $str .= join ', ', map { "L<$_>" } @{ $self->see_also };
  5         21  
  2         74  
138 2         9 $str .= "\n\n=cut\n\n";
139              
140 2         8 $str;
141             }
142              
143             sub munge_files
144             {
145 1     1 0 12567 my($self) = @_;
146 1         3 $self->munge_file($_) for @{ $self->found_files };
  1         7  
147 1         271 return;
148             }
149              
150             sub munge_file
151             {
152 1     1 0 1677 my($self, $file) = @_;
153              
154 1         15 my $doc = $self->ppi_document_for_file($file);
155              
156 1 50       122490 return unless defined $doc;
157              
158 1         8 my $comments = $doc->find('PPI::Token::Comment');
159 1         1122 my $modified = 0;
160              
161 1 50       3 foreach my $comment (@{ $comments || [] })
  1         6  
162             {
163 3 50       13 if($comment =~ /^\s*##?\s*ALIEN (SYNOPSIS|DESCRIPTION|SEE ALSO)\s*$/)
164             {
165 3         54 my $type = $1;
166 3 100       16 if($type eq 'SYNOPSIS')
    100          
    50          
167             {
168 1         7 $comment->set_content($self->render_synopsis);
169             }
170             elsif($type eq 'DESCRIPTION')
171             {
172 1         5 $comment->set_content($self->render_description);
173             }
174             elsif($type eq 'SEE ALSO')
175             {
176 1         7 $comment->set_content($self->render_see_also);
177             }
178 3         14 $modified = 1;
179             }
180             }
181              
182 1 50       5 if($modified)
183             {
184 1         10 $self->save_ppi_document_to_file( $doc, $file);
185 1         1817 $self->log_debug([ 'adding ALIEN documentation to %s', $file->name ]);
186             }
187              
188 1         180 return;
189             }
190              
191             __PACKAGE__->meta->make_immutable;
192              
193             }
194              
195             package Dist::Zilla::Plugin::AlienBase::Doc;
196              
197             1;
198              
199             =pod
200              
201             =encoding UTF-8
202              
203             =head1 NAME
204              
205             Dist::Zilla::Plugin::AlienBase::Doc - Generate boilerplate documentation for Alien::Base subclass
206              
207             =head1 VERSION
208              
209             version 0.32
210              
211             =head1 SYNOPSIS
212              
213             In your dist.ini:
214              
215             [AlienBase::Doc]
216             name = libfoo
217              
218             In your Alien/Foo.pm:
219              
220             package Alien::Foo;
221            
222             use strict;
223             use warnings;
224             use base qw( Alien::Base );
225            
226             # ALIEN SYNOPSIS
227             # ALIEN DESCRIPTION
228             # ALIEN SEE ALSO
229            
230             1;
231              
232             =head1 DESCRIPTION
233              
234             This plugin generates some boiler plat documentation for your
235             L<Alien::Base> based L<Alien> module. It will find the special codes
236             C<ALIEN SYNOPSIS>, C<ALIEN DESCRIPTION>, and C<ALIEN SEE ALSO> and
237             replace them with the appropriate boilerplate POD documentation for how
238             to use the module. The generated synopsis and see also sections are
239             probably good enough as is. The description is a little more basic, and
240             you may want to write a more detailed description yourself. It is, at
241             least, better than nothing though!
242              
243             =head1 ATTRIBUTES
244              
245             =head2 class_name
246              
247             The name of the L<Alien::Base> subclass. The default is based on the
248             distribution's main module.
249              
250             =head2 min_version
251              
252             The minimum version to suggest using as a prereq.
253              
254             =head2 type
255              
256             Types of the L<Alien>. This can be specified multiple times. Valid types:
257              
258             =over 4
259              
260             =item library
261              
262             =item tool
263              
264             =item ffi
265              
266             =back
267              
268             =head2 name
269              
270             [required]
271              
272             The name of the alienized project. For example C<libarchive> or C<infozip>.
273              
274             =head2 see_also
275              
276             List of modules to refer to in the C<SEE ALSO> section. By default this is
277              
278             =over 4
279              
280             =item L<Alien>
281              
282             =item L<Alien::Base>
283              
284             =item L<Alien::Build::Manual::AlienUser>
285              
286             =back
287              
288             =head1 AUTHOR
289              
290             Graham Ollis <plicease@cpan.org>
291              
292             =head1 COPYRIGHT AND LICENSE
293              
294             This software is copyright (c) 2017 by Graham Ollis.
295              
296             This is free software; you can redistribute it and/or modify it under
297             the same terms as the Perl 5 programming language system itself.
298              
299             =cut
300              
301             __DATA__
302              
303             __[ __SYNOPSIS_LIBRARY__ ]__
304             In your Makefile.PL:
305              
306             use ExtUtils::MakeMaker;
307             use Alien::Base::Wrapper ();
308              
309             WriteMakefile(
310             Alien::Base::Wrapper->new('{{ $class }}')->mm_args2(
311             # MakeMaker args
312             NAME => 'My::XS',
313             ...
314             ),
315             );
316              
317             In your Build.PL:
318              
319             use Module::Build;
320             use Alien::Base::Wrapper qw( {{ $class }} !export );
321              
322             my $builder = Module::Build->new(
323             ...
324             configure_requires => {
325             '{{ $class }}' => '{{ $version }}',
326             ...
327             },
328             Alien::Base::Wrapper->mb_args,
329             ...
330             );
331              
332             $build->create_build_script;
333              
334             __[ __SYNOPSIS_FFI__ ]__
335             In your L<FFI::Platypus> script or module:
336              
337             use FFI::Platypus;
338             use {{ $class }}{{ $optversion }};
339              
340             my $ffi = FFI::Platypus->new(
341             lib => [ {{ $class }}->dynamic_libs ],
342             );
343              
344             __[ __SYNOPSIS_TOOL__ ]__
345             In your script or module:
346              
347             use {{ $class }}{{ $optversion }};
348             use Env qw( @PATH );
349              
350             unshift @PATH, {{ $class }}->bin_dir;
351              
352             __[ __DESCRIPTION__ ]__
353             =head1 DESCRIPTION
354              
355             This distribution provides {{ $name }} so that it can be used by other
356             Perl distributions that are on CPAN. It does this by first trying to
357             detect an existing install of {{ $name }} on your system. If found it
358             will use that. If it cannot be found, the source code will be downloaded
359             from the internet and it will be installed in a private share location
360             for the use of other modules.
361              
362             =cut