File Coverage

blib/lib/App/GitHooks/Plugin/PerlInterpreter.pm
Criterion Covered Total %
statement 38 38 100.0
branch 6 8 75.0
condition 1 3 33.3
subroutine 8 8 100.0
pod 3 3 100.0
total 56 60 93.3


line stmt bran cond sub pod time code
1             package App::GitHooks::Plugin::PerlInterpreter;
2              
3 17     17   3140900 use strict;
  17         33  
  17         464  
4 17     17   65 use warnings;
  17         26  
  17         464  
5              
6 17     17   62 use base 'App::GitHooks::Plugin';
  17         27  
  17         2703  
7              
8             # External dependencies.
9 17     17   9374 use autodie qw( open close );
  17         209570  
  17         89  
10              
11             # Internal dependencies.
12 17     17   8393 use App::GitHooks::Constants qw( :PLUGIN_RETURN_CODES );
  17         12549  
  17         9536  
13              
14              
15             =head1 NAME
16              
17             App::GitHooks::Plugin::PerlInterpreter - Enforce a specific Perl interpreter on the first line of Perl files.
18              
19              
20             =head1 DESCRIPTION
21              
22             This plugin allows you to enforce a specific Perl interpreter on the first line
23             of Perl files. This is particularly useful if you have a system Perl and a more
24             modern PerlBrew installation on your system, and you want to make sure that
25             other developers don't invoke the system Perl by mistake.
26              
27              
28             =head1 VERSION
29              
30             Version 1.2.0
31              
32             =cut
33              
34             our $VERSION = '1.2.0';
35              
36              
37             =head1 CONFIGURATION OPTIONS
38              
39             This plugin supports the following options in the C<[PerlInterpreter]>
40             section of your C<.githooksrc> file.
41              
42             [PerlInterpreter]
43             interpreter_regex = /^#!\/usr\/bin\/env perl$/
44             recommended_interpreter = #!/usr/bin/env perl
45              
46              
47             =head2 interpreter_regex
48              
49             A regular expression that, if matched, indicates a valid hashbang line for Perl
50             scripts.
51              
52             interpreter_regex = /^#!\/usr\/bin\/env perl$/
53              
54              
55             =head2 recommended_interpreter
56              
57             An optional recommendation that will be displayed to the user when the hashbang
58             line is not valid. This will help users fix incorrect hashbang lines.
59              
60             recommended_interpreter = #!/usr/bin/env perl
61              
62             When this option is specified, errors will then display:
63              
64             x The Perl interpreter line is correct
65             Invalid: #!perl
66             Recommended: #!/usr/bin/env perl
67              
68              
69             =head1 METHODS
70              
71             =head2 get_file_pattern()
72              
73             Return a pattern to filter the files this plugin should analyze.
74              
75             my $file_pattern = App::GitHooks::Plugin::PerlInterpreter->get_file_pattern(
76             app => $app,
77             );
78              
79             =cut
80              
81             sub get_file_pattern
82             {
83 15     15 1 913367 return qr/\.(?:pl|t|cgi)$/x;
84             }
85              
86              
87             =head2 get_file_check_description()
88              
89             Return a description of the check performed on files by the plugin and that
90             will be displayed to the user, if applicable, along with an indication of the
91             success or failure of the plugin.
92              
93             my $description = App::GitHooks::Plugin::PerlInterpreter->get_file_check_description();
94              
95             =cut
96              
97             sub get_file_check_description
98             {
99 13     13 1 22190 return 'The Perl interpreter line is correct';
100             }
101              
102              
103             =head2 run_pre_commit_file()
104              
105             Code to execute for each file as part of the pre-commit hook.
106              
107             my $success = App::GitHooks::Plugin::PerlInterpreter->run_pre_commit_file();
108              
109             =cut
110              
111             sub run_pre_commit_file
112             {
113 6     6 1 11125 my ( $class, %args ) = @_;
114 6         89 my $file = delete( $args{'file'} );
115 6         63 my $git_action = delete( $args{'git_action'} );
116 6         48 my $app = delete( $args{'app'} );
117 6         737 my $repository = $app->get_repository();
118 6         274 my $config = $app->get_config();
119              
120             # Ignore deleted files.
121 6 50       540 return $PLUGIN_RETURN_SKIPPED
122             if $git_action eq 'D';
123              
124             # Retrieve the first line.
125 6         320 my $path = $repository->work_tree() . '/' . $file;
126 6         1712 open( my $file_handle, '<', $path );
127 6         19806 my $first_line = <$file_handle>;
128 6         92 close( $file_handle );
129 6         6398 chomp( $first_line );
130              
131             # Verify the interpreter.
132 6         111 my $interpreter_regex = $config->get_regex( 'PerlInterpreter', 'interpreter_regex' );
133 6 50 33     535 die "The [PerlInterpreter] section of your config file is missing a 'interpreter_regex' key.\n"
134             if !defined( $interpreter_regex ) || ( $interpreter_regex !~ /\w/ );
135              
136 6 100       151 if ( $first_line !~ /$interpreter_regex/ )
137             {
138 5         22 my $error = "Invalid: $first_line\n";
139              
140 5         30 my $recommended_interpreter = $config->get( 'PerlInterpreter', 'recommended_interpreter' );
141 5 100       75 $error .= "Recommended: $recommended_interpreter\n"
142             if defined( $recommended_interpreter );
143              
144 5         23 chomp( $error );
145 5         143 die "$error\n";
146             }
147              
148 1         18 return $PLUGIN_RETURN_PASSED;
149             }
150              
151              
152             =head1 BUGS
153              
154             Please report any bugs or feature requests through the web interface at
155             L.
156             I will be notified, and then you'll automatically be notified of progress on
157             your bug as I make changes.
158              
159              
160             =head1 SUPPORT
161              
162             You can find documentation for this module with the perldoc command.
163              
164             perldoc App::GitHooks::Plugin::PerlInterpreter
165              
166              
167             You can also look for information at:
168              
169             =over
170              
171             =item * GitHub's request tracker
172              
173             L
174              
175             =item * AnnoCPAN: Annotated CPAN documentation
176              
177             L
178              
179             =item * CPAN Ratings
180              
181             L
182              
183             =item * MetaCPAN
184              
185             L
186              
187             =back
188              
189              
190             =head1 AUTHOR
191              
192             L,
193             C<< >>.
194              
195              
196             =head1 COPYRIGHT & LICENSE
197              
198             Copyright 2013-2017 Guillaume Aubert.
199              
200             This code is free software; you can redistribute it and/or modify it under the
201             same terms as Perl 5 itself.
202              
203             This program is distributed in the hope that it will be useful, but WITHOUT ANY
204             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
205             PARTICULAR PURPOSE. See the LICENSE file for more details.
206              
207             =cut
208              
209             1;