File Coverage

blib/lib/App/GitHooks/Hook/PrepareCommitMsg.pm
Criterion Covered Total %
statement 39 43 90.7
branch 5 12 41.6
condition 1 2 50.0
subroutine 9 9 100.0
pod 1 1 100.0
total 55 67 82.0


line stmt bran cond sub pod time code
1             package App::GitHooks::Hook::PrepareCommitMsg;
2              
3 2     2   14608 use strict;
  2         3  
  2         47  
4 2     2   6 use warnings;
  2         2  
  2         49  
5              
6             # Inherit from the base Hook class.
7 2     2   5 use base 'App::GitHooks::Hook';
  2         2  
  2         664  
8              
9             # External dependencies.
10 2     2   8 use Carp;
  2         2  
  2         95  
11 2     2   545 use Data::Dumper;
  2         6737  
  2         76  
12 2     2   656 use Path::Tiny qw();
  2         7471  
  2         32  
13              
14             # Internal dependencies.
15 2     2   651 use App::GitHooks::CommitMessage;
  2         3  
  2         50  
16 2     2   7 use App::GitHooks::Constants qw( :PLUGIN_RETURN_CODES :HOOK_EXIT_CODES );
  2         2  
  2         598  
17              
18              
19             =head1 NAME
20              
21             App::GitHooks::Hook::CommitMsg - Handler for commit-msg hook.
22              
23              
24             =head1 VERSION
25              
26             Version 1.8.0
27              
28             =cut
29              
30             our $VERSION = '1.8.0';
31              
32              
33             =head1 METHODS
34              
35             =head2 run()
36              
37             Run the hook handler and return an exit status to pass to git.
38              
39             my $exit_status = App::GitHooks::Hook::CommitMsg->run(
40             app => $app,
41             );
42              
43             Arguments:
44              
45             =over 4
46              
47             =item * app I<(mandatory)>
48              
49             An App::GitHooks object.
50              
51             =back
52              
53             =cut
54              
55             sub run
56             {
57 1     1 1 2 my ( $class, %args ) = @_;
58 1         1 my $app = delete( $args{'app'} );
59 1 50       3 croak 'Unknown argument(s): ' . join( ', ', keys %args )
60             if scalar( keys %args ) != 0;
61              
62             # Check parameters.
63 1 50       2 croak "The 'app' argument is mandatory"
64             if !Data::Validate::Type::is_instance( $app, class => 'App::GitHooks' );
65              
66             # Retrieve the commit message.
67 1         18 my $command_line_arguments = $app->get_command_line_arguments();
68 1         1 my $commit_message_file = $command_line_arguments->[0];
69 1   50     4 my $commit_message = App::GitHooks::CommitMessage->new(
70             message => Path::Tiny::path( $commit_message_file )->slurp_utf8() // '',
71             app => $app,
72             );
73              
74             # Find and run all the plugins that support the prepare-commit-msg hook.
75 1         6 my $tests_success = 1;
76 1         3 my $plugins = $app->get_hook_plugins( 'prepare-commit-msg' );
77 1         15 foreach my $plugin ( @$plugins )
78             {
79 1         5 my $check_result = $plugin->run_prepare_commit_msg(
80             app => $app,
81             commit_message => $commit_message,
82             );
83 1 50       4 $tests_success = 0
84             if $check_result == $PLUGIN_RETURN_FAILED;
85             }
86              
87             # If the commit message was modified above, we need to overwrite the file.
88 1 50       3 if ( $commit_message->has_changed() )
89             {
90 0         0 my $terminal = $app->get_terminal();
91 0         0 my $message = $commit_message->get_message();
92 0         0 my $file = Path::Tiny::path( $commit_message_file );
93 0 0       0 $terminal->is_utf8()
94             ? $file->spew_utf8( $message )
95             : $file->spew( $message );
96             }
97              
98             # .git/COMMIT-MSG-CHECKS is a file we use to track if the pre-commit hook has
99             # run, as opposed to being skipped with --no-verify. Since pre-commit can be
100             # skipped, but prepare-commit-msg cannot, plugins can use the presence of
101             # that file to determine if some optional processing should be performed in
102             # the prepare-commit-msg phase. For example, you may want to add a warning
103             # indicating that --no-verify was used. Note however that the githooks man
104             # page says "it should not be used as replacement for pre-commit hook".
105             #
106             # And since we're done with prepare-commit-msg checks now, we can safely
107             # remove the file.
108 1         21 unlink( '.git/COMMIT-MSG-CHECKS' );
109              
110 1 50       12 return $tests_success
111             ? $HOOK_EXIT_SUCCESS
112             : $HOOK_EXIT_FAILURE;
113             }
114              
115              
116             =head1 BUGS
117              
118             Please report any bugs or feature requests through the web interface at
119             L.
120             I will be notified, and then you'll automatically be notified of progress on
121             your bug as I make changes.
122              
123              
124             =head1 SUPPORT
125              
126             You can find documentation for this module with the perldoc command.
127              
128             perldoc App::GitHooks::Hook::PrepareCommitMsg
129              
130              
131             You can also look for information at:
132              
133             =over
134              
135             =item * GitHub's request tracker
136              
137             L
138              
139             =item * AnnoCPAN: Annotated CPAN documentation
140              
141             L
142              
143             =item * CPAN Ratings
144              
145             L
146              
147             =item * MetaCPAN
148              
149             L
150              
151             =back
152              
153              
154             =head1 AUTHOR
155              
156             L,
157             C<< >>.
158              
159              
160             =head1 COPYRIGHT & LICENSE
161              
162             Copyright 2013-2016 Guillaume Aubert.
163              
164             This code is free software; you can redistribute it and/or modify it under the
165             same terms as Perl 5 itself.
166              
167             This program is distributed in the hope that it will be useful, but WITHOUT ANY
168             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
169             PARTICULAR PURPOSE. See the LICENSE file for more details.
170              
171             =cut
172              
173             1;