Handle builds with multiple outputs correctly in Hydra channels
This commit is contained in:
parent
5ccff14f6b
commit
0ec03aa0f4
|
@ -41,6 +41,7 @@ sub nix : Chained('get_builds') PathPart('channel') CaptureArgs(1) {
|
||||||
->search_literal("exists (select 1 from buildproducts where build = me.id and type = 'nix-build')")
|
->search_literal("exists (select 1 from buildproducts where build = me.id and type = 'nix-build')")
|
||||||
->search({}, { columns => [@buildListColumns, 'drvpath', 'description', 'homepage']
|
->search({}, { columns => [@buildListColumns, 'drvpath', 'description', 'homepage']
|
||||||
, join => ["buildoutputs"]
|
, join => ["buildoutputs"]
|
||||||
|
, order_by => ["me.id", "buildoutputs.name"]
|
||||||
, '+select' => ['buildoutputs.path', 'buildoutputs.name'], '+as' => ['outpath', 'outname'] });
|
, '+select' => ['buildoutputs.path', 'buildoutputs.name'], '+as' => ['outpath', 'outname'] });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -14,20 +14,36 @@ sub getChannelData {
|
||||||
|
|
||||||
my @storePaths = ();
|
my @storePaths = ();
|
||||||
$c->stash->{nixPkgs} = [];
|
$c->stash->{nixPkgs} = [];
|
||||||
foreach my $build ($c->stash->{channelBuilds}->all) {
|
|
||||||
my $outPath = $build->get_column("outpath");
|
my @builds = $c->stash->{channelBuilds}->all;
|
||||||
my $outName = $build->get_column("outname");
|
|
||||||
next if $checkValidity && !isValidPath($outPath);
|
for (my $n = 0; $n < scalar @builds; ) {
|
||||||
push @storePaths, $outPath;
|
# Since channelData is a join of Builds and BuildOutputs, we
|
||||||
my $pkgName = $build->nixname . "-" . $build->system . "-" . $build->id . ($outName ne "out" ? "-" . $outName : "");
|
# need to gather the rows that belong to a single build.
|
||||||
push @{$c->stash->{nixPkgs}}, { build => $build, name => $pkgName, outPath => $outPath, outName => $outName };
|
my $build = $builds[$n++];
|
||||||
# Put the system type in the manifest (for top-level paths) as
|
my @outputs = ($build);
|
||||||
# a hint to the binary patch generator. (It shouldn't try to
|
push @outputs, $builds[$n++] while $n < scalar @builds && $builds[$n]->id == $build->id;
|
||||||
# generate patches between builds for different systems.) It
|
@outputs = grep { $_->get_column("outpath") } @outputs;
|
||||||
# would be nice if Nix stored this info for every path but it
|
|
||||||
# doesn't.
|
my $outputs = {};
|
||||||
$c->stash->{systemForPath}->{$outPath} = $build->system;
|
foreach my $output (@outputs) {
|
||||||
};
|
my $outPath = $output->get_column("outpath");
|
||||||
|
next if $checkValidity && !isValidPath($outPath);
|
||||||
|
$outputs->{$output->get_column("outname")} = $outPath;
|
||||||
|
push @storePaths, $outPath;
|
||||||
|
# Put the system type in the manifest (for top-level
|
||||||
|
# paths) as a hint to the binary patch generator. (It
|
||||||
|
# shouldn't try to generate patches between builds for
|
||||||
|
# different systems.) It would be nice if Nix stored this
|
||||||
|
# info for every path but it doesn't.
|
||||||
|
$c->stash->{systemForPath}->{$outPath} = $build->system;
|
||||||
|
}
|
||||||
|
|
||||||
|
next if !%$outputs;
|
||||||
|
|
||||||
|
my $pkgName = $build->nixname . "-" . $build->system . "-" . $build->id;
|
||||||
|
push @{$c->stash->{nixPkgs}}, { build => $build, name => $pkgName, outputs => $outputs };
|
||||||
|
}
|
||||||
|
|
||||||
$c->stash->{storePaths} = [@storePaths];
|
$c->stash->{storePaths} = [@storePaths];
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,7 @@ sub nix : Chained('eval') PathPart('channel') CaptureArgs(0) {
|
||||||
->search({ finished => 1, buildstatus => 0 },
|
->search({ finished => 1, buildstatus => 0 },
|
||||||
{ columns => [@buildListColumns, 'drvpath', 'description', 'homepage']
|
{ columns => [@buildListColumns, 'drvpath', 'description', 'homepage']
|
||||||
, join => ["buildoutputs"]
|
, join => ["buildoutputs"]
|
||||||
|
, order_by => ["build.id", "buildoutputs.name"]
|
||||||
, '+select' => ['buildoutputs.path', 'buildoutputs.name'], '+as' => ['outpath', 'outname'] });
|
, '+select' => ['buildoutputs.path', 'buildoutputs.name'], '+as' => ['outpath', 'outname'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,34 +23,69 @@ sub process {
|
||||||
|
|
||||||
foreach my $pkg (@{$c->stash->{nixPkgs}}) {
|
foreach my $pkg (@{$c->stash->{nixPkgs}}) {
|
||||||
my $build = $pkg->{build};
|
my $build = $pkg->{build};
|
||||||
my $s = "";
|
$perSystem{$build->system}->{$build->get_column('job')} = $pkg;
|
||||||
$s .= " # $pkg->{name}\n";
|
|
||||||
$s .= " ${\escape $build->get_column('job')} = {\n";
|
|
||||||
$s .= " type = \"derivation\";\n";
|
|
||||||
$s .= " name = ${\escape ($build->get_column('releasename') or $build->nixname)};\n";
|
|
||||||
$s .= " system = ${\escape $build->system};\n";
|
|
||||||
$s .= " outPath = ${\escape $pkg->{outPath}};\n";
|
|
||||||
$s .= " meta = {\n";
|
|
||||||
$s .= " description = ${\escape $build->description};\n"
|
|
||||||
if $build->description;
|
|
||||||
$s .= " longDescription = ${\escape $build->longdescription};\n"
|
|
||||||
if $build->longdescription;
|
|
||||||
$s .= " license = ${\escape $build->license};\n"
|
|
||||||
if $build->license;
|
|
||||||
$s .= " maintainers = ${\escape $build->maintainers};\n"
|
|
||||||
if $build->maintainers;
|
|
||||||
$s .= " };\n";
|
|
||||||
$s .= " };\n\n";
|
|
||||||
$perSystem{$build->system} .= $s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my $res = "{ system ? builtins.currentSystem }:\n\n";
|
my $res = <<EOF;
|
||||||
|
{ system ? builtins.currentSystem }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
mkFakeDerivation = attrs: outputs:
|
||||||
|
let
|
||||||
|
outputNames = builtins.attrNames outputs;
|
||||||
|
common = attrs // outputsSet //
|
||||||
|
{ type = "derivation";
|
||||||
|
outputs = outputNames;
|
||||||
|
all = outputsList;
|
||||||
|
};
|
||||||
|
outputToAttrListElement = outputName:
|
||||||
|
{ name = outputName;
|
||||||
|
value = common // {
|
||||||
|
inherit outputName;
|
||||||
|
outPath = builtins.getAttr outputName outputs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
outputsList = map outputToAttrListElement outputNames;
|
||||||
|
outputsSet = builtins.listToAttrs outputsList;
|
||||||
|
in outputsSet;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
my $first = 1;
|
my $first = 1;
|
||||||
foreach my $system (keys %perSystem) {
|
foreach my $system (keys %perSystem) {
|
||||||
$res .= "else " if !$first;
|
$res .= "else " if !$first;
|
||||||
$res .= "if system == ${\escape $system} then {\n\n";
|
$res .= "if system == ${\escape $system} then {\n\n";
|
||||||
$res .= $perSystem{$system};
|
|
||||||
|
foreach my $job (keys $perSystem{$system}) {
|
||||||
|
my $pkg = $perSystem{$system}->{$job};
|
||||||
|
my $build = $pkg->{build};
|
||||||
|
$res .= " # Hydra build ${\$build->id}\n";
|
||||||
|
my $attr = $build->get_column('job');
|
||||||
|
$attr =~ s/\./-/g;
|
||||||
|
$res .= " ${\escape $attr} = (mkFakeDerivation {\n";
|
||||||
|
$res .= " type = \"derivation\";\n";
|
||||||
|
$res .= " name = ${\escape ($build->get_column('releasename') or $build->nixname)};\n";
|
||||||
|
$res .= " system = ${\escape $build->system};\n";
|
||||||
|
$res .= " meta = {\n";
|
||||||
|
$res .= " description = ${\escape $build->description};\n"
|
||||||
|
if $build->description;
|
||||||
|
$res .= " longDescription = ${\escape $build->longdescription};\n"
|
||||||
|
if $build->longdescription;
|
||||||
|
$res .= " license = ${\escape $build->license};\n"
|
||||||
|
if $build->license;
|
||||||
|
$res .= " maintainers = ${\escape $build->maintainers};\n"
|
||||||
|
if $build->maintainers;
|
||||||
|
$res .= " };\n";
|
||||||
|
$res .= " } {\n";
|
||||||
|
my @outputNames = sort (keys $pkg->{outputs});
|
||||||
|
$res .= " ${\escape $_} = ${\escape $pkg->{outputs}->{$_}};\n" foreach @outputNames;
|
||||||
|
my $out = defined $pkg->{outputs}->{"out"} ? "out" : $outputNames[0];
|
||||||
|
$res .= " }).$out;\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
$res .= "}\n\n";
|
$res .= "}\n\n";
|
||||||
$first = 0;
|
$first = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ install the package simply by clicking on the packages below.</p>
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
[% HTML.escape(b.description) %]
|
[% HTML.escape(b.description) %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% IF pkg.outName != 'out' %] [[% pkg.outName %]][% END %]
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue