File Coverage

blib/lib/App/GitHooks/Plugin/BlockProductionCommits.pm
Criterion Covered Total %
statement 29 29 100.0
branch 6 10 60.0
condition 1 2 50.0
subroutine 5 5 100.0
pod 1 1 100.0
total 42 47 89.3


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