hydra/src/lib/Hydra/Helper/BuildDiff.pm
Pierre Bourdon 0ab357e435 jobset-eval: fix actions not showing up sometimes for new jobs
New jobs have their "new" status take precedence over them being
"failed" or "queued", which means actions that can act on "failed" or
"queued" jobs weren't shown to the user when they could only act on
"new" jobs.

(cherry picked from commit 9a4a5dd624)
2025-04-16 09:50:32 +10:00

104 lines
3.1 KiB
Perl

package Hydra::Helper::BuildDiff;
use utf8;
use strict;
use warnings;
our @ISA = qw(Exporter);
our @EXPORT = qw(
buildDiff
);
sub cmpBuilds {
my ($left, $right) = @_;
return $left->get_column('job') cmp $right->get_column('job')
|| $left->get_column('system') cmp $right->get_column('system')
}
sub buildDiff {
# $builds is the list of current builds
# $builds2 is the list of previous (to-be-compared-to) builds
my ($builds, $builds2) = @_;
$builds = [sort { cmpBuilds($a, $b) } @{$builds}];
$builds2 = [sort { cmpBuilds($a, $b) } @{$builds2}];
my $ret = {
stillSucceed => [],
stillFail => [],
nowSucceed => [],
nowFail => [],
new => [],
removed => [],
unfinished => [],
aborted => [],
# These summary counters cut across the categories to determine whether
# actions such as "Restart all failed" or "Bump queue" are available.
totalAborted => 0,
totalFailed => 0,
totalQueued => 0,
};
my $n = 0;
foreach my $build (@{$builds}) {
my $aborted = $build->finished != 0 && (
# aborted
$build->buildstatus == 3
# cancelled
|| $build->buildstatus == 4
# timeout
|| $build->buildstatus == 7
# log limit exceeded
|| $build->buildstatus == 10
);
my $d;
my $found = 0;
while ($n < scalar(@{$builds2})) {
my $build2 = @{$builds2}[$n];
my $d = cmpBuilds($build, $build2);
last if $d == -1;
if ($d == 0) {
$n++;
$found = 1;
if ($aborted) {
# do nothing
} elsif ($build->finished == 0 || $build2->finished == 0) {
push @{$ret->{unfinished}}, $build;
} elsif ($build->buildstatus == 0 && $build2->buildstatus == 0) {
push @{$ret->{stillSucceed}}, $build;
} elsif ($build->buildstatus != 0 && $build2->buildstatus != 0) {
push @{$ret->{stillFail}}, $build;
} elsif ($build->buildstatus == 0 && $build2->buildstatus != 0) {
push @{$ret->{nowSucceed}}, $build;
} elsif ($build->buildstatus != 0 && $build2->buildstatus == 0) {
push @{$ret->{nowFail}}, $build;
} else { die; }
last;
}
my $job_system = { job => $build2->get_column('job'), system => $build2->get_column('system') };
push @{$ret->{removed}}, $job_system;
$n++;
}
if ($aborted) {
push @{$ret->{aborted}}, $build;
} else {
push @{$ret->{new}}, $build if !$found;
}
if ($build->finished != 0 && $build->buildstatus != 0) {
if ($aborted) {
++$ret->{totalAborted};
} else {
++$ret->{totalFailed};
}
} elsif ($build->finished == 0) {
++$ret->{totalQueued};
}
}
return $ret;
}
1;