File Coverage

blib/lib/Dist/Zilla/Plugin/RequiresExternal.pm
Criterion Covered Total %
statement 39 39 100.0
branch 2 2 100.0
condition n/a
subroutine 14 14 100.0
pod 2 3 66.6
total 57 58 98.2


line stmt bran cond sub pod time code
1             package Dist::Zilla::Plugin::RequiresExternal;
2              
3             # ABSTRACT: make dists require external commands
4              
5 3     3   13279548 use Modern::Perl '2010'; ## no critic (Modules::ProhibitUseQuotedVersion)
  3         8  
  3         26  
6              
7             our $VERSION = '1.008'; # VERSION
8 3     3   564 use utf8;
  3         7  
  3         27  
9              
10             #pod =for test_synopsis
11             #pod BEGIN { die "SKIP: this is ini, not perl\n" }
12             #pod
13             #pod =head1 SYNOPSIS
14             #pod
15             #pod In your F<dist.ini>:
16             #pod
17             #pod [RequiresExternal]
18             #pod requires = /path/to/some/executable
19             #pod requires = executable_in_path
20             #pod
21             #pod =head1 DESCRIPTION
22             #pod
23             #pod This L<Dist::Zilla|Dist::Zilla> plugin creates a test
24             #pod in your distribution to check for the existence of executable commands
25             #pod you require.
26             #pod
27             #pod =head1 SEE ALSO
28             #pod
29             #pod This module was indirectly inspired by
30             #pod L<Module::Install::External's requires_external_bin|Module::Install::External/requires_external_bin>
31             #pod command.
32             #pod
33             #pod =cut
34              
35 3     3   124 use Moose;
  3         9  
  3         31  
36 3     3   24612 use MooseX::Types::Moose qw(ArrayRef Bool Maybe Str);
  3         10  
  3         35  
37 3     3   24125 use MooseX::AttributeShortcuts;
  3         771948  
  3         12  
38 3     3   184632 use Dist::Zilla::File::InMemory;
  3         87705  
  3         144  
39 3     3   1354 use List::MoreUtils 'part';
  3         22392  
  3         28  
40 3     3   2596 use Path::Class;
  3         26156  
  3         196  
41 3     3   28 use namespace::autoclean;
  3         8  
  3         31  
