This allows fully declarative project specifications. This is best illustrated by example:
6WRGCITDYP7JIBYP25QIWCHWRJWFPDP2D3TJS3WO3KUHQQJAWHMQC
NS7SND6RF6X3CVSVP7MLAQQZFA64E63YKFFABPEAGEPHX6PNWBOQC
DGHAIZTOPYJCEG7MRADPTCNX2NPS75IWGWHSPHCWAW4BYATCPH2QC
FCTX433OH7QIVWHXL23DKVSUKBQSLQTRK3PFCKKSMLX6A634456QC
LZVO64YG43JD7YMZSCTZNOBS5ROZA4FMPKJW2YOMHX2V5PTGBVWQC
3HZY24CX4U2TO74HOY4YX3LBJIYF4DLXHCIY7J2RASAC4COMSMZAC
4NTIBJ74F2QUMISJPB4DGM7VPYFVZDS6ZDITVIAQCSWO6C3UIQ6QC
ODNCGFQ5FPKFI624BVMLW7PJ2EFJOR3TY66OCZM42UNNTWBCF2TQC
FPK5LF53CFUEKFYJ3IYXT4UTVC6IITWJOCFATMC4PLHEUP5SIEAAC
7UJ5YV4VUSXMKB57KKXDG6KLIXMQXO45VO5UTOT46BHQJBFZ7XKQC
JAH3UPWAVSHXIPNGL6PROQPZBYZHPJNFONWBDZX4HCX646USZXUQC
24BMQDZAWDQ7VNIA7TIROXSOYLOJBNZ2E4264WHWNJAEN6ZB3UOAC
OOQ2D3KCLFPYNAN253PHWLBQMB6OMO2KYQWQXLTP65SQAYZWQ5LAC
BMSQD2ZH3T37RNPRKKKNF5DTJEGBLY4YR2BZDKP7PXJGS3ZBBLWAC
OSVLMLCQQ52E47CX7TZAIFZSO4VVGRHWJTZY2G23YUPMDCKURTYAC
VHV6GI4L2GEV2PV3AEV4C22O3JB4XUS6WPEBFINYD5CJOBMAESAAC
PCKLFRT5IZVLG47GQQ23GBSROKUR4CUEZW4PRVGREHNDFTCZ7VBAC
LBNVQXUBEZ45SOTGVXK5UEZXIAIZTJLWZNUYFI4JZ6J65N3KPDVQC
JM3DPYOMVNMCL5GMEYC3Y4NDRGTNIFBBFTPGPVT66GPENVPU7EVQC
X27GNHDV5KPZ5GSH6DCAJMNCEMZLCP7M43JWF2X3O5QWXMOX273AC
V4RNHJNR3WIBINRVD5MADTLUQWMCOMWHBD43MDV2XD7S6BRLL2YAC
SB2V735VJ2CDHGCXRUA5FOYHDRXQFVOZ3KXC3YKXWRNW6DIX7RXQC
Y6AHH4THYQA43V77L43YM42DYRPCMDSWLUV4NKWAQYMPL4NTUIPQC
T5BIOVJEMBIASP7EKQVV2N3VD6I56UXH6LCD5I33BDQEVHJAMGKQC
7ECJWNVXNO3BKM7B7FIFIRBE77QET5PK2C3XKVQUXCYKHDP3V4UQC
2G63HKCHG7S6DGWDOHSDF7PXFPD6H4TRKDKIIFCXXAKET6FCWN2AC
A6XVP6FE3CO7BVZR23HQS2GFDNF3FK7KBDSOB4YIPRISZHEWQJKAC
JY7BXXOP3EZCDT5RSMVE4Y6IECXGYL4GEBJOZHR7H3Z35XZ3NIVQC
D7PL2VWUCRIFGFPFXTB466NIUYU4FECAQPHF4TDFVMOK23VEHDEAC
77BG3TYKSKVV6C6VDJH7JDRJRPRNNBAO2OH4YZ6JY5Q5OP3VGXFQC
7YBYT2LQML2PKEO6UO4444AGSASS664UCDXW2YO3ALB7THQHCEBQC
ZDENAYQI5DRRNUIDVKUGC45NK6C4ZFUL5FYMACTRZOCYQXPMY63QC
N22GPKYTOLZLBGTGDATQDVZ4R5APZEAOIA7L32X4UXBH4XNI7MWAC
OVR2RWBIUXNW2XSG63KFL2S3Q7UVTLHOEYO3573LZBY7AMLUKKTQC
FDE3BJAPDEP3BYT5A5GEGLNXPPZLA2KTGXB4ZNYRP4LJ7IFRKYXAC
IE2PRAQUCQVFPJ4CAIJRPXXEFC5VBAE3EO5I5FG4XWEDRNONNHKQC
KN3VYE5P2RJB3KZ355LA5C2T2D5S2IR3QZFE53AJIWUVMETEEYDAC
D5QIOJGPKQJIYBUCSC3MFJ3TXLPNZ2XMI37GXMFRVRFWWR2VMTFAC
sub updateDeclarativeJobset {
my ($db, $project, $jobsetName, $declSpec) = @_;
my @allowed_keys = qw(
enabled
hidden
description
nixexprinput
nixexprpath
checkinterval
schedulingshares
enableemail
emailoverride
keepnr
);
my %update = ( name => $jobsetName );
foreach my $key (@allowed_keys) {
$update{$key} = $declSpec->{$key};
delete $declSpec->{$key};
}
txn_do($db, sub {
my $jobset = $project->jobsets->update_or_create(\%update);
$jobset->jobsetinputs->delete;
while ((my $name, my $data) = each %{$declSpec->{"inputs"}}) {
my $input = $jobset->jobsetinputs->create(
{ name => $name,
type => $data->{type},
emailresponsible => $data->{emailresponsible}
});
$input->jobsetinputalts->create({altnr => 0, value => $data->{value}});
}
delete $declSpec->{"inputs"};
die "invalid keys in declarative specification file\n" if (%{$declSpec});
});
};
sub handleDeclarativeJobsetBuild {
my ($db, $project, $build) = @_;
eval {
my $id = $build->id;
die "Declarative jobset build $id failed" unless $build->buildstatus == 0;
my $declPath = ($build->buildoutputs)[0]->path;
my $declText = read_file($declPath)
or die "Couldn't read declarative specification file $declPath: $!";
my $declSpec = decode_json($declText);
txn_do($db, sub {
my @kept = keys %$declSpec;
push @kept, ".jobsets";
$project->jobsets->search({ name => { "not in" => \@kept } })->update({ enabled => 0, hidden => 1 });
while ((my $jobsetName, my $spec) = each %$declSpec) {
updateDeclarativeJobset($db, $project, $jobsetName, $spec);
}
});
};
$project->jobsets->find({ name => ".jobsets" })->update({ errormsg => $@, errortime => time, fetcherrormsg => undef })
if defined $@;
};
# Created by DBIx::Class::Schema::Loader v0.07043 @ 2015-07-30 16:52:20
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:67kWIE0IGmEJTvOIATAKaw
# Created by DBIx::Class::Schema::Loader v0.07043 @ 2016-03-11 10:39:17
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1ats3brIVhRTWLToIYSoaQ
</div>
</div>
<div class="control-group">
<label class="control-label">Declarative spec file</label>
<div class="controls">
<div class="input-append">
<input type="text" class="span3" name="declfile" [% HTML.attributes(value => project.declfile) %]/>
</div>
<span class="help-inline">(Leave blank for non-declarative project configuration)</span>
<div class="control-group">
<label class="control-label">Declarative input type</label>
<div class="controls">
[% INCLUDE renderSelection param="decltype" options=inputTypes edit=1 curValue=project.decltype %]
value
<input style="width: 70%" type="text" [% HTML.attributes(value => project.declvalue, name => "declvalue") %]/>
</div>
</div>
my $jobsetsJobset = length($project->declfile) && $jobset->name eq ".jobsets";
if ($jobsetsJobset) {
my @declInputs = fetchInput($plugins, $db, $project, $jobset, "decl", $project->decltype, $project->declvalue, 0);
my $declInput = @declInputs[0] or die "cannot find the input containing the declarative project specification\n";
die "multiple alternatives for the input containing the declarative project specificaiton are not supported\n"
if scalar @declInputs != 1;
my $declFile = $declInput->{storePath} . "/" . $project->declfile;
my $declText = read_file($declFile)
or die "Couldn't read declarative specification file $declFile: $!\n";
my $declSpec;
eval {
$declSpec = decode_json($declText);
};
die "Declarative specification file $declFile not valid JSON: $@\n" if $@;
updateDeclarativeJobset($db, $project, ".jobsets", $declSpec);
$jobset->discard_changes;
}
-- Add declarative fields to Projects
alter table Projects add column declfile text;
alter table Projects add column decltype text;
alter table Projects add column declvalue text;