FDE3BJAPDEP3BYT5A5GEGLNXPPZLA2KTGXB4ZNYRP4LJ7IFRKYXAC M552HLIAP52D42AVXVC5SGROAYN2TBCEUZOXESWEMBBUX7G3U6TAC X27GNHDV5KPZ5GSH6DCAJMNCEMZLCP7M43JWF2X3O5QWXMOX273AC N22GPKYTOLZLBGTGDATQDVZ4R5APZEAOIA7L32X4UXBH4XNI7MWAC PHX2HIVGHHKCAX6VNN2WXD4LRGSA74KQMJCCTMHK7HS6JPELVECAC 5QJP6JHSLKEQ5WBHAU62HJXU4PUGVRDVAIS3SHHFHTTVPEVCRYCAC IMY5UQE3I2UJRKEFJSW5OM4IY5QGQICDSAKCP7MGWGS7FO4ELXTQC GWCV3TQVFLUPBREUFRJV6ACJGQHD24NIUAVQQFURMXT3GL2SPPZAC die unless defined $inputInfo->{$jobset->nixexprinput};
# Instantiate the store derivation.my $drvPath = `nix-instantiate $nixExprPath --attr $jobName $extraArgs`or die "cannot evaluate the Nix expression containing the job definitions: $?";chomp $drvPath;# Call nix-env --xml to get info about this job (drvPath, outPath, meta attributes, ...).my $infoXml = `nix-env -f $nixExprPath --query --available "*" --attr-path --out-path --drv-path --meta --xml --system-filter "*" --attr $jobName $extraArgs`or die "cannot get information about the job: $?";my $info = XMLin($infoXml, KeyAttr => ['attrPath', 'name'])or die "cannot parse XML output";my $job = $info->{item};die if !defined $job || $job->{attrPath} ne $jobName;my $description = defined $job->{meta}->{description} ? $job->{meta}->{description}->{value} : "";die unless $job->{drvPath} eq $drvPath;my $outPath = $job->{outPath};buildJob($project, $jobset, $jobName, $drvPath, $outPath, $inputInfo, $job->{system});};sub checkJobAlternatives {my ($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs, $argsNeeded, $n) = @_;if ($n >= scalar @{$argsNeeded}) {checkJob($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs);return;}my $argName = @{$argsNeeded}[$n];print " finding alternatives for argument $argName\n";my ($input) = $jobset->jobsetinputs->search({name => $argName});if (defined $input) {foreach my $alt ($input->jobsetinputalts) {print " INPUT ", $input->name, " (type ", $input->type, ") alt ", $alt->altnr, "\n";fetchInput($input, $alt, $inputInfo); # !!! cachingmy $newArgs = "";if (defined $inputInfo->{$argName}->{storePath}) {# !!! escaping$newArgs = " --arg $argName '{path = " . $inputInfo->{$argName}->{storePath} . ";}'";} elsif (defined $inputInfo->{$argName}->{value}) {$newArgs = " --argstr $argName '" . $inputInfo->{$argName}->{value} . "'";}checkJobAlternatives($project, $jobset, $inputInfo, $nixExprPath,$jobName, $jobExpr, $extraArgs . $newArgs, $argsNeeded, $n + 1);}}else {(my $prevBuild) = $db->resultset('Builds')->search({project => $project->name, jobset => $jobset->name, attrname => $argName, buildStatus => 0},{order_by => "timestamp DESC", rows => 1});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};checkJobAlternatives($project, $jobset, $inputInfo, $nixExprPath,$jobName, $jobExpr,$extraArgs . " --arg $argName '{path = " . $prevBuild->outpath . ";}'",$argsNeeded, $n + 1);}}
sub checkJobSet {my ($project, $jobset) = @_;my $inputInfo = {};# Fetch the input containing the Nix expression.(my $exprInput) = $jobset->jobsetinputs->search({name => $jobset->nixexprinput});die unless defined $exprInput;die "not supported yet" if scalar($exprInput->jobsetinputalts) != 1;fetchInput($exprInput, $exprInput->jobsetinputalts->first, $inputInfo);# Evaluate the Nix expression.
if (defined $inputInfo->{$argName}) {# The argument name matches an input.$$usedInputs{$argName} = $inputInfo->{$argName};if (defined $inputInfo->{$argName}->{storePath}) {# !!! escaping$extraArgs .= " --arg $argName '{path = builtins.toPath " . $inputInfo->{$argName}->{storePath} . ";}'";} elsif (defined $inputInfo->{$argName}->{value}) {$extraArgs .= " --argstr $argName '" . $inputInfo->{$argName}->{value} . "'";}}else {(my $prevBuild) = $db->resultset('Builds')->search({project => $project->name, jobset => $jobset->name, attrname => $argName, buildStatus => 0},{order_by => "timestamp DESC", rows => 1});my $storePath;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";}$$usedInputs{$argName} ={ type => "build", storePath => $prevBuild->outpath, id => $prevBuild->id};$extraArgs .= " --arg $argName '{path = builtins.toPath " . $prevBuild->outpath . ";}'";}}
push @argsNeeded, $argName;}
# Instantiate the store derivation.print $extraArgs, "\n";my $drvPath = `nix-instantiate $nixExprPath --attr $jobName $extraArgs`or die "cannot evaluate the Nix expression containing the job definitions: $?";chomp $drvPath;
# Call nix-env --xml to get info about this job (drvPath, outPath, meta attributes, ...).my $infoXml = `nix-env -f $nixExprPath --query --available "*" --attr-path --out-path --drv-path --meta --xml --system-filter "*" --attr $jobName $extraArgs`or die "cannot get information about the job: $?";my $info = XMLin($infoXml, KeyAttr => ['attrPath', 'name'])or die "cannot parse XML output";my $job = $info->{item};die if !defined $job || $job->{attrPath} ne $jobName;my $description = defined $job->{meta}->{description} ? $job->{meta}->{description}->{value} : "";die unless $job->{drvPath} eq $drvPath;my $outPath = $job->{outPath};buildJob($project, $jobset, $jobName, $drvPath, $outPath, $usedInputs, $job->{system});
checkJobAlternatives($project, $jobset, $inputInfo, $nixExprPath,$jobName, $jobExpr, "", \@argsNeeded, 0);
};sub checkJobSetAlts {my ($project, $jobset, $inputs, $n, $inputInfo) = @_;if ($n >= scalar @{$inputs}) {checkJobSetInstance($project, $jobset, $inputInfo);return;}my $input = @{$inputs}[$n];foreach my $alt ($input->jobsetinputalts) {print " INPUT ", $input->name, " (type ", $input->type, ") alt ", $alt->altnr, "\n";fetchInput($input, $alt, $inputInfo); # !!! cachingcheckJobSetAlts($project, $jobset, $inputs, $n + 1, $inputInfo);}};sub checkJobSet {my ($project, $jobset) = @_;my $inputInfo = {};my @jobsetinputs = $jobset->jobsetinputs;checkJobSetAlts($project, $jobset, \@jobsetinputs, 0, $inputInfo);