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   11042140 use Modern::Perl '2010'; ## no critic (Modules::ProhibitUseQuotedVersion)
  3         10  
  3         29  
6              
7             our $VERSION = '1.009'; # VERSION
8 3     3   602 use utf8;
  3         8  
  3         26  
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   118 use Moose;
  3         6  
  3         49  
36 3     3   20879 use MooseX::Types::Moose qw(ArrayRef Bool Maybe Str);
  3         7  
  3         42  
37 3     3   17610 use MooseX::AttributeShortcuts;
  3         903836  
  3         16  
38 3     3   158433 use Dist::Zilla::File::InMemory;
  3         78798  
  3         108  
39 3     3   2362 use List::MoreUtils 'part';
  3         36918  
  3         38  
40 3     3   4099 use Path::Class;
  3         31599  
  3         217  
41 3     3   27 use namespace::autoclean;
  3         8  
  3         36  
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 662 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 252840 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   13 my @requires = part { file($_)->is_absolute() } @{ $self->_requires };
  3         253  
  2         80  
103 2         224 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       90 $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         4276 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 52164 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   1242 no Moose;
  3         47  
  3         34  
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 bugtracker
165             rt cpants kwalitee diff irc mailto metadata placeholders metacpan
166              
167             =head1 NAME
168              
169             Dist::Zilla::Plugin::RequiresExternal - make dists require external commands
170              
171             =head1 VERSION
172              
173             version 1.009
174              
175             =for test_synopsis BEGIN { die "SKIP: this is ini, not perl\n" }
176              
177             =head1 SYNOPSIS
178              
179             In your F<dist.ini>:
180              
181             [RequiresExternal]
182             requires = /path/to/some/executable
183             requires = executable_in_path
184              
185             =head1 DESCRIPTION
186              
187             This L<Dist::Zilla|Dist::Zilla> plugin creates a test
188             in your distribution to check for the existence of executable commands
189             you require.
190              
191             =head1 ATTRIBUTES
192              
193             =head2 requires
194              
195             Each C<requires> attribute should be either an absolute path to an
196             executable or the name of a command in the user's C<PATH> environment.
197             Multiple C<requires> lines are allowed.
198              
199             Example from a F<dist.ini> file:
200              
201             [RequiresExternal]
202             requires = sqlplus
203             requires = /usr/bin/java
204              
205             This will require the program C<sqlplus> to be available somewhere in
206             the user's C<PATH> and the program C<java> specifically in F</usr/bin>.
207              
208             =head2 fatal
209              
210             Boolean value to determine if a failed test will immediately stop
211             testing. It also causes the test name to change to
212             F<t/000-requires_external.t> so that it runs earlier.
213             Defaults to false.
214              
215             =head1 METHODS
216              
217             =head2 gather_files
218              
219             Adds a F<t/requires_external.t> test script to your distribution that
220             checks if each L</requires> item is executable.
221              
222             =head2 metadata
223              
224             Using this plugin will add L<Test::Most|Test::Most>
225             and L<Env::Path|Env::Path> to your distribution's
226             testing prerequisites since the generated script uses those modules.
227              
228             =head1 SEE ALSO
229              
230             This module was indirectly inspired by
231             L<Module::Install::External's requires_external_bin|Module::Install::External/requires_external_bin>
232             command.
233              
234             =for Pod::Coverage mvp_multivalue_args
235              
236             =head1 SUPPORT
237              
238             =head2 Perldoc
239              
240             You can find documentation for this module with the perldoc command.
241              
242             perldoc Dist::Zilla::Plugin::RequiresExternal
243              
244             =head2 Websites
245              
246             The following websites have more information about this module, and may be of help to you. As always,
247             in addition to those websites please use your favorite search engine to discover more resources.
248              
249             =over 4
250              
251             =item *
252              
253             CPANTS
254              
255             The CPANTS is a website that analyzes the Kwalitee ( code metrics ) of a distribution.
256              
257             L<http://cpants.cpanauthors.org/dist/Dist-Zilla-Plugin-RequiresExternal>
258              
259             =item *
260              
261             CPAN Testers
262              
263             The CPAN Testers is a network of smoke testers who run automated tests on uploaded CPAN distributions.
264              
265             L<http://www.cpantesters.org/distro/D/Dist-Zilla-Plugin-RequiresExternal>
266              
267             =item *
268              
269             CPAN Testers Matrix
270              
271             The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms.
272              
273             L<http://matrix.cpantesters.org/?dist=Dist-Zilla-Plugin-RequiresExternal>
274              
275             =item *
276              
277             CPAN Testers Dependencies
278              
279             The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution.
280              
281             L<http://deps.cpantesters.org/?module=Dist::Zilla::Plugin::RequiresExternal>
282              
283             =back
284              
285             =head2 Bugs / Feature Requests
286              
287             Please report any bugs or feature requests through the web
288             interface at L<https://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal/issues>. You will be automatically notified of any
289             progress on the request by the system.
290              
291             =head2 Source Code
292              
293             The code is open to the world, and available for you to hack on. Please feel free to browse it and play
294             with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
295             from your repository :)
296              
297             L<https://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal>
298              
299             git clone git://github.com/mjgardner/Dist-Zilla-Plugin-RequiresExternal.git
300              
301             =head1 AUTHORS
302              
303             =over 4
304              
305             =item *
306              
307             Mark Gardner <mjgardner@cpan.org>
308              
309             =item *
310              
311             Joenio Costa <joenio@joenio.me>
312              
313             =back
314              
315             =head1 COPYRIGHT AND LICENSE
316              
317             This software is copyright (c) 2020 by GSI Commerce and Joenio Costa.
318              
319             This is free software; you can redistribute it and/or modify it under
320             the same terms as the Perl 5 programming language system itself.
321              
322             =cut