Skip to content

Commit

Permalink
Implement contributor lookup for past releases
Browse files Browse the repository at this point in the history
Can be handy, like when fixing missing contributors for
R#2024 #2024
  • Loading branch information
zoffixznet committed Jul 5, 2018
1 parent 7a87b7f commit 8fee8d4
Showing 1 changed file with 93 additions and 13 deletions.
106 changes: 93 additions & 13 deletions tools/contributors.p6
@@ -1,16 +1,93 @@
#!/usr/bin/env perl6
use v6;

sub MAIN (
$last_release? is copy,
:$rakudo = '.',
:$doc = '../doc',
:$nqp = 'nqp',
:$moar = 'nqp/MoarVM',
:$roast = 't/spec',
my %*SUB-MAIN-OPTS = :named-anywhere;
# repeat named args in MAIN multies for nice USAGE messsages
constant RAK_REPO = '.';
constant DOC_REPO = '../doc';
constant NQP_REPO = 'nqp';
constant MOAR_REPO = 'nqp/MoarVM';
constant ROAST_REPO = 't/spec';

subset PathToRepo of Str where .so;

#|(past releases)
multi MAIN('for', 'release', $release,
PathToRepo :$rakudo = RAK_REPO,
PathToRepo :$doc = DOC_REPO,
PathToRepo :$nqp = NQP_REPO,
PathToRepo :$moar = MOAR_REPO,
PathToRepo :$roast = ROAST_REPO,
) {
# fetch all available tags, creating a list of hashes, each of which got
# a tag name and the date it was created on
my @releases = run(:out, :cwd($rakudo),
«git for-each-ref --sort=taggerdate
'--format=%(tag)|%(creatordate)' refs/tags»
).out.lines(:close).map(
*.split('|', :skip-empty).List
).grep(* == 2).map: { %(:tag(.head), :date(parse-date .tail)) };

~$release @releases».<tag> or die "Could not find $release in the list of"
~ " known releases: @releases».<tag>";

# create a map of tag => the tag immediatelly previous to it (temporally)
# this gives us the tag (along with that tag's date) for the previous rls
my %prev-rel = @releases.rotor(2 => -1).map: {.tail<tag> => .head };
%prev-rel{$release} or die "Could not figure out the tag for previous"
~ " release. Did you give me the first release ever? I can't handle it";

# gen committers using the dates of the tag we were asked for and the
# the tag that's previous to it, temporally, giving us the space of one rls
say join ', ', committers :since(%prev-rel{$release}<date>),
:until(@releases.first(*.<tag> eq $release)<date>),
:$rakudo, :$doc, :$nqp, :$moar, :$roast
}

#|(current release)
multi MAIN ($last_release? is copy,
PathToRepo :$rakudo = RAK_REPO,
PathToRepo :$doc = DOC_REPO,
PathToRepo :$nqp = NQP_REPO,
PathToRepo :$moar = MOAR_REPO,
PathToRepo :$roast = ROAST_REPO
) {
$last_release //= get-last-release-date-for $rakudo;
say join ', ', committers since => $last_release,
:$rakudo, :$doc, :$nqp, :$moar, :$roast
}

sub parse-date ($date) {
# newer gits have `--date` option to set format; I don't have such a new
# git, so do this business of extracting the date:
# 'Fri Feb 23 08:03:10 2018 +0200'
# Thu Feb 26 23:51:11 2009 -0600
if $date ~~ /
$<wkd>=\w**3 \s+ $<mon>=\w**3 \s+ $<day>=\d+ \s+
$<time>=[[\d**2 \:]**2 \d**2] \s+ $<year>=\d**4 \s+ $<offset>=\S+
/ {
my $month = <
NaM Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
>.antipairs.Hash{$<mon>};
DateTime.new:
"$<year>-$month.fmt("%02d")-$<day>.Str.fmt("%02d")T$<time>$<offset>";
}
elsif (try DateTime.new: $date) {
warn "Date `$date` is in unexpected format. Parsed it as $^res";
$^res
}
else { die "I don't know how to parse date $date" }
}

sub committers (
:$since!,
:$until,
:$rakudo = RAK_REPO,
:$doc = DOC_REPO,
:$nqp = NQP_REPO,
:$moar = MOAR_REPO,
:$roast = ROAST_REPO,
) {
# Check all the places with repos that may be applicable. Get all of the
# committers in that repo since the given date as commit ID => author pairs.
# Only keep the unique commit ID's (so that each author only gets credited
Expand All @@ -30,9 +107,10 @@ sub MAIN (
my @*CREDITS = ($rakudo, $doc, $nqp, $moar, $roast
.IO».child('CREDITS').grep(*.r.lines.flat;

say "Contributors to Rakudo since the release on $last_release:";
say "Contributors to Rakudo since $since"
~ (" until $until" with $until) ~ ":";
my @contributors = @repos.map({
|get-committers($_,$last_release)
|get-committers($_, $since, |($_ with $until))
}).unique(:as(*.key))».value.Bag.sort(-*.value.key;

for @contributors -> $name is rw {
Expand All @@ -46,7 +124,7 @@ sub MAIN (
}

}
say @contributors.join(', ');
@contributors
}

sub get-last-release-date-for ($rakudo-repo) {
Expand All @@ -63,19 +141,21 @@ sub get-last-release-date-for ($rakudo-repo) {
).out.slurp(:close).lines.head;
}

sub get-committers($repo, $since) {
sub get-committers($repo, $since, $until?) {
die "Expected a repo in `$repo` but did not find one"
unless $repo.IO.d && "$repo/.git".IO.d;

my @commits = run(:out, :cwd($repo),
<git log --since>, $since, '--pretty=format:%an|%cn|%H|%s'
<git log --since>, $since, |('--until', $_ with $until),
'--pretty=format:%an|%cn|%H|%s'
).out.lines.grep: ?*; # grep needed because of (Str) on empty pipe

@commits or warn qq:to/END/;
*********************** !! WARNING !! ********************
Did not find any commits in $repo since last release ($since).
Did not find any commits in directory `$repo`
between $since and {$until ?? $until !! "now"}
Are you sure it's current and is on the right branch?
*********************** !! WARNING !! ********************
Expand Down

0 comments on commit 8fee8d4

Please sign in to comment.