Skip to content

Instantly share code, notes, and snippets.

@keedi
Created June 8, 2013 08:12
Show Gist options
  • Save keedi/5734489 to your computer and use it in GitHub Desktop.
Save keedi/5734489 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use Cwd qw/ abs_path /;
use Encode qw/ decode_utf8 /;
use List::MoreUtils qw/ uniq /;
use WWW::Bugzilla;
#
# Edited by Keedi Kim
#
# - handle multiple bug numbers
# - use git config
# - show merged info when using git flow
#
#
# Get old revision, new revision and branch/tag name
#
my ($oldrev, $newrev, $refname);
if (scalar(@ARGV)) {
($oldrev, $newrev, $refname) = @ARGV[ 0 .. 2 ];
} else {
my $args = <STDIN>;
($oldrev, $newrev, $refname) = split(" ", $args);
}
# A hook script which integrates with bugzilla. It looks for bug IDs in
# commit messages and adds the commit message as well as a link to the
# changeset as a comment on the bug.
# This program is released under the terms of the GNU General Public License
# version 2. A copy of the license may be obtained by emailing the author,
# or at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#
# The absolute lack of warranty and other disclaimers as per the license
# apply.
#
# Copyright 2008, Devendra Gera. All rights reserved.
#
# Author : Devendra Gera
### user configurable section
# The bugzilla has contains the server, username and password for the targeted
# bugzilla installation. There's NO 'http://' in the server line.
#
# Retrieve all info from git config
#
my $server = qx(git config bugzilla.server);
my $email = qx(git config bugzilla.email);
my $password = qx(git config bugzilla.password);
my $use_ssl = qx(git config bugzilla.use_ssl);
map { s/\s+$// } ( $server, $email, $password, $use_ssl );
# The bug_regex should extract the bug id strings
my $bug_regex = qr{
[Bb]ug \s* \#\d+
(?:
[, ]+
(?: [Bb]ug \s* )?
\#\d+
)*
}x;
##### End user configurable section
my @log_lines = `git log --stat $oldrev..$newrev`;
my @commit_logs;
my @chunk;
for my $line ( @log_lines ) {
chomp $line;
if ( $line =~ /^commit [0-9a-f]+$/ ) {
push @commit_logs, join("\n", @chunk) if @chunk;
@chunk = ();
next;
}
} continue {
push @chunk, $line;
}
push @commit_logs, join("\n", @chunk) if @chunk;
for my $commit_log ( reverse @commit_logs ) {
my @bug_numbers;
if ( $commit_log =~ /($bug_regex)/ ) {
my $num_str = $1;
@bug_numbers = uniq ( $num_str =~ /#(\d+)/g );
}
next unless @bug_numbers;
my $project_dir = $ENV{GIT_DIR} || `dirname $ENV{GIT_CONFIG}`;
$project_dir = abs_path($project_dir);
my $project_short = `basename $project_dir .git`;
chomp $project_short;
my ($short_refname) = ($refname =~ /refs\/[^\/]*\/(.*)/);
my $comment = <<"END_COMMENT";
Project: $project_short \[$short_refname\]
$commit_log
END_COMMENT
# If commit is just merging, it doesn't show
# any commit message or file changes information.
# So we have to fetch them manually.
if ( $commit_log =~ /Merge branch '(.+?)' into (.+?)/ ) {
my $from = $1;
my $to = $2;
my $merge_info = `git log --pretty=format:'* \%cd \%h - \%s (\%an)' --date=short $newrev^..$newrev`;
my $merge_stat = `git diff --stat $newrev^..$newrev`;
$comment .= "$merge_info\n\n$merge_stat";
}
for my $bug_number ( @bug_numbers ) {
my $bz = WWW::Bugzilla->new(
server => $server,
email => $email,
password => $password,
use_ssl => $use_ssl =~ m/^true$/i ? 1 : 0,
bug_number => $bug_number
);
die "cannot connect to bugzilla" unless defined $bz;
$bz->additional_comments( decode_utf8($comment) );
$bz->commit;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment