summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorMartin Roth <gaumless@gmail.com>2022-12-10 22:00:40 -0700
committerMartin Roth <martin.roth@amd.corp-partner.google.com>2022-12-13 18:49:13 +0000
commitae7d8379a560631f3bdd01624b027d6c65361a4c (patch)
tree79733c4e74660ba0e0e5a58fd09b290836f9873c /util
parenta6514e2b1f79c6112768f3b7bc47310c06c2c3a2 (diff)
util/release: Update gerrit_stats script to latest version
This updates a number of things: - Move the cache directory under the .local directory - Reformat & clean up with perltidy. Add the perltidy command line. - Add username and email aliases to clean up duplicates and unknown email addresses. - Use full length commit IDs - Collect patch commenters - Check variables before using them as key values - Ignore patch submit time, just collect the date - Get stats about large patches - Format the output better Example output: Statistics from commit c35f2819348501579a32e870e21f5f1b062d26e8 to commit f8fbf0917c722378454b07c2e8ec1a3f87b324ae Patch, Date, Owner, Author, Submitter, Inserted lines, Deleted lines, Subject, Reviewers, Commenters "f8fbf0917c722378454b07c2e8ec1a3f87b324ae", 2022/12/10, Frank Chu, Frank Chu, Martin Roth, 22, 1, "mb/google/brya/var/marasov: Change FSP board type to Type3", "Frank Chu, Eric Lai" , "-" "5778e06771627a5541ca2b137e783f47257f05ec", 2022/12/10, Dinesh Gehlot, Dinesh Gehlot, Subrata Banik, 30, 1, "soc/intel/meteorlake: Drop casts around `soc_read_pmc_base()`", "Kapil Porwal, Elyes Haouas" , "Subrata Banik" "ed8bdefcdf6c19258febb9931d1e8eb12b958bcc", 2022/12/10, Jamie Ryu, Jamie Ryu, Felix Held, 76, 3, "mb/intel/mtlrvp: Add MTL-P RVP board ids", "Usha P, Sridhar Siricilla, Eric Lai, Subrata Banik" , "Eric Lai, Subrata Banik, Harsha B R, Angel Pons" - Total Commits: 985 - Average Commits per day: 17.85 - Total lines added: 61475 - Average lines added per commit: 62.41 - Number of patches adding more than 100 lines: 49 - Average lines added per small commit: 37.82 - Total lines removed: 758022 - Average lines removed per commit: 769.57 - Total difference between added and removed: -696547 === Authors - Number of commits === Author ,Ptchs ,Revws , Cmnts , Sbmts , Email , Prcnt, Last commit , Earliest_commit Elyes Haouas , 126 , 90 , 28 , 0 , ehaouas@noos.fr ,12.79%, 2022/12/10 , 2022/10/17 Arthur Heymans , 107 , 99 , 28 , 40 , arthur@aheymans.xyz ,10.86%, 2022/12/10 , 2022/10/17 === Authors - Lines added === Martin Roth , 10103, 16.434% Kyösti Mälkki , 6044, 9.832% Arthur Heymans , 3314, 5.391% === Authors - Lines removed === Arthur Heymans , -741944, 97.879% Felix Held , -3031, 0.400% Kyösti Mälkki , -1680, 0.222% === Reviewers - Number of patches reviewed === Angel Pons , 272, 27.614% Eric Lai , 201, 20.406% Felix Held , 106, 10.761% === Submitters - Number of patches submitted === Name , #, total%, Own, own%, Other, other% Felix Held , 482, 48.934%, 56, 11.62%, 426, 88.38% Martin Roth , 179, 18.173%, 42, 23.46%, 137, 76.54% Subrata Banik , 54, 5.482%, 31, 57.41%, 23, 42.59% Signed-off-by: Martin Roth <gaumless@gmail.com> Change-Id: Ie1694116ab36ca4db25d13935adadca10e50068f Reviewed-on: https://review.coreboot.org/c/coreboot/+/70572 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Felix Singer <felixsinger@posteo.net>
Diffstat (limited to 'util')
-rwxr-xr-xutil/release/gerrit_stats.pl519
1 files changed, 389 insertions, 130 deletions
diff --git a/util/release/gerrit_stats.pl b/util/release/gerrit_stats.pl
index 94681579e1..789cb051d7 100755
--- a/util/release/gerrit_stats.pl
+++ b/util/release/gerrit_stats.pl
@@ -8,6 +8,8 @@ package gerrit_stats;
# sudo cpan App::cpanminus
# sudo /usr/local/bin/cpanm JSON::Util Net::OpenSSH DateTime Devel::Size
+# perltidy -l=200 -bt=2 -ce
+
use strict;
use warnings;
use English qw( -no_match_vars );
@@ -23,7 +25,7 @@ use Devel::Size qw(size total_size);
my $old_version;
my $new_version;
-my $infodir="$ENV{'HOME'}/.commit_info/" . `git config -l | grep remote.origin.url | sed 's|.*@||' | sed 's|:.*||'`;
+my $infodir = "$ENV{'HOME'}/.local/commit_info/" . `git config -l | grep remote.origin.url | sed 's|.*@||' | sed 's|:.*||'`;
chomp($infodir);
my $URL_WITH_USER;
my $SKIP_GERRIT_CHECK;
@@ -41,106 +43,275 @@ Main();
sub Main {
check_arguments();
- my %submitters = ();
- my %authors = ();
- my %owners = ();
- my %reviewers = ();
- my %author_added = ();
- my %author_removed = ();
- my $total_added = 0;
- my $total_removed = 0;
- my $number_of_commits = 0;
- my $number_of_submitters = 0;
- my $submit_epoch = "";
- my $first_submit_epoch = "";
- if (!$URL_WITH_USER) {
- get_user()
+ my %submitters = ();
+ my %authors = ();
+ my %owners = ();
+ my %reviewers = ();
+ my %commenters = ();
+ my %author_added = ();
+ my %author_removed = ();
+ my $total_added = 0;
+ my $total_removed = 0;
+ my $number_of_commits = 0;
+ my $number_of_submitters = 0;
+ my $submit_epoch = "";
+ my $first_submit_epoch = "";
+ my $patches_over_100_lines = 0;
+ my $total_lines_large_patches = 0;
+ my %email_addresses = (
+ 'Kacper Stojek' => 'kacper.stojek@3mdeb.com',
+ 'Damien Zammit' => 'damien@zamaudio.com',
+ 'Pavel Sayekat' => 'pavelsayekat@gmail.com',
+ 'Lance Zhao' => 'lance.zhao@gmail.com',
+ );
+
+ my %aliases = (
+ ' Felix Singer' => 'Felix Singer',
+ 'Abhay kumar' => 'Abhay Kumar',
+ 'AlexandruX Gagniuc' => 'Alexandru Gagniuc',
+ 'Anish K. Patel' => 'Anish K Patel',
+ 'Bao Zheng' => 'Zheng Bao',
+ 'Bernhard M. Wiedemann' => 'Bernhard M. Wiedermann',
+ 'Björn Busse' => 'Bjarn Busse',
+ 'BryantOu' => 'Bryant Ou',
+ 'Chen Wisley' => 'Wisley Chen',
+ 'Cheng-Yi Chiang' => 'Jimmy Cheng-Yi Chiang',
+ 'Chris Ching (using chromium account)' => 'Chris Ching,',
+ 'ChromeOS Developer' => 'Dave Parker',
+ 'Cristi M' => 'Cristian Magherusan-Stanciu',
+ 'Cristian M?gheru?an-Stanciu' => 'Cristian Magherusan-Stanciu',
+ 'Cristian MÄgheruÈan-Stanciu' => 'Cristian Magherusan-Stanciu',
+ 'Cristian MÄgheruÈan-Stanciu' => 'Cristian Magherusan-Stanciu',
+ 'DAWEI CHIEN' => 'Dawei Chien',
+ 'efdesign98' => 'Frank Vibrans',
+ 'Eugene D. Myers' => 'Eugene Myers',
+ 'Frank Vibrans III' => 'Frank Vibrans',
+ 'frank vibrans' => 'Frank Vibrans',
+ 'Frank.Vibrans' => 'Frank Vibrans',
+ 'FrankChu' => 'Frank Chu',
+ 'garmin chang' => 'Garmin Chang',
+ 'Garmin.Chang' => 'Garmin Chang',
+ 'hannahwilliams2' => 'Hannah Williams',
+ 'HAOUAS Elyes' => 'Elyes Haouas',
+ 'Harshapriya N' => 'Harsha Priya',
+ 'Hsuan-ting Chen' => 'Hsuan Ting Chen',
+ 'Iru Cai (vimacs)' => 'Iru Cai',
+ 'Jérémy Compostella' => 'Jeremy Compostella',
+ 'Jérémy Compostella' => 'Jeremy Compostella',
+ 'JG Poxu' => 'Po Xu',
+ 'JonathonHall-Purism' => 'Jonathon Hall',
+ 'Karthikeyan Ramasubramanian' => 'Karthik Ramasubramanian',
+ 'Kerry She' => 'Kerry Sheh',
+ 'kewei.xu' => 'kewei xu',
+ 'Kumar, Gomathi' => 'Gomathi Kumar',
+ 'Kyösti Mälkki' => 'Kyösti Mälkki',
+ 'Kyösti Mälkki' => 'Kyösti Mälkki',
+ 'Marcello Sylvester Bauer' => 'Marcello Sylvester Bauer',
+ 'Martin L Roth' => 'Martin Roth',
+ 'Martin Roth - Personal' => 'Martin Roth',
+ 'Matt Ziegelbaum' => 'Matthew Ziegelbaum',
+ 'mengqi.zhang' => 'Mengqi Zhang',
+ 'mrnuke' => 'Alexandru Gagniuc',
+ 'Nina-CM Wu' => 'Nina Wu',
+ 'ot_zhenguo.li' => 'Zhenguo Li',
+ 'Patrick Georgi patrick.georgi' => 'Patrick Georgi',
+ 'Patrick Georgi patrick' => 'Patrick Georgi',
+ 'Pavlushka' => 'Pavel Sayekat',
+ 'Ravi Kumar Bokka' => 'Ravi Kumar',
+ 'Ravi kumar' => 'Ravi Kumar',
+ 'Ravi Sarawadi' => 'Ravishankar Sarawadi',
+ 'ravindr1' => 'Ravindra',
+ 'Ravindra N' => 'Ravindra',
+ 'Ricardo Ribalda Delgado' => 'Ricardo Ribalda',
+ 'ron minnich' => 'Ron Minnich',
+ 'Ronald G. Minnich' => 'Ron Minnich',
+ 'samrab' => 'Sudheer Amrabadi',
+ 'SANTHOSH JANARDHANA HASSAN' => 'Santhosh Janardhana Hassan',
+ 'semihalf-czapiga-jakub' => 'Jakub Czapiga',
+ 'Seunghwan Kim' => 'SH Kim',
+ 'Sooi, Li Cheng' => 'Li Cheng Sooi',
+ 'Stefan Reinauerstepan' => 'Stefan Reinauer',
+ 'stepan' => 'Stefan Reinauer',
+ 'Swift Geek (Sebastian Grzywna)' => 'Sebastian "Swift Geek" Grzywna',
+ 'Sylvain "ythier" Hitier' => 'Sylvain Hitier',
+ 'Thomas Gstädtner' => 'Thomas Gstaedtner',
+ 'UwePoeche' => 'Uwe Poeche',
+ 'UwePoeche' => 'Uwe Poeche',
+ 'Varshit Pandya' => 'Varshit B Pandya',
+ 'Wayne3 Wang' => 'Wayne Wang',
+ 'Wayne3_Wang' => 'Wayne Wang',
+ 'Xi Chen' => 'Xixi Chen',
+ 'Yu-Hsuan Hsu' => 'Yu-hsuan Hsu',
+ 'zbao' => 'Zheng Bao',
+ 'Zheng Bao zheng.bao' => 'Zheng Bao',
+ 'zhiyong tao' => 'Zhiyong Tao',
+ 'Дмитрий Понаморев' => 'Dmitry Ponamorev',
+ );
+
+ if ( !$URL_WITH_USER ) {
+ get_user();
}
- # make sure the versions exist
+ print "Saving data to $infodir\n";
+
+ # Make sure the versions exist
check_versions();
- #fetch patches if needed. Get ids of first and last commits
- my @commits = `git log --pretty=%h "$old_version..$new_version" 2>/dev/null`;
+ # Fetch patches if needed. Get ids of first and last commits
+ my @commits = `git log --pretty=%H "$old_version..$new_version" 2>/dev/null`;
get_commits(@commits);
- my $last_commit_id = $commits[0];
- my $first_commit_id = $commits[@commits - 1];
+ my $last_commit_id = $commits[0];
+ my $first_commit_id = $commits[ @commits - 1 ];
chomp $last_commit_id;
chomp $first_commit_id;
print "Statistics from commit $first_commit_id to commit $last_commit_id\n";
- print "Patch, Date, Owner, Author, Submitter, Inserted lines, Deleted lines, Subject, Reviewers\n";
+ print "Patch, Date, Owner, Author, Submitter, Inserted lines, Deleted lines, Subject, Reviewers, Commenters\n";
- #loop through all commits
+ # Loop through all commits
for my $commit_id (@commits) {
$commit_id =~ s/^\s+|\s+$//g;
- my $submitter = "";
- my %patch_reviewers = ();
+ my $submitter = "";
+ my %patch_reviewers = ();
+ my %patch_commenters = ();
my $info;
my $owner;
my $author;
my $author_email;
my $inserted_lines = 0;
- my $deleted_lines = 0;
+ my $deleted_lines = 0;
my $subject;
$number_of_commits++;
print "\"$commit_id\", ";
- #read the data file for the current commit
- if (-f "$infodir/$commit_id" && -s "$infodir/$commit_id" > 20) {
+ # Read the data file for the current commit
+ if ( -f "$infodir/$commit_id" && -s "$infodir/$commit_id" > 20 ) {
open( my $HANDLE, "<", "$infodir/$commit_id" ) or die "Error: could not open file '$infodir/$commit_id'\n";
$info = <$HANDLE>;
close $HANDLE;
my $commit_info = JSON::Util->decode($info);
- #get the easy data
+ # Get the easy data
$owner = $commit_info->{'owner'}{'name'};
- if (! $owner) {
+ if ( !$owner ) {
$owner = $commit_info->{'owner'}{'username'};
}
- if (! $owner) {
- $owner = "";
+ if ( !$owner ) {
+ $owner = "-";
+ }
+ if ( $owner && exists( $aliases{$owner} ) ) {
+ $owner = $aliases{$owner};
}
+
$author = $commit_info->{'currentPatchSet'}{'author'}{'name'};
- $author_email = $commit_info->{'currentPatchSet'}{'author'}{'email'};
- if (! $author) {
+ if ( $author && exists( $aliases{$author} ) ) {
+ $author = $aliases{$author};
+ }
+ if ( !$author ) {
$author = $commit_info->{'currentPatchSet'}{'author'}{'username'};
}
-
+ $author_email = $commit_info->{'currentPatchSet'}{'author'}{'email'};
$inserted_lines = $commit_info->{'currentPatchSet'}{'sizeInsertions'};
- $deleted_lines = $commit_info->{'currentPatchSet'}{'sizeDeletions'};
- $subject = $commit_info->{'subject'};
+ $deleted_lines = $commit_info->{'currentPatchSet'}{'sizeDeletions'};
+ $subject = $commit_info->{'subject'};
#get the patch's submitter
my $approvals = $commit_info->{'currentPatchSet'}{'approvals'};
for my $approval (@$approvals) {
- if ($approval->{'type'} eq "SUBM") {
+ if ( $approval->{'type'} eq "SUBM" ) {
$submit_epoch = $approval->{'grantedOn'};
- $submitter = $approval->{'by'}{'name'};
+ $submitter = $approval->{'by'}{'name'};
+ if ( exists( $aliases{$submitter} ) ) {
+ $submitter = $aliases{$submitter};
+ }
}
}
- #get all the reviewers for all patch revisions
+ # Get all the commenters for all patch revisions
+ my $comments = $commit_info->{'comments'};
+ for my $comment (@$comments) {
+ my $commenter;
+ if ( $comment->{'reviewer'}{'username'} ) {
+ if ( $comment->{'reviewer'}{'username'} eq "jenkins" ) {
+ next;
+ }
+ if ( $comment->{'reviewer'}{'username'} eq "hardwaretestrobot" ) {
+ next;
+ }
+ if ( $comment->{'reviewer'}{'username'} eq "raptor-automated-test" ) {
+ next;
+ }
+ }
+
+ if ( $comment->{'reviewer'}{'name'} ) {
+ if ( $comment->{'reviewer'}{'name'} eq "Gerrit Code Review" ) {
+ next;
+ }
+ }
+ if ( $comment->{'message'} ) {
+ if ( $comment->{'message'} =~ "successfully cherry-picked" ) {
+ next;
+ }
+ if ( $comment->{'message'} =~ ": Code-Review" ) {
+ next;
+ }
+ if ( $comment->{'message'} =~ "Uploaded patch set" ) {
+ next;
+ }
+ }
+
+ if ( !$commenter ) {
+ $commenter = $comment->{'reviewer'}{'name'};
+ if ( $commenter && exists( $aliases{$commenter} ) ) {
+ $commenter = $aliases{$commenter};
+ }
+ }
+ if ( !$commenter ) {
+ $commenter = $comment->{'reviewer'}{'username'};
+ if ( $commenter && exists( $aliases{$commenter} ) ) {
+ $commenter = $aliases{$commenter};
+ }
+ }
+ if ( $commenter && $author && $commenter eq $author ) {
+ next;
+ }
+ if ($commenter) {
+ if ( $commenter && exists $patch_commenters{$commenter} ) {
+ $patch_commenters{$commenter}++;
+ } else {
+ $patch_commenters{$commenter} = 1;
+ }
+ }
+ }
+
+ # Get all the reviewers for all patch revisions
my $patchsets = $commit_info->{'patchSets'};
for my $patch (@$patchsets) {
- if (! $author) {
+ if ( !$author ) {
$author = $patch->{'author'}{'name'};
+ if ( $author && exists( $aliases{$author} ) ) {
+ $author = $aliases{$author};
+ }
}
+
my $approvals = $patch->{'approvals'};
for my $approval (@$approvals) {
- if ( (! $submitter) && ($approval->{'type'} eq "SUBM")) {
+ if ( ( !$submitter ) && ( $approval->{'type'} eq "SUBM" ) ) {
$submit_epoch = $approval->{'grantedOn'};
- $submitter = $approval->{'by'}{'name'};
+ $submitter = $approval->{'by'}{'name'};
+ if ( $submitter && exists( $aliases{$submitter} ) ) {
+ $submitter = $aliases{$submitter};
+ }
}
- if ($approval->{'type'} eq "Code-Review") {
+ if ( $approval->{'type'} eq "Code-Review" ) {
my $patch_reviewer = $approval->{'by'}{'name'};
if ($patch_reviewer) {
- if (exists $patch_reviewers{$patch_reviewer}) {
+ if ( exists $patch_reviewers{$patch_reviewer} ) {
$patch_reviewers{$patch_reviewer}++;
} else {
$patch_reviewers{$patch_reviewer} = 1;
@@ -151,24 +322,36 @@ sub Main {
}
} else {
- # get the info from git
+
+ # Get the info from git
my $logline = `git log --pretty="%ct@@@%s@@@%an@@@%aE@@@%cn" $commit_id^..$commit_id --`;
$logline =~ m/^(.*)@@@(.*)@@@(.*)@@@(.*)@@@(.*)\n/;
- ($submit_epoch, $subject, $author, $author_email, $submitter) = ($1, $2, $3, $4, $5);
+ ( $submit_epoch, $subject, $author, $author_email, $submitter ) = ( $1, $2, $3, $4, $5 );
+ if ( exists( $aliases{$author} ) ) {
+ $author = $aliases{$author};
+ }
$owner = $author;
+
+ if ( $submitter && exists( $aliases{$submitter} ) ) {
+ $submitter = $aliases{$submitter};
+ }
+
$logline = `git log --pretty= --shortstat $commit_id^..$commit_id --`;
- if ($logline =~ m/\s+(\d+)\s+insertion/) {
+ if ( $logline =~ m/\s+(\d+)\s+insertion/ ) {
$inserted_lines = $1;
}
- if ($logline =~ m/\s+(\d+)\s+deletion/) {
+ if ( $logline =~ m/\s+(\d+)\s+deletion/ ) {
$deleted_lines = $1 * -1;
}
my @loglines = `git log $commit_id^..$commit_id -- | grep '\\sReviewed-by:'`;
- for my $line (@loglines){
- if ($line =~ m/.*:\s+(.*)\s</) {
+ for my $line (@loglines) {
+ if ( $line =~ m/.*:\s+(.*)\s</ ) {
my $patch_reviewer = $1;
+ if ( exists( $aliases{$patch_reviewer} ) ) {
+ $patch_reviewer = $aliases{$patch_reviewer};
+ }
if ($patch_reviewer) {
- if (exists $patch_reviewers{$patch_reviewer}) {
+ if ( exists $patch_reviewers{$patch_reviewer} ) {
$patch_reviewers{$patch_reviewer}++;
} else {
$patch_reviewers{$patch_reviewer} = 1;
@@ -181,155 +364,230 @@ sub Main {
# Not entirely certain why this is needed, but for a number of patches have been submitted
# the submit time in gerrit is set to April 9, 2015.
- if ($submit_epoch == 1428586219){
+ if ( $submit_epoch == 1428586219 ) {
my $logline = `git log --pretty="%ct" $commit_id^..$commit_id --`;
$logline =~ m/^(.*)\n/;
$submit_epoch = $1;
}
- #add the count and owner to the submitter hash
- if (exists $submitters{$submitter}) {
- $submitters{$submitter}++;
+ # Add the count and owner to the submitter hash
+ if ( $submitter && exists $submitters{$submitter} && exists $submitters{$submitter}{count} ) {
+ $submitters{$submitter}{count}++;
} else {
- $submitters{$submitter} = 1;
+ $submitters{$submitter}{count} = 1;
$number_of_submitters++;
+ $submitters{$submitter}{"self"} = 0;
+ $submitters{$submitter}{others} = 0;
+ $submitters{$submitter}{name} = $submitter;
+ }
+
+ if ( $submitter eq $author ) {
+ $submitters{$submitter}{"self"}++;
+ } else {
+ $submitters{$submitter}{others}++;
}
- #create a readable date
- my $dt = DateTime->from_epoch(epoch => $submit_epoch);
- $dt->set_time_zone( 'Europe/Paris' );
- my $submit_time = $dt->strftime('%Y/%m/%d %H:%M:%S');
- if (!$first_submit_epoch) {
+ # Create a readable date
+ my $dt = DateTime->from_epoch( epoch => $submit_epoch );
+ $dt->set_time_zone('Europe/Paris');
+ my $submit_time = $dt->strftime('%Y/%m/%d');
+ if ( !$first_submit_epoch ) {
$first_submit_epoch = $submit_epoch;
}
- #create the list of reviewers to print
+ # Create the list of commenters to print
+ my $commenterlist = "";
+ foreach my $commenter ( keys %patch_commenters ) {
+ if ( $commenter && exists( $aliases{$commenter} ) ) {
+ $commenter = $aliases{$commenter};
+ }
+
+ if ( $commenterlist eq "" ) {
+ $commenterlist = $commenter;
+ } else {
+ $commenterlist .= ", $commenter";
+ }
+
+ if ( $commenter && exists $commenters{$commenter} ) {
+ $commenters{$commenter}++;
+ } else {
+ $commenters{$commenter} = 1;
+ }
+ }
+ if ( !$commenterlist ) {
+ $commenterlist = "-";
+ }
+
+ # Create the list of reviewers to print
my $reviewerlist = "";
- foreach my $reviewer (keys %patch_reviewers) {
- if ($reviewerlist eq "") {
+ foreach my $reviewer ( keys %patch_reviewers ) {
+ if ( exists( $aliases{$reviewer} ) ) {
+ $reviewer = $aliases{$reviewer};
+ }
+
+ if ( $reviewerlist eq "" ) {
$reviewerlist = $reviewer;
} else {
$reviewerlist .= ", $reviewer";
}
- if (exists $reviewers{$reviewer}) {
+ if ( $reviewer && exists $reviewers{$reviewer} ) {
$reviewers{$reviewer}++;
} else {
$reviewers{$reviewer} = 1;
}
}
- if (! $reviewerlist) {
- $reviewerlist = "-"
+ if ( !$reviewerlist ) {
+ $reviewerlist = "-";
}
if ($print_commit_list) {
- print "$submit_time, $owner, $author, $submitter, $inserted_lines, $deleted_lines, \"$subject\", \"$reviewerlist\"\n";
+ print "$submit_time, $owner, $author, $submitter, $inserted_lines, $deleted_lines, \"$subject\", \"$reviewerlist\" , \"$commenterlist\"\n";
} else {
print "$number_of_commits\n";
}
$total_added += $inserted_lines;
+ if ( $inserted_lines - $deleted_lines > 100 ) {
+ $patches_over_100_lines++;
+ $total_lines_large_patches += $inserted_lines;
+ }
$total_removed += $deleted_lines;
- if (exists $owners{$owner}) {
+ if ( exists $owners{$owner} ) {
$owners{$owner}++;
} else {
$owners{$owner} = 1;
}
- if (exists $authors{$author}{"num"}) {
+ if ( $author && exists $authors{$author}{"num"} ) {
$authors{$author}{"num"}++;
- $author_added{$author} += $inserted_lines;
+ $author_added{$author} += $inserted_lines;
$author_removed{$author} += $deleted_lines;
- $authors{$author}{"earliest_commit"}=$submit_time;
+ $authors{$author}{"earliest_commit"} = $submit_time;
} else {
- $authors{$author}{"num"} = 1;
- $authors{$author}{"latest_commit"}=$submit_time;
- $authors{$author}{"earliest_commit"}=$submit_time;
- $author_added{$author} = $inserted_lines;
- $author_removed{$author} = $deleted_lines;
+ $authors{$author}{"num"} = 1;
+ $authors{$author}{"latest_commit"} = $submit_time;
+ $authors{$author}{"earliest_commit"} = $submit_time;
+ $author_added{$author} = $inserted_lines;
+ $author_removed{$author} = $deleted_lines;
}
- if (! exists $authors{$author}{email} && $author_email) {
- $authors{$author}{email} = "$author_email";
+ if ( $author && ( !exists $authors{$author}{email} || $authors{$author}{email} eq "-" ) ) {
+ if ($author_email) {
+ $authors{$author}{email} = "$author_email";
+ } elsif ( exists $email_addresses{$author} ) {
+ $authors{$author}{email} = $email_addresses{$author};
+ }
}
}
- my $Days = ($first_submit_epoch - $submit_epoch) / 86400;
- if (($first_submit_epoch - $submit_epoch) % 86400) {
+ my $Days = ( $first_submit_epoch - $submit_epoch ) / 86400;
+ if ( ( $first_submit_epoch - $submit_epoch ) % 86400 ) {
$Days += 1;
}
- print "- Total Commits: $number_of_commits\n";
+ print "\n- Total Commits: $number_of_commits\n";
printf "- Average Commits per day: %.2f\n", $number_of_commits / $Days;
print "- Total lines added: $total_added\n";
+ printf "- Average lines added per commit: %.2f\n", $total_added / $number_of_commits;
+ print "- Number of patches adding more than 100 lines: $patches_over_100_lines\n";
+ printf "- Average lines added per small commit: %.2f\n", ( $total_added - $total_lines_large_patches ) / ( $number_of_commits - $patches_over_100_lines );
+
print "- Total lines removed: $total_removed\n";
- print "- Total difference: " . ($total_added + $total_removed) . "\n\n";
+ printf "- Average lines removed per commit: %.2f\n", $total_removed / $number_of_commits;
+ print "- Total difference between added and removed: " . ( $total_added - $total_removed ) . "\n\n";
print "=== Authors - Number of commits ===\n";
+ printf "%-30s ,%5s ,%5s ,%6s ,%6s , %-52s ,%6s, %-19s , %s\n", "Author", "Ptchs", "Revws", "Cmnts", "Sbmts", "Email", "Prcnt", "Last commit", "Earliest_commit";
+
my $number_of_authors = 0;
- foreach my $author (sort { $authors{$b}{num} <=> $authors{$a}{num} } (keys %authors) ) {
- if (! exists $authors{$author}{"email"}) {
- $authors{$author}{"email"} = "-";
- }
- printf "%-25s %5d %-40s (%2.2f%%) {%s / %s}\n",$author, $authors{$author}{"num"}, $authors{$author}{"email"}, $authors{$author}{"num"} / $number_of_commits * 100, $authors{$author}{"latest_commit"}, $authors{$author}{"earliest_commit"};
+ foreach my $author ( sort { $authors{$b}{num} <=> $authors{$a}{num} } ( keys %authors ) ) {
+ my $submissions = 0;
+ if ( $author && exists $submitters{$author} ) {
+ $submissions = $submitters{$author}{count};
+ }
+ my $review_count = 0;
+ if ( $author && exists $reviewers{$author} ) {
+ $review_count = $reviewers{$author};
+ }
+
+ my $comment_count = 0;
+ if ( $author && exists $commenters{$author} ) {
+ $comment_count = $commenters{$author};
+ }
+
+ if ( $author && !exists $authors{$author}{"email"} ) {
+ $authors{$author}{"email"} = "-";
+ }
+
+ printf "%-30s ,%5d ,%5d ,%6d ,%6d , %-52s ,%5.2f%%, %s , %s\n", $author, $authors{$author}{"num"}, $review_count,
+ $comment_count, $submissions, $authors{$author}{"email"}, $authors{$author}{"num"} / $number_of_commits * 100,
+ $authors{$author}{"latest_commit"}, $authors{$author}{"earliest_commit"};
$number_of_authors++;
}
print "Total Authors: $number_of_authors\n\n";
print "=== Authors - Lines added ===\n";
- foreach my $author (sort { $author_added{$b} <=> $author_added{$a} } (keys %author_added) ) {
- if ($author_added{$author}) {
- printf "%-25s %5d (%2.3f%%)\n",$author, $author_added{$author}, $author_added{$author} / $total_added * 100;
+ foreach my $author ( sort { $author_added{$b} <=> $author_added{$a} } ( keys %author_added ) ) {
+ if ( $author_added{$author} ) {
+ printf "%-30s, %10d, %2.3f%%\n", $author, $author_added{$author}, $author_added{$author} / $total_added * 100;
}
}
print "\n";
print "=== Authors - Lines removed ===\n";
- foreach my $author (sort { $author_removed{$a} <=> $author_removed{$b} } (keys %author_removed) ) {
- if ($author_removed{$author}) {
- printf "%-25s %5d (%2.3f%%)\n",$author,$author_removed{$author} * -1, $author_removed{$author} / $total_removed * 100;
+ foreach my $author ( sort { $author_removed{$b} <=> $author_removed{$a} } ( keys %author_removed ) ) {
+ if ( $author_removed{$author} ) {
+ printf "%-30s, %10d, %6.3f%%\n", $author, $author_removed{$author} * -1, $author_removed{$author} / $total_removed * 100;
}
}
print "\n";
print "=== Reviewers - Number of patches reviewed ===\n";
my $number_of_reviewers = 0;
- foreach my $reviewer (sort { $reviewers{$b} <=> $reviewers{$a} } (keys %reviewers) ) {
- printf "%-25s %5d (%2.3f%%)\n",$reviewer, $reviewers{$reviewer}, $reviewers{$reviewer} / $number_of_commits * 100;
+ foreach my $reviewer ( sort { $reviewers{$b} <=> $reviewers{$a} } ( keys %reviewers ) ) {
+ printf "%-30s, %6d, %6.3f%%\n", $reviewer, $reviewers{$reviewer}, $reviewers{$reviewer} / $number_of_commits * 100;
$number_of_reviewers++;
}
print "Total Reviewers: $number_of_reviewers\n\n";
print "=== Submitters - Number of patches submitted ===\n";
- foreach my $submitter (sort { $submitters{$b} <=> $submitters{$a} } (keys %submitters) ) {
- printf "%-25s %5d (%2.3f%%)\n",$submitter, $submitters{$submitter}, $submitters{$submitter} / $number_of_commits * 100;
+ printf "%-30s, %6s, %7s, %6s, %7s, %6s, %7s\n", "Name", "#", "total%", "Own", "own%", "Other", "other%";
+ foreach my $submitter ( sort { $submitters{$b}{count} <=> $submitters{$a}{count} } ( keys %submitters ) ) {
+ printf "%-30s, % 6d, %6.3f%%, %6d, %6.2f%%, %6d, %6.2f%%\n",
+ $submitter,
+ $submitters{$submitter}{count},
+ $submitters{$submitter}{count} / $number_of_commits * 100,
+ $submitters{$submitter}{"self"},
+ $submitters{$submitter}{"self"} / $submitters{$submitter}{count} * 100,
+ $submitters{$submitter}{others}, $submitters{$submitter}{others} / $submitters{$submitter}{count} * 100;
}
print "Total Submitters: $number_of_submitters\n\n";
print "Commits, Ave, Added, Removed, Diff, Authors, Reviewers, Submitters\n";
- printf "$number_of_commits, %.2f, $total_added, $total_removed, " . ($total_added + $total_removed) . ", $number_of_authors, $number_of_reviewers, $number_of_submitters\n", $number_of_commits / $Days;
+ printf "$number_of_commits, %.2f, $total_added, $total_removed, " . ( $total_added + $total_removed ) . ", $number_of_authors, $number_of_reviewers, $number_of_submitters\n",
+ $number_of_commits / $Days;
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
sub check_versions {
`git cat-file -e $old_version^{commit} 2>/dev/null`;
- if (${^CHILD_ERROR_NATIVE}){
+ if ( ${^CHILD_ERROR_NATIVE} ) {
print "Error: Old version ($old_version) does not exist.\n";
exit 1;
}
`git cat-file -e $new_version^{commit} 2>/dev/null`;
- if (${^CHILD_ERROR_NATIVE}){
+ if ( ${^CHILD_ERROR_NATIVE} ) {
print "Error: New version ($new_version) does not exist.\n";
exit 1;
}
}
#-------------------------------------------------------------------------------
-#-------------------------------------------------------------------------------
sub get_user {
- my $url=`git config -l | grep remote.origin.url`;
- if ($url =~ /.*url=ssh:\/\/(\w+@[a-zA-Z][a-zA-Z0-9\.]+:\d+)/)
- {
+ my $url = `git config -l | grep remote.origin.url`;
+
+ if ( $url =~ /.*url=ssh:\/\/(\w+@[a-zA-Z][a-zA-Z0-9\.]+:\d+)(\/\w+)*/ ) {
$URL_WITH_USER = $1;
} else {
print "Error: Could not get a ssh url with a username from gitconfig.\n";
@@ -341,44 +599,44 @@ sub get_user {
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
sub get_commits {
- my @commits = @_;
+ my @commits = @_;
my $submit_time = "";
- if (defined $SKIP_GERRIT_CHECK) {
+ if ( defined $SKIP_GERRIT_CHECK && $SKIP_GERRIT_CHECK ) {
return;
}
- my $ssh = Net::OpenSSH->new("$URL_WITH_USER", );
- $ssh->error and die "Couldn't establish SSH connection to $URL_WITH_USER:". $ssh->error;
+ my $ssh = Net::OpenSSH->new( "$URL_WITH_USER", );
+ $ssh->error and die "Couldn't establish SSH connection to $URL_WITH_USER:" . $ssh->error;
print "Using URL: ssh://$URL_WITH_USER\n";
- if (! -d $infodir) {
- mkpath($infodir)
+ if ( !-d $infodir ) {
+ mkpath($infodir);
}
for my $commit_id (@commits) {
$commit_id =~ s/^\s+|\s+$//g;
$submit_time = "";
- my $gerrit_review;
+ my $gerrit_review;
- # Quit if we've reeached the last coreboot commit supporting these queries
- if ($commit_id =~ /^7309709/) {
+ # Look for last coreboot commit
+ if ( $commit_id eq "7309709742" ) {
last;
}
- if (-f "$infodir/$commit_id") {
+ if ( -f "$infodir/$commit_id" ) {
$gerrit_review = 1;
} else {
$gerrit_review = `git log $commit_id^..$commit_id | grep '\\sReviewed-on:\\s'`;
}
- if ($gerrit_review && $commit_id && (! -f "$infodir/$commit_id") ) {
+ if ( $gerrit_review && $commit_id && ( !-f "$infodir/$commit_id" ) ) {
print "Downloading $commit_id";
my @info = $ssh->capture("gerrit query --format=JSON --comments --files --current-patch-set --all-approvals --submit-records --dependencies commit:$commit_id");
$ssh->error and die "remote ls command failed: " . $ssh->error;
- my $commit_info = JSON::Util->decode($info[0]);
- my $rowcount = $commit_info->{'rowCount'};
- if (defined $rowcount && ($rowcount eq "0")) {
+ my $commit_info = JSON::Util->decode( $info[0] );
+ my $rowcount = $commit_info->{'rowCount'};
+ if ( defined $rowcount && ( $rowcount eq "0" ) ) {
print " - no gerrit commit for that id.\n";
open( my $HANDLE, ">", "$infodir/$commit_id" ) or die "Error: could not open file '$infodir/$commit_id'\n";
print $HANDLE "No gerrit commit";
@@ -388,13 +646,13 @@ sub get_commits {
my $approvals = $commit_info->{'currentPatchSet'}{'approvals'};
for my $approval (@$approvals) {
- if ($approval->{'type'} eq "SUBM") {
- $submit_time = $approval->{'grantedOn'}
+ if ( $approval->{'type'} eq "SUBM" ) {
+ $submit_time = $approval->{'grantedOn'};
}
}
- my $dt="";
+ my $dt = "";
if ($submit_time) {
- $dt = DateTime->from_epoch(epoch => $submit_time);
+ $dt = DateTime->from_epoch( epoch => $submit_time );
} else {
print " - no submit time for that id.\n";
open( my $HANDLE, ">", "$infodir/$commit_id" ) or die "Error: could not open file '$infodir/$commit_id'\n";
@@ -408,9 +666,9 @@ sub get_commits {
print $HANDLE $info[0];
close $HANDLE;
- $dt->set_time_zone( 'Europe/Paris' );
+ $dt->set_time_zone('Europe/Paris');
print " - submit time: " . $dt->strftime('%Y/%m/%d %H:%M:%S') . "\n";
- } elsif ($commit_id && (! -f "$infodir/$commit_id")) {
+ } elsif ( $commit_id && ( !-f "$infodir/$commit_id" ) ) {
print "No gerrit commit for $commit_id\n";
open( my $HANDLE, ">", "$infodir/$commit_id" ) or die "Error: could not open file '$infodir/$commit_id'\n";
print $HANDLE "No gerrit commit";
@@ -426,16 +684,17 @@ sub get_commits {
sub check_arguments {
my $show_usage = 0;
GetOptions(
- 'help|?' => sub { usage() },
- 'url|u=s' => \$URL_WITH_USER,
- 'skip|s' => \$SKIP_GERRIT_CHECK,
+ 'help|?' => sub { usage() },
+ 'url|u=s' => \$URL_WITH_USER,
+ 'skip|s' => \$SKIP_GERRIT_CHECK,
);
+
# strip ssh:// from url if passed in.
- if (defined $URL_WITH_USER) {
+ if ( defined $URL_WITH_USER ) {
$URL_WITH_USER =~ s|ssh://||;
}
if (@ARGV) {
- ($old_version, $new_version) = @ARGV;
+ ( $old_version, $new_version ) = @ARGV;
} else {
usage();
}