You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.8 KiB
136 lines
4.8 KiB
#!/usr/bin/env perl |
|
|
|
use warnings; |
|
use strict; |
|
|
|
use Net::GitHub; |
|
use Time::Moment; |
|
use Term::ReadPassword; |
|
|
|
# This version of the script emits the cumulative number of bugs, split into open & closed |
|
# suitable for drawing the 'top' and 'bottom' of a burndown graph. |
|
# |
|
# N.B. this doesn't take into account issues changing priority over time, but only their most recent priority. |
|
# |
|
# If you want instead the number of open issues on a given day, then look at issues-no-state.pl |
|
|
|
my $gh = Net::GitHub->new( |
|
login => 'ara4n', pass => read_password("github password: "), |
|
); |
|
|
|
$gh->set_default_user_repo('vector-im', 'element-web'); |
|
|
|
#my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 }); |
|
my @issues = $gh->issue->repos_issues({ state => 'all' }); |
|
while ($gh->issue->has_next_page) { |
|
push @issues, $gh->issue->next_page; |
|
} |
|
|
|
# we want: |
|
# day by day: |
|
# split by { open, closed } |
|
# split by { bug, feature, neither } |
|
# each split by { p1, p2, p3, p4, p5, unprioritised } <- priority |
|
# each split by { minor, major, critical, cosmetic, network, no-severity } <- severity |
|
# then split (with overlap between the groups) as { total, tag1, tag2, ... }? |
|
|
|
# ...and then all over again split by milestone. |
|
|
|
my $days = {}; |
|
my $schema = {}; |
|
my $now = Time::Moment->now; |
|
|
|
foreach my $issue (@issues) { |
|
next if ($issue->{pull_request}); |
|
|
|
# use Data::Dumper; |
|
# print STDERR Dumper($issue); |
|
|
|
my @label_list = map { $_->{name} } @{$issue->{labels}}; |
|
my $labels = {}; |
|
$labels->{$_} = 1 foreach (@label_list); |
|
$labels->{bug}++ if ($labels->{cosmetic} && !$labels->{bug} && !$labels->{feature}); |
|
|
|
my $extract_labels = sub { |
|
my $label = undef; |
|
foreach (@_) { |
|
$label ||= $_ if (delete $labels->{$_}); |
|
} |
|
return $label; |
|
}; |
|
|
|
my $state = $issue->{state}; |
|
my $type = &$extract_labels(qw(bug feature)) || "neither"; |
|
my $priority = &$extract_labels(qw(p1 p2 p3 p4 p5)) || "unprioritised"; |
|
my $severity = &$extract_labels(qw(minor major critical cosmetic network)) || "no-severity"; |
|
|
|
my $start = Time::Moment->from_string($issue->{created_at}); |
|
|
|
do { |
|
my $ymd = $start->strftime('%F'); |
|
|
|
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++; |
|
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ total }++; |
|
foreach (keys %$labels) { |
|
$days->{ $ymd }->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++; |
|
$schema->{ 'created' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++; |
|
} |
|
|
|
$start = $start->plus_days(1); |
|
# print STDERR "^"; |
|
} while ($start->compare($now) < 0); |
|
|
|
if ($state eq 'closed') { |
|
my $end = Time::Moment->from_string($issue->{closed_at}); |
|
do { |
|
my $ymd = $end->strftime('%F'); |
|
|
|
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++; |
|
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ total }++; |
|
foreach (keys %$labels) { |
|
$days->{ $ymd }->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++; |
|
$schema->{ 'resolved' }->{ $type }->{ $priority }->{ $severity }->{ $_ }++; |
|
} |
|
|
|
$end = $end->plus_days(1); |
|
} while ($end->compare($now) < 0); |
|
# print STDERR "v"; |
|
} |
|
|
|
# print STDERR "\n"; |
|
} |
|
|
|
print "day,"; |
|
foreach my $state (sort keys %{$schema}) { |
|
foreach my $type (grep { /^(bug|feature)$/ } sort keys %{$schema->{$state}}) { |
|
foreach my $priority (grep { /^(p1|p2)$/ } sort keys %{$schema->{$state}->{$type}}) { |
|
foreach my $severity (sort keys %{$schema->{$state}->{$type}->{$priority}}) { |
|
# foreach my $tag (sort keys %{$schema->{$state}->{$type}->{$priority}->{$severity}}) { |
|
# print "\"$type\n$priority\n$severity\n$tag\","; |
|
# } |
|
print "\"$state\n$type\n$priority\n$severity\","; |
|
} |
|
} |
|
} |
|
} |
|
print "\n"; |
|
|
|
foreach my $day (sort keys %$days) { |
|
print "$day,"; |
|
foreach my $state (sort keys %{$schema}) { |
|
foreach my $type (grep { /^(bug|feature)$/ } sort keys %{$schema->{$state}}) { |
|
foreach my $priority (grep { /^(p1|p2)$/ } sort keys %{$schema->{$state}->{$type}}) { |
|
foreach my $severity (sort keys %{$schema->{$state}->{$type}->{$priority}}) { |
|
# foreach my $tag (sort keys %{$schema->{$state}->{$type}->{$priority}->{$severity}}) { |
|
# print $days->{$day}->{$state}->{$type}->{$priority}->{$severity}->{$tag} || 0; |
|
# print ","; |
|
# } |
|
print $days->{$day}->{$state}->{$type}->{$priority}->{$severity}->{total} || 0; |
|
print ","; |
|
} |
|
} |
|
} |
|
} |
|
print "\n"; |
|
} |
|
|
|
|