File Coverage

blib/lib/Git/Hooks/GerritChangeId.pm
Criterion Covered Total %
statement 49 53 92.4
branch 7 14 50.0
condition 2 18 11.1
subroutine 11 11 100.0
pod 0 3 0.0
total 69 99 69.7


line stmt bran cond sub pod time code
1 1     1   4610 use warnings;
  1         5  
  1         85  
2              
3             package Git::Hooks::GerritChangeId;
4             # ABSTRACT: Git::Hooks plugin to insert a Change-Id in a commit message
5             $Git::Hooks::GerritChangeId::VERSION = '3.4.0';
6 1     1   24 use v5.16.0;
  1         4  
7 1     1   6 use utf8;
  1         2  
  1         8  
8 1     1   22 use Carp;
  1         2  
  1         113  
9 1     1   8 use Log::Any '$log';
  1         3  
  1         26  
10 1     1   977 use Git::Hooks;
  1         11  
  1         146  
11 1     1   349 use Git::Message;
  1         10  
  1         40  
12 1     1   12 use Path::Tiny;
  1         12  
  1         588  
13              
14             my $CFG = __PACKAGE__ =~ s/.*::/githooks./r;
15              
16             ##########
17              
18             sub gen_change_id {
19 2     2 0 10 my ($git, $msg) = @_;
20              
21 2         18 my $filename = Path::Tiny->tempfile(UNLINK => 1);
22 2 50 0     2268 open my $fh, '>', $filename ## no critic (RequireBriefOpen)
23             or $git->fault("Internal error: can't open '$filename' for writing:", {details => $!})
24             and croak;
25              
26 2         172 foreach my $info (
27             [ tree => [qw/write-tree/] ],
28             [ parent => [qw/rev-parse HEAD^0/] ],
29             [ author => [qw/var GIT_AUTHOR_IDENT/] ],
30             [ committer => [qw/var GIT_COMMITTER_IDENT/] ],
31             ) {
32 8         143 my $value = eval { $git->run(@{$info->[1]}) };
  8         18  
  8         122  
33 8 50       134019 if (defined $value) {
34             # It's OK if we can't find value.
35 8         201 $fh->print("$info->[0] $value");
36             }
37             }
38              
39 2         130 $fh->print("\n", $msg);
40 2         34 $fh->close();
41              
42 2         351 return 'I' . $git->run(qw/hash-object -t blob/, $filename);
43             }
44              
45             sub insert_change_id {
46 17     17 0 80 my ($git, $msg) = @_;
47              
48             # Does Change-Id: already exist? if so, exit (no change).
49 17 100       392 return if $msg =~ /^Change-Id:/im;
50              
51 2         90 my $cmsg = Git::Message->new($msg);
52              
53             # Don't mess with the message if it's empty.
54 2 0 33     30 if ( (! defined $cmsg->title || $cmsg->title !~ /\S/)
      0        
      33        
55             && (! defined $cmsg->body || $cmsg->body !~ /\S/)
56             ) {
57             # (Signed-off-by footers don't count.)
58 0         0 my @footer = $cmsg->get_footer_keys;
59 0 0 0     0 return if @footer == 0 || @footer == 1 && $footer[0] eq 'signed-off-by';
      0        
60             }
61              
62             # Insert the Change-Id footer
63 2         13 $cmsg->add_footer_values('Change-Id' => gen_change_id($git, $cmsg->as_string));
64              
65 2         35 return $cmsg->as_string;
66             }
67              
68             sub rewrite_message {
69 17     17 0 298808 my ($git, $commit_msg_file) = @_;
70              
71 17         202 $log->debug(__PACKAGE__ . "::rewrite_message($commit_msg_file)");
72              
73 17         775 my $msg = eval { $git->read_commit_msg_file($commit_msg_file) };
  17         434  
74 17 50       110 unless (defined $msg) {
75 0         0 $git->fault("Internal error: cannot read commit message file '$commit_msg_file'",
76             {details => $@});
77 0         0 return 0;
78             }
79              
80             # Rewrite the message file
81 17 100       180 if (my $new_msg = insert_change_id($git, $msg)) {
82 2         53 $git->write_commit_msg_file($commit_msg_file, $new_msg);
83             }
84              
85 17         79 return 1;
86             }
87              
88             # Install hooks
89             APPLYPATCH_MSG(\&rewrite_message);
90             COMMIT_MSG(\&rewrite_message);
91              
92             1;
93              
94             __END__