File Coverage

blib/lib/App/GitHooks/Plugin/MatchBranchTicketID.pm
Criterion Covered Total %
statement 26 28 92.8
branch 3 4 75.0
condition 6 6 100.0
subroutine 6 6 100.0
pod 1 1 100.0
total 42 45 93.3


line stmt bran cond sub pod time code
1             package App::GitHooks::Plugin::MatchBranchTicketID;
2              
3 7     7   2340285 use strict;
  7         19  
  7         260  
4 7     7   37 use warnings;
  7         14  
  7         241  
5              
6 7     7   40 use base 'App::GitHooks::Plugin';
  7         17  
  7         1782  
7              
8             # Internal dependencies.
9 7     7   1950 use App::GitHooks::Utils;
  7         4420  
  7         193  
10 7     7   1149 use App::GitHooks::Constants qw( :PLUGIN_RETURN_CODES );
  7         399  
  7         3193  
11              
12              
13             =head1 NAME
14              
15             App::GitHooks::Plugin::MatchBranchTicketID - Detect discrepancies between the ticket ID specified by the branch name and the one in the commit message.
16              
17              
18             =head1 DESCRIPTION
19              
20             C allows pulling ticket IDs from the
21             branch name. This way, if you're committing a lot, having a proper branch name
22             can save you a lot of time.
23              
24             That said, you sometimes need to commit using a different ticket ID than what
25             the branch specifies. In order to prevent typos, this plugin will detect if the
26             ticket ID specified in the commit message doesn't match the ticket ID infered
27             from the branch name, and ask you to confirm that you want to proceed forward.
28              
29              
30             =head1 VERSION
31              
32             Version 1.0.1
33              
34             =cut
35              
36             our $VERSION = '1.0.1';
37              
38              
39             =head1 CONFIGURATION OPTIONS
40              
41             This plugin supports the following options in the main section of your
42             C<.githooksrc> file.
43              
44             project_prefixes = OPS, DEV, TEST
45             extract_ticket_id_from_branch = /^($project_prefixes\d+)/
46             normalize_branch_ticket_id = s/^(.*?)(\d+)$/\U$1-$2/
47             extract_ticket_id_from_commit = /^($project_prefixes-\d+|--): /
48              
49              
50             =head2 project_prefixes
51              
52             The list of valid ticket prefixes.
53              
54             project_prefixes = OPS, DEV, TEST
55              
56              
57             =head2 extract_ticket_id_from_branch
58              
59             A regular expression with one capturing group that will extract the ticket ID
60             from a branch name.
61              
62             extract_ticket_id_from_branch = /^($project_prefixes\d+)/
63              
64             In the example above, if a branch is named C, the
65             regular expression will identify C as the ticket ID corresponding to
66             that branch.
67              
68             Note that:
69              
70             =over 4
71              
72             =item *
73              
74             Prefixes used for private branches are recognized properly and ignored
75             accordingly. In other words, both C and
76             C will be identified as tied to C with the
77             regex above.
78              
79             =item *
80              
81             $project_prefixes is replaced at run time by the prefixes listed in the
82             C configuration option, to avoid duplication of information.
83              
84             =back
85              
86              
87             =head2 normalize_branch_ticket_id
88              
89             A replacement expression to normalize the ticket ID extracted with
90             C.
91              
92             normalize_branch_ticket_id = s/^(.*?)(\d+)$/\U$1-$2/
93              
94             In the example above, C gave C, which is then
95             normalized as C.
96              
97              
98             =head2 extract_ticket_id_from_commit
99              
100             A regular expression with one capturing group that will extract the ticket ID
101             from a commit message.
102              
103             extract_ticket_id_from_commit = /^($project_prefixes-\d+|--): /
104              
105             Note that:
106              
107             =over 4
108              
109             =item *
110              
111             $project_prefixes is replaced at run time by the prefixes listed in the
112             C configuration option, to avoid duplication of information.
113              
114             =item *
115              
116             The example above allows C<--> to indicate that no ticket ID is available. This allows an occasional commit without a ticket ID, while making it easy to identify / review later. But you can configure this regular expression to use C or any other keyword instead.
117              
118             =back
119              
120              
121             =head1 METHODS
122              
123             =head2 run_commit_msg()
124              
125             Code to execute as part of the commit-msg hook.
126              
127             my $success = App::GitHooks::Plugin::MatchBranchTicketID->run_commit_msg();
128              
129             =cut
130              
131             sub run_commit_msg
132             {
133 6     6 1 49678 my ( $class, %args ) = @_;
134 6         26 my $commit_message = delete( $args{'commit_message'} );
135 6         18 my $app = delete( $args{'app'} );
136 6         36 my $repository = $app->get_repository();
137              
138 6         1056542 my $ticket_id = $commit_message->get_ticket_id();
139              
140             # If the branch specifies a ticket ID, and it doesn't match the ticket ID
141             # found in the commit message, ask the user to confirm.
142 6         2381 my $branch_ticket_id = App::GitHooks::Utils::get_ticket_id_from_branch_name( $app );
143 6 100 100     232731 if ( defined( $ticket_id ) && defined( $branch_ticket_id ) && ( $branch_ticket_id ne $ticket_id ) )
      100        
144             {
145 2         40 print $app->color( 'red', "Your branch is referencing $branch_ticket_id, but your commit message references $ticket_id.\n" );
146 2 50       54 if ( $app->get_terminal()->is_interactive() )
147             {
148 0         0 print "Press to continue committing with $ticket_id, or Ctrl-C to abort the commit.\n";
149 0         0 my $input = ; ## no critic (InputOutput::ProhibitExplicitStdin)
150             }
151             else
152             {
153 2         158 return $PLUGIN_RETURN_FAILED;
154             }
155             }
156              
157 4         86 return $PLUGIN_RETURN_PASSED;
158             }
159              
160              
161             =head1 BUGS
162              
163             Please report any bugs or feature requests through the web interface at
164             L.
165             I will be notified, and then you'll automatically be notified of progress on
166             your bug as I make changes.
167              
168              
169             =head1 SUPPORT
170              
171             You can find documentation for this module with the perldoc command.
172              
173             perldoc App::GitHooks::Plugin::MatchBranchTicketID
174              
175              
176             You can also look for information at:
177              
178             =over
179              
180             =item * GitHub's request tracker
181              
182             L
183              
184             =item * AnnoCPAN: Annotated CPAN documentation
185              
186             L
187              
188             =item * CPAN Ratings
189              
190             L
191              
192             =item * MetaCPAN
193              
194             L
195              
196             =back
197              
198              
199             =head1 AUTHOR
200              
201             L,
202             C<< >>.
203              
204              
205             =head1 COPYRIGHT & LICENSE
206              
207             Copyright 2013-2014 Guillaume Aubert.
208              
209             This program is free software: you can redistribute it and/or modify it under
210             the terms of the GNU General Public License version 3 as published by the Free
211             Software Foundation.
212              
213             This program is distributed in the hope that it will be useful, but WITHOUT ANY
214             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
215             PARTICULAR PURPOSE. See the GNU General Public License for more details.
216              
217             You should have received a copy of the GNU General Public License along with
218             this program. If not, see http://www.gnu.org/licenses/
219              
220             =cut
221              
222             1;