POPU2ATH2HHBTGHKRAV3EY2K55P664IARI3YJGLDKVJ6PQPXBQ4AC
N6E7R424QZUPRLE6WAMMDPF7THV7MCKEL5RKSQNORY3OYOW7TDDQC
XNCWZ7OTIBIGWKAV7ZWCNO6QGQGAWRCZYK4HZMYPURJ7CLMRXUHAC
M3WSK4CBBGLP5W4YXPKWDL67RS2JV6VRTF67GLFKP7Q2FBT3NC6QC
2T42QGZDK23C5V4ZHO4R7EBJESIQ62GKWDBWVX7OBEE3YVBUNUFAC
CN5LSNJNYOZPSWS5GNCMIEPZ27DAYVEQ5CIA3XGPXO7CWADCKC7QC
BHZXGT2HWAMFNVBUDG7VR5HNA2SUJBUSMWB7EHTECB4QJ5HVYANAC
KD5237CUR4X3VRUD46H3CVU22NYS7LOPF3WXENWHNSF7GKEIQZ6QC
4N5APGRGHTKFMEJ7THSJX6TSYYAP3BUZQG73AJBKCQLXOOEHPATQC
4LWGZL33NOCTVZXUZZM5P6BRBHDUMEAJPVPNB52PN3UZVC7DMSZAC
YGRLM2SKOIPP4M24VYZTRREELKICDFKXL7ZHHR54BR5HVRCDOP6AC
N22GPKYTOLZLBGTGDATQDVZ4R5APZEAOIA7L32X4UXBH4XNI7MWAC
TLZ2SPBRX274EUS73SUUCOFYQUXB76S3F4AOSJXDYXIMMS7JIHEAC
X27GNHDV5KPZ5GSH6DCAJMNCEMZLCP7M43JWF2X3O5QWXMOX273AC
M552HLIAP52D42AVXVC5SGROAYN2TBCEUZOXESWEMBBUX7G3U6TAC
6BLUKEQ2M5RGWMPXPYIFIEVEUBV4PYAZ75S2WSBIATMRGYFMQZHQC
ZVTSOVHNQNQCRF3N44RKDQSL3UM7HSLTAXICMWEE6EIA6SWJXZCQC
YAPITGB3ENS6PXRBFC647ESCQUYG442DKHUPM46PJKCKTMHWGVXAC
FDE3BJAPDEP3BYT5A5GEGLNXPPZLA2KTGXB4ZNYRP4LJ7IFRKYXAC
H7CNGK4OJNRYZQGPLBGR72DULLEPFQ5UISF5J24D7IMA7SYW5LGQC
BVOPAMLSAU4UTV3DUX53OYDMXP2SETAQVUKAYE2OTCVVN4RD7LLQC
VJHIHMEHNE27HYL4CLC5J3SNALGPRSHYKQO2A65P5ORMTJEI42WQC
7YBYT2LQML2PKEO6UO4444AGSASS664UCDXW2YO3ALB7THQHCEBQC
KOTB7BKVML6T6S5ZNTQ6456FMGCRZCP3E3KVWCOW7T6SPRHC53LAC
L2E6EVE2RVFVDCUNRJ4CZYSQNS2DZUA5DTBETHBDUQUV2KQQRAOQC
ECBA3GQOGTF73Y7A5EFUXZ5PDIZ5NPJM3WMOUJTE3AEK2PZQX3MQC
67P45PY4GTWQXZRCMR734D5YYN2OERZM57NBB2CZXEULQT2GRFNAC
TWURROKCCLM4VOGVBX74ZW3UR4Q3ZSU3HDHU3CIOQUJ55PFOD7GQC
CMU3YKOUUB6VNP54NVYUKFHI3A46YAAANNYOZSHCUJIQOQEZ3GCAC
3ZCEPLNOOWRHKM75FJJVQHHYIAHXAYKFF5SEKQGVSMLRAF4NOBIAC
PHX2HIVGHHKCAX6VNN2WXD4LRGSA74KQMJCCTMHK7HS6JPELVECAC
sub checkJob {
my ($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs) = @_;
# Instantiate the store derivation.
(my $res, my $drvPath, my $stderr) = captureStdoutStderr(
"nix-instantiate", $nixExprPath, "--attr", $jobName, @{$extraArgs});
die "cannot evaluate the Nix expression for job `$jobName':\n$stderr" unless $res;
chomp $drvPath;
sub fetchInputs {
my ($jobset, $inputInfo) = @_;
foreach my $input ($jobset->jobsetinputs->all) {
foreach my $alt ($input->jobsetinputalts->all) {
push @{$$inputInfo{$input->name}}, fetchInputAlt($input, $alt);
}
}
}
# Call nix-env --xml to get info about this job (drvPath, outPath, meta attributes, ...).
($res, my $infoXml, $stderr) = captureStdoutStderr(
qw(nix-env --query --available * --attr-path --out-path --drv-path --meta --xml --system-filter *),
"-f", $nixExprPath, "--attr", $jobName, @{$extraArgs});
die "cannot get information about the job `$jobName':\n$stderr" unless $res;
my $job = $info->{item}->{$jobName};
die if !defined $job;
my $description = defined $job->{meta}->{description} ? $job->{meta}->{description}->{value} : "";
my $longDescription = defined $job->{meta}->{longDescription} ? $job->{meta}->{longDescription}->{value} : "";
my $license = defined $job->{meta}->{license} ? $job->{meta}->{license}->{value} : "";
my $homepage = defined $job->{meta}->{homepage} ? $job->{meta}->{homepage}->{value} : "";
die unless $job->{drvPath} eq $drvPath;
my $jobName = $job->{jobName};
my $drvPath = $job->{drvPath};
, description => $description
, longdescription => $longDescription
, license => $license
, nixname => $job->{name}
, description => $job->{description}
, longdescription => $job->{longDescription}
, license => $job->{license}
, nixname => $job->{nixName}
if ($n >= scalar @{$argsNeeded}) {
eval {
checkJob($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs);
};
if ($@) {
print "error evaluating job `", $jobName, "': $@";
setJobsetError($jobset, $@);
}
return;
}
my $argName = @{$argsNeeded}[$n];
#print "finding alternatives for argument $argName\n";
my ($input) = $jobset->jobsetinputs->search({name => $argName});
my %newInputInfo = %{$inputInfo}; $inputInfo = \%newInputInfo; # clone
if (defined $input) {
foreach my $alt ($input->jobsetinputalts) {
#print "input ", $input->name, " (type ", $input->type, ") alt ", $alt->altnr, "\n";
fetchInput($input, $alt, $inputInfo);
my @newArgs = @{$extraArgs};
if (defined $inputInfo->{$argName}->{storePath}) {
push @newArgs, "--arg", $argName,
"{path = builtins.storePath " . $inputInfo->{$argName}->{storePath} . ";" .
" outPath = builtins.storePath " . $inputInfo->{$argName}->{storePath} . ";" .
" rev = \"" . $inputInfo->{$argName}->{revision} . "\";}";
} elsif ($inputInfo->{$argName}->{type} eq "string") {
push @newArgs, "--argstr", $argName, $inputInfo->{$argName}->{value};
} elsif ($inputInfo->{$argName}->{type} eq "boolean") {
push @newArgs, "--arg", $argName, $inputInfo->{$argName}->{value};
foreach my $input (keys %{$inputInfo}) {
foreach my $alt (@{$inputInfo->{$input}}) {
given ($alt->{type}) {
when ("string") {
push @res, "--argstr", $input, $alt->{value};
}
when ("boolean") {
push @res, "--arg", $input, $alt->{value};
}
when (["svn", "path"]) {
push @res, "--arg", $input, (
"{ outPath = builtins.storePath " . $alt->{storePath} . "" .
"; rev = \"" . $alt->{revision} . "\"" .
";}"
);
}
if (!defined $prevBuild) {
# !!! reschedule?
die "missing input `$argName'";
}
# The argument name matches a previously built job in this
# jobset. Pick the most recent build. !!! refine the
# selection criteria: e.g., most recent successful build.
if (!isValidPath($prevBuild->outpath)) {
die "input path " . $prevBuild->outpath . " has been garbage-collected";
}
$$inputInfo{$argName} =
{ type => "build"
, storePath => $prevBuild->outpath
, id => $prevBuild->id
};
my $pkgNameRE = "(?:(?:[A-Za-z0-9]|(?:-[^0-9]))+)";
my $versionRE = "(?:[A-Za-z0-9\.\-]+)";
my $relName = ($prevBuild->resultInfo->releasename or $prevBuild->nixname);
my $version = $2 if $relName =~ /^($pkgNameRE)-($versionRE)$/;
my @newArgs = @{$extraArgs};
push @newArgs, "--arg", $argName,
"{ path = builtins.storePath " . $prevBuild->outpath . "; " .
" outPath = builtins.storePath " . $prevBuild->outpath . "; " .
($version ? " version = \"$version\"; " : "") . # !!! escape
"}";
checkJobAlternatives(
$project, $jobset, $inputInfo, $nixExprPath,
$jobName, $jobExpr, \@newArgs, $argsNeeded, $n + 1);
}
return @res;
# Fetch the input containing the Nix expression.
(my $exprInput) = $jobset->jobsetinputs->search({name => $jobset->nixexprinput});
die "No input named " . $jobset->nixexprinput unless defined $exprInput;
die "Multiple alternatives for the Nix expression input not supported yet"
if scalar($exprInput->jobsetinputalts) != 1;
# Evaluate the Nix expression.
my $nixExprPath = $inputInfo->{$jobset->nixexprinput}->{storePath} . "/" . $jobset->nixexprpath;
# Evaluate the job expression.
my $nixExprPath = $inputInfo->{$jobset->nixexprinput}->[0]->{storePath}
or die "cannot find the input containing the job expression";
$nixExprPath .= "/" . $jobset->nixexprpath;
# Iterate over the attributes listed in the Nix expression and
# perform the builds described by them. If an attribute is a
# function, then fill in the function arguments with the
# (alternative) values supplied in the jobsetinputs table.
foreach my $jobName (keys(%{$jobs->{attrs}->{attr}})) {
print "considering job $jobName\n";
my @argsNeeded = ();
my $jobExpr = $jobs->{attrs}->{attr}->{$jobName};
# !!! fix the case where there is only 1 attr, XML::Simple fucks up as usual
if (defined $jobExpr->{function}->{attrspat}) {
foreach my $argName (keys(%{$jobExpr->{function}->{attrspat}->{attr}})) {
#print "needs input $argName\n";
push @argsNeeded, $argName;
}
}
eval {
checkJobAlternatives(
$project, $jobset, {}, $nixExprPath,
$jobName, $jobExpr, [], \@argsNeeded, 0);
};
if ($@) {
print "error checking job ", $jobName, ": $@";
setJobsetError($jobset, $@);
}
# Schedule each successfully evaluated job.
foreach my $job (@{$jobs->{job}}) {
print "considering job " . $job->{jobName} . "\n";
checkJob($project, $jobset, $inputInfo, $job);