File Coverage

blib/lib/Dist/Zilla/Plugin/Test/PodSpelling.pm
Criterion Covered Total %
statement 52 52 100.0
branch 8 10 80.0
condition 1 3 33.3
subroutine 10 10 100.0
pod 1 6 16.6
total 72 81 88.8


line stmt bran cond sub pod time code
1 7     7   10831819 use strict;
  7         9  
  7         192  
2 7     7   25 use warnings;
  7         9  
  7         322  
3             package Dist::Zilla::Plugin::Test::PodSpelling; # git description: v2.007002-6-g4ddf499
4             # vim: set ts=8 sts=4 sw=4 tw=115 et :
5             # ABSTRACT: Author tests for POD spelling
6             # KEYWORDS: plugin test spelling words stopwords typos errors documentation
7              
8             our $VERSION = '2.007003';
9              
10 7     7   31 use Moose;
  7         7  
  7         46  
11             extends 'Dist::Zilla::Plugin::InlineFiles';
12             with (
13             'Dist::Zilla::Role::FileMunger',
14             'Dist::Zilla::Role::TextTemplate',
15             'Dist::Zilla::Role::FileFinderUser' => {
16             default_finders => [ ':InstallModules', ':ExecFiles' ],
17             },
18             'Dist::Zilla::Role::PrereqSource',
19             );
20              
21             sub mvp_multivalue_args { return ( qw( stopwords directories ) ) }
22              
23             sub mvp_aliases { +{
24 11     11 0 1504 directory => 'directories',
25             stopword => 'stopwords',
26             } }
27              
28             has wordlist => (
29             is => 'ro',
30             isa => 'Str',
31             default => 'Pod::Wordlist',
32             );
33              
34             has spell_cmd => (
35             is => 'ro',
36             isa => 'Str',
37             default => '',
38             );
39              
40             has stopwords => (
41             is => 'ro',
42             isa => 'ArrayRef[Str]',
43             traits => [ 'Array' ],
44             default => sub { [] },
45             handles => {
46             push_stopwords => 'push',
47             uniq_stopwords => 'uniq',
48             no_stopwords => 'is_empty',
49             }
50             );
51              
52             has directories => (
53             isa => 'ArrayRef[Str]',
54             traits => [ 'Array' ],
55             is => 'ro',
56             default => sub { [ qw(bin lib) ] },
57             handles => {
58             no_directories => 'is_empty',
59             print_directories => [ join => ' ' ],
60             }
61             );
62              
63             has _files => (
64             is => 'rw',
65             isa => 'ArrayRef[Dist::Zilla::Role::File]',
66             );
67              
68             around dump_config => sub
69             {
70             my ($orig, $self) = @_;
71             my $config = $self->$orig;
72              
73             $config->{+__PACKAGE__} = {
74             blessed($self) ne __PACKAGE__ ? ( version => $VERSION ) : (),
75             wordlist => $self->wordlist,
76             spell_cmd => $self->spell_cmd,
77             directories => [ sort @{ $self->directories } ],
78             # TODO: should only include manually-configured words
79             stopwords => [ sort @{ $self->stopwords } ],
80             };
81              
82             return $config;
83             };
84              
85             sub gather_files {
86 11     11 0 335093 my ($self) = @_;
87              
88 11         113 my $data = $self->merged_section_data;
89 11 50 33     1477 return unless $data and %$data;
90              
91 11         18 my @files;
92 11         29 for my $name (keys %$data) {
93             my $file = Dist::Zilla::File::InMemory->new({
94             name => $name,
95 11         19 content => ${ $data->{$name} },
  11         354  
96             });
97 11         2616 $self->add_file($file);
98 11         2898 push @files, $file;
99             }
100              
101 11         343 $self->_files(\@files);
102 11         32 return;
103             }
104              
105             sub add_stopword {
106 100     100 1 112 my ( $self, $data ) = @_;
107              
108 100         244 $self->log_debug( 'attempting stopwords extraction from: ' . $data );
109             # words must be greater than 2 characters
110 100         4967 my ( $word ) = $data =~ /(\p{Word}{2,})/xms;
111              
112             # log won't like an undef
113 100 100       175 return unless $word;
114              
115 90         195 $self->log_debug( 'add stopword: ' . $word );
116              
117 90         6420 $self->push_stopwords( $word );
118 90         124 return;
119             }
120              
121             sub munge_files {
122 11     11 0 15610 my ($self) = @_;
123              
124 11         21 $self->munge_file($_) foreach @{ $self->_files };
  11         394  
125 11         29 return;
126             }
127              
128             sub munge_file {
129 11     11 0 19 my ($self, $file) = @_;
130              
131 11 100       355 my $set_spell_cmd = $self->spell_cmd
132             ? sprintf("set_spell_cmd('%s');", $self->spell_cmd)
133             : undef;
134              
135             # TODO - move this into an attribute builder
136 11         19 foreach my $holder ( split( /\s/xms, join( ' ',
137 11         249 @{ $self->zilla->authors },
138             $self->zilla->copyright_holder,
139 11 100       23908 @{ $self->zilla->distmeta->{x_contributors} || [] },
140             ))
141             ) {
142 60         139394 $self->add_stopword( $holder );
143             }
144              
145             # TODO: we should use the filefinder for the names of the files to check in, rather than hardcoding that list!
146 11         49 foreach my $file ( @{ $self->found_files } ) {
  11         51  
147             # many of my stopwords are part of a filename
148 17         13722 $self->log_debug( 'splitting filenames for more words' );
149              
150 17         714 foreach my $name ( split( '/', $file->name ) ) {
151 40         618 $self->add_stopword( $name );
152             }
153             }
154              
155 11 50       447 my $stopwords = $self->no_stopwords
156             ? undef
157             : join("\n", '__DATA__', sort $self->uniq_stopwords);
158              
159 11         67 $file->content(
160             $self->fill_in_string(
161             $file->content,
162             {
163             name => __PACKAGE__,
164             version => __PACKAGE__->VERSION,
165             wordlist => \$self->wordlist,
166             set_spell_cmd => \$set_spell_cmd,
167             stopwords => \$stopwords,
168             directories => \$self->print_directories,
169             }
170             ),
171             );
172              
173 11         13323 return;
174             }
175              
176             sub register_prereqs {
177 11     11 0 5294 my $self = shift;
178 11         289 $self->zilla->register_prereqs(
179             {
180             type => 'requires',
181             phase => 'develop',
182             },
183             'Test::Spelling' => '0.12',
184             );
185 11         4482 return;
186             }
187              
188             __PACKAGE__->meta->make_immutable;
189 7     7   36088 no Moose;
  7         9  
  7         37  
