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(enabledhiddendescriptionnixexprinputnixexprpathcheckintervalschedulingsharesenableemailemailoverridekeepnr);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 Projectsalter table Projects add column declfile text;alter table Projects add column decltype text;alter table Projects add column declvalue text;