42             with qw(
43             Dist::Zilla::Role::Plugin
44             Dist::Zilla::Role::FileGatherer
45             Dist::Zilla::Role::MetaProvider
46             Dist::Zilla::Role::TextTemplate
47             );
48              
49             #pod =for Pod::Coverage mvp_multivalue_args
50             #pod
51             #pod =cut
52              
53 3     3 0 678 sub mvp_multivalue_args { return 'requires' }
54              
55             #pod =attr requires
56             #pod
57             #pod Each C<requires> attribute should be either an absolute path to an
58             #pod executable or the name of a command in the user's C<PATH> environment.
59             #pod Multiple C<requires> lines are allowed.
60             #pod
61             #pod Example from a F<dist.ini> file:
62             #pod
63             #pod [RequiresExternal]
64             #pod requires = sqlplus
65             #pod requires = /usr/bin/java
66             #pod
67             #pod This will require the program C<sqlplus> to be available somewhere in
68             #pod the user's C<PATH> and the program C<java> specifically in F</usr/bin>.
69             #pod
70             #pod =cut
71              
72             has _requires => (
73             is => 'lazy',
74             isa => Maybe [ ArrayRef [Str] ],
75             init_arg => 'requires',
76             default => sub { [] },
77             );
78              
79             #pod =attr fatal
80             #pod
81             #pod Boolean value to determine if a failed test will immediately stop
82             #pod testing. It also causes the test name to change to
83             #pod F<t/000-requires_external.t> so that it runs earlier.
84             #pod Defaults to false.
85             #pod
86             #pod =cut
87              
88             has fatal => ( is => 'ro', required => 1, isa => Maybe [Bool], default => 0 );
89              
90             #pod =method gather_files
91             #pod
92             #pod Adds a F<t/requires_external.t> test script to your distribution that
93             #pod checks if each L</requires> item is executable.
94             #pod
95             #pod =cut
96              
97             sub gather_files {
98 2     2 1 309557 my $self = shift;
99              
100             # @{$requires[0]} will contain any non-absolute paths to look for in $PATH
101             # @{$requires[1]} will contain any absolute paths
102 2     3   16 my @requires = part { file($_)->is_absolute() } @{ $self->_requires };
  3         334  
  2         111  
103 2         291 my $template = <<'END_TEMPLATE';
104             #!/usr/bin/env perl
105              
106             use Test::Most;
107             plan tests => {{
108             $OUT = 0;
109             $OUT += @{ $requires[0] } if defined $requires[0];
110             $OUT += @{ $requires[1] } if defined $requires[1];
111             }};
112             bail_on_fail if {{ $fatal }};
113             use Env::Path 0.18 'PATH';
114              
115             {{ "ok(scalar PATH->Whence(\$_), \"\$_ in PATH\") for qw(@{ $requires[0] });"
116             if defined $requires[0]; }}
117             {{ "ok(-x \$_, \"\$_ is executable\") for qw(@{ $requires[1] });"
118             if defined $requires[1]; }}
119             END_TEMPLATE
120              
121 2 100       118 $self->add_file(
122             Dist::Zilla::File::InMemory->new(
123             name => (
124             $self->fatal
125             ? 't/000-requires_external.t'
126             : 't/requires_external.t',
127             ),
128             content => $self->fill_in_string(
129             $template, { fatal => $self->fatal, requires => \@requires },
130             ),
131             ),
132             );
133 2         5883 return;
134             }
135              
136             #pod =method metadata
137             #pod
138             #pod Using this plugin will add L<Test::Most|Test::Most>
139             #pod and L<Env::Path|Env::Path> to your distribution's
140             #pod testing prerequisites since the generated script uses those modules.
141             #pod
142             #pod =cut
143              
144             sub metadata {
145             return {
146 2     2 1 63420 prereqs => {
147             test => {
148             requires => { 'Test::Most' => '0', 'Env::Path' => '0.18' },
149             },
150             },
151             };
152             }
153              
154             __PACKAGE__->meta->make_immutable();
155 3     3   1213 no Moose;
  3         9  
  3         26  
