Add meta-jobs.

If a job is named with a regex starting with ^, treat it as a
meta-job and apply its attributes to matching jobs.

Explicitly set attributes on normal job definitions will override
those set by a meta job.

This should reduce the need to copy/paste error messages for
some common jobs.

Change-Id: I4362f4892d1c60514fbaa9092ecd8b44493c7421
This commit is contained in:
James E. Blair 2012-06-01 11:32:01 -07:00
parent 3266340ecc
commit b0954652c6
2 changed files with 30 additions and 7 deletions

View File

@ -67,6 +67,11 @@ class Job(object):
def __repr__(self): def __repr__(self):
return '<Job %s>' % (self.name) return '<Job %s>' % (self.name)
def copy(self, other):
self.failure_message = other.failure_message
self.success_message = other.failure_message
self.event_filters = other.event_filters[:]
class Build(object): class Build(object):
def __init__(self, job, uuid): def __init__(self, job, uuid):

View File

@ -16,6 +16,7 @@ import os
import Queue import Queue
import threading import threading
import logging import logging
import re
import yaml import yaml
from model import Job, Change, Project, ChangeQueue, EventFilter from model import Job, Change, Project, ChangeQueue, EventFilter
@ -39,6 +40,7 @@ class Scheduler(threading.Thread):
self.queue_managers = {} self.queue_managers = {}
self.jobs = {} self.jobs = {}
self.projects = {} self.projects = {}
self.metajobs = {}
def _parseConfig(self, fp): def _parseConfig(self, fp):
def toList(item): def toList(item):
@ -74,15 +76,18 @@ class Scheduler(threading.Thread):
for config_job in data['jobs']: for config_job in data['jobs']:
job = self.getJob(config_job['name']) job = self.getJob(config_job['name'])
job.failure_message = config_job.get('failure-message', None) # Be careful to only set attributes explicitly present on
job.success_message = config_job.get('success-message', None) # this job, to avoid squashing attributes set by a meta-job.
silent = config_job.get('silent', None) m = config_job.get('failure-message', None)
if silent: if m:
job.silent = True job.failure_message = m
m = config_job.get('success-message', None)
if m:
job.success_message = m
branches = toList(config_job.get('branch')) branches = toList(config_job.get('branch'))
if branches: if branches:
f = EventFilter(branches=branches) f = EventFilter(branches=branches)
job.event_filters.append(f) job.event_filters = [f]
def add_jobs(job_tree, config_jobs): def add_jobs(job_tree, config_jobs):
for job in config_jobs: for job in config_jobs:
@ -105,6 +110,10 @@ class Scheduler(threading.Thread):
config_jobs = config_project[qname] config_jobs = config_project[qname]
add_jobs(job_tree, config_jobs) add_jobs(job_tree, config_jobs)
# All jobs should be defined at this point, get rid of
# metajobs so that getJob isn't doing anything weird.
self.metajobs = {}
# TODO(jeblair): check that we don't end up with jobs like # TODO(jeblair): check that we don't end up with jobs like
# "foo - bar" because a ':' is missing in the yaml for a dependent job # "foo - bar" because a ':' is missing in the yaml for a dependent job
for manager in self.queue_managers.values(): for manager in self.queue_managers.values():
@ -114,7 +123,16 @@ class Scheduler(threading.Thread):
if name in self.jobs: if name in self.jobs:
return self.jobs[name] return self.jobs[name]
job = Job(name) job = Job(name)
self.jobs[name] = job if name.startswith('^'):
# This is a meta-job
regex = re.compile(name)
self.metajobs[regex] = job
else:
# Apply attributes from matching meta-jobs
for regex, metajob in self.metajobs.items():
if regex.match(name):
job.copy(metajob)
self.jobs[name] = job
return job return job
def setLauncher(self, launcher): def setLauncher(self, launcher):