File Coverage

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


line stmt bran cond sub pod time code
1             package App::GitHooks::Plugin::MatchBranchTicketID;
2              
3 7     7   1159644 use strict;
  7         14  
  7         182  
4 7     7   26 use warnings;
  7         7  
  7         160  
5              
6 7     7   22 use base 'App::GitHooks::Plugin';
  7         10  
  7         1153  
7              
8             # Internal dependencies.
9 7     7   719 use App::GitHooks::Utils;
  7         2037  
  7         165  
10 7     7   411 use App::GitHooks::Constants qw( :PLUGIN_RETURN_CODES );
  7         3344  
  7         2018  
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.2
33              
34             =cut
35              
36             our $VERSION = '1.0.2';
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 22873 my ( $class, %args ) = @_;
134 6         11 my $commit_message = delete( $args{'commit_message'} );
135 6         10 my $app = delete( $args{'app'} );
136 6         23 my $repository = $app->get_repository();
137              
138 6         221850 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         1330 my $branch_ticket_id = App::GitHooks::Utils::get_ticket_id_from_branch_name( $app );
143 6 100 100     57554 if ( defined( $ticket_id ) && defined( $branch_ticket_id ) && ( $branch_ticket_id ne $ticket_id ) )
      100        
144             {
145 2         29 print $app->color( 'red', "Your branch is referencing $branch_ticket_id, but your commit message references $ticket_id.\n" );
146             # uncoverable branch true
147 2 50       51 if ( $app->get_terminal()->is_interactive() )
148             {
149 0         0 print "Press to continue committing with $ticket_id, or Ctrl-C to abort the commit.\n";
150 0         0 my $input = ; ## no critic (InputOutput::ProhibitExplicitStdin)
151             }
152             else
153             {
154 2         60 return $PLUGIN_RETURN_FAILED;
155             }
156             }
157              
158 4         47 return $PLUGIN_RETURN_PASSED;
159             }
160              
161              
162             =head1 BUGS
163              
164             Please report any bugs or feature requests through the web interface at
165             L.
166             I will be notified, and then you'll automatically be notified of progress on
167             your bug as I make changes.
168              
169              
170             =head1 SUPPORT
171              
172             You can find documentation for this module with the perldoc command.
173              
174             perldoc App::GitHooks::Plugin::MatchBranchTicketID
175              
176              
177             You can also look for information at:
178              
179             =over
180              
181             =item * GitHub's request tracker
182              
183             L
184              
185             =item * AnnoCPAN: Annotated CPAN documentation
186              
187             L
188              
189             =item * CPAN Ratings
190              
191             L
192              
193             =item * MetaCPAN
194              
195             L
196              
197             =back
198              
199              
200             =head1 AUTHOR
201              
202             L,
203             C<< >>.
204              
205              
206             =head1 COPYRIGHT & LICENSE
207              
208             Copyright 2013-2016 Guillaume Aubert.
209              
210             This code is free software; you can redistribute it and/or modify it under the
211             same terms as Perl 5 itself.
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 LICENSE file for more details.
216              
217             =cut
218              
219             1;