156             1;
157              
158             __END__
159              
160             =pod
161              
162             =encoding utf8
163              
164             =for :stopwords Mark Gardner Joenio Costa GSI Commerce and cpan testmatrix url annocpan
165             anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders
166             metacpan
167              
168             =head1 NAME
169              
170             Dist::Zilla::Plugin::RequiresExternal - make dists require external commands
171              
172             =head1 VERSION
173              
174             version 1.008
175              
176             =for test_synopsis BEGIN { die "SKIP: this is ini, not perl\n" }
177              
178             =head1 SYNOPSIS
179              
180             In your F<dist.ini>:
181              
182             [RequiresExternal]
183             requires = /path/to/some/executable
184             requires = executable_in_path
185              
186             =head1 DESCRIPTION
187              
188             This L<Dist::Zilla|Dist::Zilla> plugin creates a test
189             in your distribution to check for the existence of executable commands
190             you require.
191              
192             =head1 ATTRIBUTES
193              
194             =head2 requires
195              
196             Each C<requires> attribute should be either an absolute path to an
197             executable or the name of a command in the user's C<PATH> environment.
198             Multiple C<requires> lines are allowed.
199              
200             Example from a F<dist.ini> file:
201              
202             [RequiresExternal]
203             requires = sqlplus
204             requires = /usr/bin/java
205              
206             This will require the program C<sqlplus> to be available somewhere in
207             the user's C<PATH> and the program C<java> specifically in F</usr/bin>.
208              
209             =head2 fatal
210              
211             Boolean value to determine if a failed test will immediately stop
212             testing. It also causes the test name to change to
213             F<t/000-requires_external.t> so that it runs earlier.
214             Defaults to false.
215              
216             =head1 METHODS
217              
218             =head2 gather_files
219              
220             Adds a F<t/requires_external.t> test script to your distribution that
221             checks if each L</requires> item is executable.
222              
223             =head2 metadata
224              
225             Using this plugin will add L<Test::Most|Test::Most>
226             and L<Env::Path|Env::Path> to your distribution's
227             testing prerequisites since the generated script uses those modules.
228              
229             =head1 SEE ALSO
230              
231             This module was indirectly inspired by
232             L<Module::Install::External's requires_external_bin|Module::Install::External/requires_external_bin>
233             command.
234              
235             =for Pod::Coverage mvp_multivalue_args
236              
237             =head1 SUPPORT
238              
239             =head2 Perldoc
240              
241             You can find documentation for this module with the perldoc command.
242              
243             perldoc Dist::Zilla::Plugin::RequiresExternal
244              
245             =head2 Websites
246              
247             The following websites have more information about this module, and may be of help to you. As always,
248             in addition to those websites please use your favorite search engine to discover more resources.
249              
250             =over 4
251              
252             =item *
253              
254             Search CPAN
255              
256             The default CPAN search engine, useful to view POD in HTML format.
257              
258             L<http://search.cpan.org/dist/Dist-Zilla-Plugin-RequiresExternal>
259              
260             =item *
261              
262             AnnoCPAN
263              
264             The AnnoCPAN is a website that allows community annotations of Perl module documentation.
265              
266             L<http://annocpan.org/dist/Dist-Zilla-Plugin-RequiresExternal>
267              
268             =item *
269              
270             CPAN Ratings
271              
272             The CPAN Ratings is a website that allows community ratings and reviews of Perl modules.
273              
274             L<http://cpanratings.perl.org/d/Dist-Zilla-Plugin-RequiresExternal>
275              
276             =item *
277              
278             CPANTS
279              
280             The CPANTS is a website that analyzes the Kwalitee ( code metrics ) of a distribution.
281              
282             L<http://cpants.cpanauthors.org/dist/Dist-Zilla-Plugin-RequiresExternal>
283              
284             =item *
285              
286             CPAN Testers
287              
288             The CPAN Testers is a network of smokers who run automated tests on uploaded CPAN distributions.
289              
290             L<http://www.cpantesters.org/distro/D/Dist-Zilla-Plugin-RequiresExternal>
291              
292             =item *
293              
294             CPAN Testers Matrix
295              
296             The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms.
297              
298             L<http://matrix.cpantesters.org/?dist=Dist-Zilla-Plugin-RequiresExternal>
299              
300             =item *
301              
302             CPAN Testers Dependencies
303              
304             The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution.
305              
306             L<http://deps.cpantesters.org/?module=Dist::Zilla::Plugin::RequiresExternal>
307              
308             =back
309              
310             =head2 Bugs / Feature Requests
311              
312             Please report any bugs or feature requests through the web
313             interface at L<https://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal/issues>. You will be automatically notified of any
314             progress on the request by the system.
315              
316             =head2 Source Code
317              
318             The code is open to the world, and available for you to hack on. Please feel free to browse it and play
319             with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
320             from your repository :)
321              
322             L<https://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal>
323              
324             git clone git://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal.git
325              
326             =head1 AUTHORS
327              
328             =over 4
329              
330             =item *
331              
332             Mark Gardner <mjgardner@cpan.org>
333              
334             =item *
335              
336             Joenio Costa <joenio@joenio.me>
337              
338             =back
339              
340             =head1 COPYRIGHT AND LICENSE
341              
342             This software is copyright (c) 2017 by GSI Commerce and Joenio Costa.
343              
344             This is free software; you can redistribute it and/or modify it under
345             the same terms as the Perl 5 programming language system itself.
346              
347             =cut