The attached script summarizes git log data and generates CSV lines for each 
commit.  For example,
; git log -2 | ~/reviews.pl
8984, 2019-05-23, levi...@openssl.org, O, paul.d...@oracle.com, O
9624, 2019-08-18, bernd.edlin...@hotmail.de, C, levi...@openssl.org, O
It ignores log entries that don’t follow the common format of having 
“Reviewed-by” and “Merged from” lines.

This can be useful to get a handle on PR’s and reviewer activity.  I don’t yet 
know what questions to ask :) but it will be nice to have numbers that prove 
that the project needs to improve its reviewer flow :( There’s rumors that the 
project will be announcing some restructuring or policy changes soon, and maybe 
this will be helpful input to that process.


#! /usr/bin/env perl

# Read "git log" output (usually a subset, not the whole log) and print
# summary lines for each PR showing author, date, reviewers (one per line).
# A typical use, see who reviewed PR's in the first quarter of 2019:
#       git log --since 1/1/2019 --until 3/31/2019 | perl reviews.pl
use strict;
use warnings;
use Date::Parse;

# Things we log.
my $author = '-';
my $when = '-';
my $pr = 0;
my @reviewers;


# List of OMC members who use non-openssl.org addresses
my %omc_email = (
    'paul.d...@oracle.com' => 1,
    'k...@roeckx.be' => 1,
    'b...@links.org' => 1,
    'openssl-us...@dukhovni.org' => 1,
);
my %committers = (
    'matthias.st.pie...@ncp-e.com' => 1,
    'beld...@gmail.com' => 1,
    'bernd.edlin...@hotmail.de' => 1,
    'bka...@akamai.com' => 1,
    'david...@google.com' => 1,
    'ka...@mit.edu' => 1,
    'nic....@gmail.com' => 1,
    'patrick.ste...@de.ibm.com' => 1,
    'paulyang....@gmail.com' => 1,
    'shane.lon...@oracle.com' => 1,
    'tm...@fedoraproject.org' => 1,
);

# Return "O" if |$1| is an OMC member, "C" if they are a committer, or
# "N" otherwise.
sub user_type {
    my $email = shift;

    return "O" if $email =~ m/\@openssl.org/ or defined $omc_email{$email};
    return "C" if defined $committers{$email};
    return "N";
}


# If this commit is a new PR, print a CSV line.
my $savedpr = 0;
sub process {
    if ( $savedpr != $pr ) {
        for my $r ( @reviewers ) {
            my $a_type = user_type($author);
            my $r_type = user_type($r);
            print "$pr, $when, $author, $a_type, $r, $r_type\n";
        }
    }
    $savedpr = $pr;
    $author = '-';
    $pr = 0;
    $when = '-';
    @reviewers = ();
}


# Get input source.
my $LOG;
if ( -t STDIN ) {
    open $LOG, "git log|" or die "Can't popen git log $!,";
} else {
    $LOG = *STDIN;
}

# Read/parse/process input.
while ( <$LOG> ) {
    chop;
    if ( /^commit / ) {
        process();
    } elsif ( /^Author:.*<(.*)>/ ) {
        $author = $1;
    } elsif ( /^Date:\s+... (.*) [-+]\d+/ ) {
        my @f = strptime($1);
        $when = sprintf "%4.4d-%02.2d-%02.2d", $f[5] + 1900, $f[4] + 1, $f[3];
    } elsif ( /Reviewed-by: .*<(.*)>/) {
        push @reviewers, $1;
    } elsif ( m@Merged from https://github.com/openssl/openssl/pull/(\d+)@ ) {
        $pr = $1;
    }
}
process();

Reply via email to