element-web/scripts/issues-burndown.pl

137 lines
4.8 KiB
Perl
Raw Normal View History

2016-03-30 22:25:18 +02:00
#!/usr/bin/env perl
use warnings;
use strict;
use Net::GitHub;
2017-05-07 20:34:05 +02:00
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
2016-03-30 22:25:18 +02:00
my $gh = Net::GitHub->new(
2017-05-07 20:34:05 +02:00
login => 'ara4n', pass => read_password("github password: "),
2016-03-30 22:25:18 +02:00
);
2023-12-12 11:31:44 +01:00
$gh->set_default_user_repo('element-hq', 'element-web');
2016-03-30 22:25:18 +02:00
2017-05-07 20:34:05 +02:00
#my @issues = $gh->issue->repos_issues({ state => 'all', milestone => 3 });
my @issues = $gh->issue->repos_issues({ state => 'all' });
2016-03-30 22:25:18 +02:00
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 = {};
2017-05-07 20:34:05 +02:00
my $now = Time::Moment->now;
2016-03-30 22:25:18 +02:00
foreach my $issue (@issues) {
next if ($issue->{pull_request});
2017-05-07 20:34:05 +02:00
2016-03-30 22:25:18 +02:00
# 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";
2017-05-07 20:34:05 +02:00
my $start = Time::Moment->from_string($issue->{created_at});
2016-03-30 22:25:18 +02:00
do {
2017-05-07 20:34:05 +02:00
my $ymd = $start->strftime('%F');
2016-03-30 22:25:18 +02:00
$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 }->{ $_ }++;
}
2017-05-07 20:34:05 +02:00
$start = $start->plus_days(1);
# print STDERR "^";
} while ($start->compare($now) < 0);
2016-03-30 22:25:18 +02:00
if ($state eq 'closed') {
2017-05-07 20:34:05 +02:00
my $end = Time::Moment->from_string($issue->{closed_at});
2016-03-30 22:25:18 +02:00
do {
2017-05-07 20:34:05 +02:00
my $ymd = $end->strftime('%F');
2016-03-30 22:25:18 +02:00
$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 }->{ $_ }++;
}
2017-05-07 20:34:05 +02:00
$end = $end->plus_days(1);
} while ($end->compare($now) < 0);
# print STDERR "v";
2016-03-30 22:25:18 +02:00
}
2017-05-07 20:34:05 +02:00
# print STDERR "\n";
2016-03-30 22:25:18 +02:00
}
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";
}