File Coverage

blib/lib/App/GitHooks/Plugin/BlockProductionCommits.pm
Criterion Covered Total %
statement 33 33 100.0
branch 8 12 66.6
condition 1 2 50.0
subroutine 6 6 100.0
pod 1 1 100.0
total 49 54 90.7


line stmt bran cond sub pod time code
1             package App::GitHooks::Plugin::BlockProductionCommits;
2              
3 4     4   563473 use strict;
  4         7  
  4         91  
4 4     4   12 use warnings;
  4         7  
  4         88  
5              
6 4     4   13 use base 'App::GitHooks::Plugin';
  4         11  
  4         607  
7              
8             # External dependencies.
9 4     4   285 use Carp qw( croak );
  4         5  
  4         181  
10              
11             # Internal dependencies.
12 4     4   429 use App::GitHooks::Constants qw( :PLUGIN_RETURN_CODES );
  4         3539  
  4         1465  
13              
14              
15             =head1 NAME
16              
17             App::GitHooks::Plugin::BlockProductionCommits - Prevent commits in a production environment.
18              
19              
20             =head1 DESCRIPTION
21              
22             Committing in production means you've been developing in production. That just
23             sounds like a terrible idea.
24              
25              
26             =head1 VERSION
27              
28             Version 1.2.0
29              
30             =cut
31              
32             our $VERSION = '1.2.0';
33              
34              
35             =head1 CONFIGURATION OPTIONS
36              
37             This plugin supports the following options in the C<[BlockProductionCommits]>
38             section of your C<.githooksrc> file.
39              
40             [BlockProductionCommits]
41             env_variable = my_environment
42             env_safe_regex = /^development$/
43             remotes_whitelist_regex = /\/my_production_tools_repository\.git$/
44              
45              
46             =head2 env_variable
47              
48             The name of the environment variable to use to determine the environment.
49              
50             env_variable = my_environment
51              
52              
53             =head2 env_safe_regex
54              
55             A regular expression that indicates that the environment is safe to commit when
56             it is matched.
57              
58             env_safe_regex = /^development$/
59              
60             The example above only allow commits when C<$ENV{'my_environment'} =~ /^development$/>.
61              
62              
63             =head2 remotes_whitelist_regex
64              
65             A regular expression that indicates that commits should be allowed even if the
66             environment is production as long as the git remote matches it.
67              
68             This is particularly useful if you have many repositories on your production
69             machines, and one of them is used by automated tools that should still be
70             allowed to commit.
71              
72             remotes_whitelist_regex = /\/my_production_tools_repository\.git$/
73              
74              
75             =head1 METHODS
76              
77             =head2 run_pre_commit()
78              
79             Code to execute as part of the pre-commit hook.
80              
81             my $success = App::GitHooks::Plugin::BlockProductionCommits->run_pre_commit();
82              
83             =cut
84              
85             sub run_pre_commit
86             {
87 3     3 1 10899 my ( $class, %args ) = @_;
88 3         7 my $app = delete( $args{'app'} );
89 3         11 my $repository = $app->get_repository();
90 3         87329 my $config = $app->get_config();
91              
92             # Allow non-interactive tools to commit in production.
93 3 50       105 my $is_interactive = defined( $config->get( 'testing', 'force_interactive' ) )
94             ? $config->get( 'testing', 'force_interactive' )
95             : $app->get_terminal()->is_interactive();
96 3 50       65 return $PLUGIN_RETURN_PASSED
97             if !$is_interactive;
98              
99             # Check if the environment is safe to commit in.
100 3         10 my $env_variable = $config->get( 'BlockProductionCommits', 'env_variable' );
101 3 100       268 croak "You must define 'env_variable' in the [BlockProductionCommits] section of your githooksrc config"
102             if !defined( $env_variable );
103 2   50     9 my $env_value = $ENV{ $env_variable } // '';
104 2         10 my $env_regex = $config->get_regex( 'BlockProductionCommits', 'env_safe_regex' );
105 2 100       107 return $PLUGIN_RETURN_PASSED
106             if $env_value =~ $env_regex;
107              
108             # Check for whitelisted remotes, in case some specific repositories should be
109             # allowed to be committed to in production.
110 1         3 my $remotes_whitelist_regex = $config->get_regex( 'BlockProductionCommits', 'remotes_whitelist_regex' );
111 1 50       18 if ( defined( $remotes_whitelist_regex ) )
112             {
113 1         3 my $remotes = $repository->run( 'remote', '-v' );
114 1 50       7101 return $PLUGIN_RETURN_PASSED
115             if $remotes =~ /$remotes_whitelist_regex/x;
116             }
117              
118 1         9 my $failure_character = $app->get_failure_character();
119 1         27 print $app->wrap(
120             $app->color( 'red', "$failure_character Non-dev environment detected - please commit from your dev instead.\n" ),
121             "",
122             );
123 1         49 return $PLUGIN_RETURN_FAILED;
124             }
125              
126              
127             =head1 BUGS
128              
129             Please report any bugs or feature requests through the web interface at
130             L.
131             I will be notified, and then you'll automatically be notified of progress on
132             your bug as I make changes.
133              
134              
135             =head1 SUPPORT
136              
137             You can find documentation for this module with the perldoc command.
138              
139             perldoc App::GitHooks::Plugin::BlockProductionCommits
140              
141              
142             You can also look for information at:
143              
144             =over
145              
146             =item * GitHub's request tracker
147              
148             L
149              
150             =item * AnnoCPAN: Annotated CPAN documentation
151              
152             L
153              
154             =item * CPAN Ratings
155              
156             L
157              
158             =item * MetaCPAN
159              
160             L
161              
162             =back
163              
164              
165             =head1 AUTHOR
166              
167             L,
168             C<< >>.
169              
170              
171             =head1 COPYRIGHT & LICENSE
172              
173             Copyright 2013-2017 Guillaume Aubert.
174              
175             This code is free software; you can redistribute it and/or modify it under the
176             same terms as Perl 5 itself.
177              
178             This program is distributed in the hope that it will be useful, but WITHOUT ANY
179             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
180             PARTICULAR PURPOSE. See the LICENSE file for more details.
181              
182             =cut
183              
184             1;