190             1;
191              
192             #pod =pod
193             #pod
194             #pod =for Pod::Coverage gather_files mvp_multivalue_args mvp_aliases munge_files munge_file register_prereqs
195             #pod
196             #pod =head1 SYNOPSIS
197             #pod
198             #pod In C<dist.ini>:
199             #pod
200             #pod [Test::PodSpelling]
201             #pod
202             #pod or:
203             #pod
204             #pod [Test::PodSpelling]
205             #pod directory = docs
206             #pod wordlist = Pod::Wordlist
207             #pod spell_cmd = aspell list
208             #pod stopword = CPAN
209             #pod stopword = github
210             #pod stopword = stopwords
211             #pod stopword = wordlist
212             #pod
213             #pod If you're using C<[ExtraTests]> it must come after C<[Test::PodSpelling]>,
214             #pod it's worth noting that this ships in the C<[@Basic]> bundle so you may have to
215             #pod remove it from that first.
216             #pod
217             #pod =head1 DESCRIPTION
218             #pod
219             #pod This is a plugin that runs at the L<gather files|Dist::Zilla::Role::FileGatherer> stage,
220             #pod providing the file:
221             #pod
222             #pod xt/author/pod-spell.t - a standard Test::Spelling test
223             #pod
224             #pod L<Test::Spelling> will be added as a develop prerequisite.
225             #pod
226             #pod =method add_stopword
227             #pod
228             #pod Called to add stopwords to the stopwords array. It is used to determine if
229             #pod automagically detected words are valid and print out debug logging for the
230             #pod process.
231             #pod
232             #pod =attr directories (or directory)
233             #pod
234             #pod Additional directories you wish to search for POD spell checking purposes.
235             #pod C<bin> and C<lib> are set by default.
236             #pod
237             #pod =attr wordlist
238             #pod
239             #pod The module name of a word list you wish to use that works with
240             #pod L<Test::Spelling>.
241             #pod
242             #pod Defaults to L<Pod::Wordlist>.
243             #pod
244             #pod =attr spell_cmd
245             #pod
246             #pod If C<spell_cmd> is set then C<set_spell_cmd( your_spell_command );> is
247             #pod added to the test file to allow for custom spell check programs.
248             #pod
249             #pod Defaults to nothing.
250             #pod
251             #pod =attr stopwords
252             #pod
253             #pod If stopwords is set then C<add_stopwords( E<lt>DATAE<gt> )> is added
254             #pod to the test file and the words are added after the C<__DATA__>
255             #pod section.
256             #pod
257             #pod C<stopword> or C<stopwords> can appear multiple times, one word per line.
258             #pod
259             #pod Normally no stopwords are added by default, but author names appearing in
260             #pod C<dist.ini> are automatically added as stopwords so you don't have to add them
261             #pod manually just because they might appear in the C<AUTHORS> section of the
262             #pod generated POD document. The same goes for contributors listed under the
263             #pod 'x_contributors' field on your distributions META file.
264             #pod
265             #pod =cut
266              
267             =pod
268              
269             =encoding UTF-8
270              
271             =head1 NAME
272              
273             Dist::Zilla::Plugin::Test::PodSpelling - Author tests for POD spelling
274              
275             =head1 VERSION
276              
277             version 2.007003
278              
279             =head1 SYNOPSIS
280              
281             In C<dist.ini>:
282              
283             [Test::PodSpelling]
284              
285             or:
286              
287             [Test::PodSpelling]
288             directory = docs
289             wordlist = Pod::Wordlist
290             spell_cmd = aspell list
291             stopword = CPAN
292             stopword = github
293             stopword = stopwords
294             stopword = wordlist
295              
296             If you're using C<[ExtraTests]> it must come after C<[Test::PodSpelling]>,
297             it's worth noting that this ships in the C<[@Basic]> bundle so you may have to
298             remove it from that first.
299              
300             =head1 DESCRIPTION
301              
302             This is a plugin that runs at the L<gather files|Dist::Zilla::Role::FileGatherer> stage,
303             providing the file:
304              
305             xt/author/pod-spell.t - a standard Test::Spelling test
306              
307             L<Test::Spelling> will be added as a develop prerequisite.
308              
309             =head1 ATTRIBUTES
310              
311             =head2 directories (or directory)
312              
313             Additional directories you wish to search for POD spell checking purposes.
314             C<bin> and C<lib> are set by default.
315              
316             =head2 wordlist
317              
318             The module name of a word list you wish to use that works with
319             L<Test::Spelling>.
320              
321             Defaults to L<Pod::Wordlist>.
322              
323             =head2 spell_cmd
324              
325             If C<spell_cmd> is set then C<set_spell_cmd( your_spell_command );> is
326             added to the test file to allow for custom spell check programs.
327              
328             Defaults to nothing.
329              
330             =head2 stopwords
331              
332             If stopwords is set then C<add_stopwords( E<lt>DATAE<gt> )> is added
333             to the test file and the words are added after the C<__DATA__>
334             section.
335              
336             C<stopword> or C<stopwords> can appear multiple times, one word per line.
337              
338             Normally no stopwords are added by default, but author names appearing in
339             C<dist.ini> are automatically added as stopwords so you don't have to add them
340             manually just because they might appear in the C<AUTHORS> section of the
341             generated POD document. The same goes for contributors listed under the
342             'x_contributors' field on your distributions META file.
343              
344             =head1 METHODS
345              
346             =head2 add_stopword
347              
348             Called to add stopwords to the stopwords array. It is used to determine if
349             automagically detected words are valid and print out debug logging for the
350             process.
351              
352             =for Pod::Coverage gather_files mvp_multivalue_args mvp_aliases munge_files munge_file register_prereqs
353              
354             =head1 SUPPORT
355              
356             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-Test-PodSpelling>
357             (or L<bug-Dist-Zilla-Plugin-Test-PodSpelling@rt.cpan.org|mailto:bug-Dist-Zilla-Plugin-Test-PodSpelling@rt.cpan.org>).
358              
359             There is also a mailing list available for users of this distribution, at
360             L<http://dzil.org/#mailing-list>.
361              
362             There is also an irc channel available for users of this distribution, at
363             L<C<#distzilla> on C<irc.perl.org>|irc://irc.perl.org/#distzilla>.
364              
365             I am also usually active on irc, as 'ether' at C<irc.perl.org>.
366              
367             =head1 AUTHORS
368              
369             =over 4
370              
371             =item *
372              
373             Caleb Cushing <xenoterracide@gmail.com>
374              
375             =item *
376              
377             Marcel Gruenauer <hanekomu@gmail.com>
378              
379             =back
380              
381             =head1 CONTRIBUTORS
382              
383             =for stopwords Karen Etheridge Randy Stauner Graham Knop David Golden Harley Pig Alexandr Ciornii Breno G. de Oliveira
384              
385             =over 4
386              
387             =item *
388              
389             Karen Etheridge <ether@cpan.org>
390              
391             =item *
392              
393             Randy Stauner <rwstauner@cpan.org>
394              
395             =item *
396              
397             Graham Knop <haarg@haarg.org>
398              
399             =item *
400              
401             David Golden <dagolden@cpan.org>
402              
403             =item *
404              
405             Harley Pig <harleypig@gmail.com>
406              
407             =item *
408              
409             Alexandr Ciornii <alexchorny@gmail.com>
410              
411             =item *
412              
413             Breno G. de Oliveira <garu@cpan.org>
414              
415             =back
416              
417             =head1 COPYRIGHT AND LICENCE
418              
419             This software is Copyright (c) 2010 by Karen Etheridge.
420              
421             This is free software, licensed under:
422              
423             The Artistic License 2.0 (GPL Compatible)
424              
425             =cut
426              
427             __DATA__
428             ___[ xt/author/pod-spell.t ]___
429             use strict;
430             use warnings;
431             use Test::More;
432              
433             # generated by {{ $name }} {{ $version }}
434             use Test::Spelling 0.12;
435             use {{ $wordlist }};
436              
437             {{ $set_spell_cmd }}
438             {{ $stopwords ? 'add_stopwords(<DATA>);' : undef }}
439             all_pod_files_spelling_ok( qw( {{ $directories }} ) );
440             {{ $stopwords }}