diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-02-13 21:16:02 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-06-12 10:17:09 +0000 |
commit | 2792c18e1d33594da05914d9d521adc2cc641ad9 (patch) | |
tree | 7100e93a723b4749d5020d3fed9e6db7bc00d257 /git-hooks/gerrit-bot-extras | |
parent | 59e404b2f2628ca3f4e8104ec55c7409f9db90f3 (diff) | |
download | qtrepotools-2792c18e1d33594da05914d9d521adc2cc641ad9.tar.gz |
factor out watches and w-i-p handling to separate worker
originally, the idea was to have one gerrit-bot instance per worker, but
that would result in an (even greater) flood of comments. so all
functionality that didn't fit into sanitize-commit was added to
gerrit-bot. at this time it's getting messy, so clean it up by making it
a plain launcher/dispatcher again, with the ability to run multiple
workers on a single commit.
Change-Id: I8c04f449726793b99e9f1ac5c6db330a1f17389f
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'git-hooks/gerrit-bot-extras')
-rwxr-xr-x | git-hooks/gerrit-bot-extras | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/git-hooks/gerrit-bot-extras b/git-hooks/gerrit-bot-extras new file mode 100755 index 0000000..fad85da --- /dev/null +++ b/git-hooks/gerrit-bot-extras @@ -0,0 +1,108 @@ +#! /usr/bin/perl + +# Copyright (C) 2017 The Qt Company Ltd. +# Contact: http://www.qt.io/licensing/ +# +# You may use this file under the terms of the 3-clause BSD license. +# See the file LICENSE from this package for details. +# + +use strict; +use warnings; +use JSON; + +# Usage: $0 <project> <SHA1> [instance] +# - default instance is 'sanitybot' +# - configure git: git config --global <instance>.<option> <value> +# Valid options are: +# watches (optional) +# Space-separated list of path watches. Each watch requires an own +# section named watches.<name> with the following keys (note that +# these sections are NOT namespaced with the instance): +# projects (default ".*") +# Regular expression specifying the projects to watch. +# files +# Regular expression specifying the filepaths to watch. +# message (optional) +# The message to post when this watch triggers. +# invite (optional) +# Space-separated list of reviewers to add when this watch triggers. + +die "usage: $0 <project> <SHA1> [instance]\n" if ($#ARGV < 1); +my $project = shift @ARGV; +my $rev = shift @ARGV; + +my $instance = 'sanitybot'; +$instance = $ARGV[0] if ($#ARGV > -1); + +# Doing this is less expensive than calling git repeatedly. +my %config = (); +for (`git config -l`) { + /^([^=]+)=(.*$)/; + $config{$1} = $2; +} + +sub getcfg($;$) +{ + my ($key, $def) = @_; + my $fkey = $instance.'.'.$key; + if (defined $config{$fkey}) { + return $config{$fkey}; + } elsif (@_ > 1) { + return $def; + } else { + die $fkey." not set.\n"; + } +} + +my @messages = (); +my %verdict = (); +my @invite = (); + +my (@watches, %watch_files, %watch_messages, %watch_invites); +for my $w (split(/\s+/, getcfg('watches', ""))) { + my $p = $config{'watches.'.$w.'.projects'}; + next if (defined($p) && $project !~ qr/^$p$/); + my $f = $config{'watches.'.$w.'.files'}; + die "watches.$w.files not set.\n" if (!defined($f)); + $watch_files{$w} = qr/^$f$/; + $watch_messages{$w} = $config{'watches.'.$w.'.message'}; + my $i = $config{'watches.'.$w.'.invite'}; + $watch_invites{$w} = defined($i) ? [ split(/\s+/, $i) ] : []; + push @watches, $w; +} + +my $subject; + +if (@watches) { + my @touched = `git show --pretty=\%s --name-only --ignore-submodules -C $rev`; + chop(@touched); + $subject = shift @touched; + shift @touched; # empty line + for my $w (@watches) { + for my $file (@touched) { + if ($file =~ $watch_files{$w}) { + push @messages, $watch_messages{$w} if (defined($watch_messages{$w})); + push @invite, @{$watch_invites{$w}}; + last; + } + } + } +} + +if (!defined($subject)) { + $subject = `git show --pretty=\%s -s $rev`; + chop($subject); +} + +my $cr = 0; +if ($subject =~ /^[<[]?[Ww]ip\b|\bWIP\b|\*{3}|^(?:squash|fixup)! |^(.)\1*$/) { + unshift @messages, "Apparently pushing a Work In Progress"; + $cr = -2; +} +$verdict{labels}{'Code-Review'} = $cr; + +$verdict{message} = join("\n\n", @messages) if (@messages); +$verdict{invite} = \@invite if (@invite); + +print encode_json(\%verdict)."\n"; |