From a57957df841755af8006349c972259985952e8b1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 27 Aug 2013 11:48:02 +0200 Subject: [PATCH] Handle job aliases in AggregateConstituents Aggregate constituents are derivations. However there can be multiple builds in an evaluation that have the same derivation, i.e. they can alias each other (e.g. "emacs", "emacs24" and "emacs24Packages.emacs" in Nixpkgs). Previously we picked a build arbitrarily for the AggregateConstituents table. Now we pick the one with the shortest name (e.g. "emacs"). --- src/lib/Hydra/Helper/AddBuilds.pm | 4 ++-- src/script/hydra-evaluator | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/lib/Hydra/Helper/AddBuilds.pm b/src/lib/Hydra/Helper/AddBuilds.pm index f1e21b49..ec62811d 100644 --- a/src/lib/Hydra/Helper/AddBuilds.pm +++ b/src/lib/Hydra/Helper/AddBuilds.pm @@ -433,7 +433,7 @@ sub checkBuild { { rows => 1, columns => ['id'], join => ['buildoutputs'] }); if (defined $prevBuild) { print STDERR " already scheduled/built as build ", $prevBuild->id, "\n"; - $buildMap->{$prevBuild->id} = { new => 0, drvPath => $drvPath }; + $buildMap->{$prevBuild->id} = { id => $prevBuild->id, jobName => $jobName, new => 0, drvPath => $drvPath }; return; } } @@ -506,7 +506,7 @@ sub checkBuild { $build->buildoutputs->create({ name => $_, path => $buildInfo->{output}->{$_}->{path} }) foreach @outputNames; - $buildMap->{$build->id} = { new => 1, drvPath => $drvPath }; + $buildMap->{$build->id} = { id => $build->id, jobName => $jobName, new => 1, drvPath => $drvPath }; $$jobOutPathMap{$jobName . "\t" . $firstOutputPath} = $build->id; if ($build->iscachedbuild) { diff --git a/src/script/hydra-evaluator b/src/script/hydra-evaluator index 0fdca76a..7505b93b 100755 --- a/src/script/hydra-evaluator +++ b/src/script/hydra-evaluator @@ -177,20 +177,31 @@ sub checkJobsetWrapped { if ($hasNewBuilds) { # Create JobsetEvalMembers mappings. - my %drvPathToId; while (my ($id, $x) = each %buildMap) { $ev->jobsetevalmembers->create({ build => $id, isnew => $x->{new} }); - $drvPathToId{$x->{drvPath}} = $id; } - # Create AggregateConstituents mappings. + # Create AggregateConstituents mappings. Since there can + # be jobs that alias each other, if there are multiple + # builds for the same derivation, pick the one with the + # shortest name. + my %drvPathToId; + while (my ($id, $x) = each %buildMap) { + my $y = $drvPathToId{$x->{drvPath}}; + if (defined $y) { + next if length $x->{jobName} > length $y->{jobName}; + next if length $x->{jobName} == length $y->{jobName} && $x->{jobName} ge $y->{jobName}; + } + $drvPathToId{$x->{drvPath}} = $x; + } + foreach my $job (@{$jobs->{job}}) { next unless $job->{constituents}; - my $id = $drvPathToId{$job->{drvPath}} or die; + my $x = $drvPathToId{$job->{drvPath}} or die; foreach my $drvPath (split / /, $job->{constituents}) { my $constituent = $drvPathToId{$drvPath}; if (defined $constituent) { - $db->resultset('AggregateConstituents')->update_or_create({aggregate => $id, constituent => $constituent}); + $db->resultset('AggregateConstituents')->update_or_create({aggregate => $x->{id}, constituent => $constituent->{id}}); } else { warn "aggregate job ‘$job->{jobName}’ has a constituent ‘$drvPath’ that doesn't correspond to a Hydra build\n"; }