The Gatekeeper, or a project gating system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
5.2 KiB

# Copyright 2014 Rackspace Australia
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import abc
class BaseSource(object, metaclass=abc.ABCMeta):
"""Base class for sources.
A source class gives methods for fetching and updating changes. Each
pipeline must have (only) one source. It is the canonical provider of the
change to be tested.
Defines the exact public methods that must be supplied."""
def __init__(self, driver, connection, canonical_hostname, config=None):
self.driver = driver
self.connection = connection
self.canonical_hostname = canonical_hostname
self.config = config or {}
def getRefSha(self, project, ref):
"""Return a sha for a given project ref."""
def isMerged(self, change, head=None):
"""Determine if change is merged.
If head is provided the change is checked if it is at head."""
def canMerge(self, change, allow_needs, event=None, allow_refresh=False):
"""Determine if change can merge.
change: The change to check for mergeability
allow_needs: The statuses/votes that are allowed to be missing on a
change, typically the votes the pipeline would set itself
before attempting to merge
event: event information for log annotation
allow_refresh: Allow refreshing of cached volatile data that cannot be
reliably kept up to date using events.
def postConfig(self):
"""Called after configuration has been processed."""
def getChange(self, event):
"""Get the change representing an event.
This method is called very frequently, and should generally
return quickly. The connection is expected to cache change
objects and automatically update them as related events are
def getChangeByURL(self, url, event):
"""Get the change corresponding to the supplied URL.
The URL may may not correspond to this source; if it doesn't,
or there is no change at that URL, return None.
def getChangeByKey(self, key):
"""Get the change corresponding to the supplied cache key.
The key may not correspond to this source. Return None if it
raise NotImplementedError
def getChangesDependingOn(self, change, projects, tenant):
"""Return changes which depend on changes at the supplied URIs.
Search this source for changes which depend on the supplied
change. Generally the Change.uris attribute should be used to
perform the search, as it contains a list of URLs without the
scheme which represent a single change
If the projects argument is None, search across all known
projects. If it is supplied, the search may optionally be
restricted to only those projects.
The tenant argument can be used by the source to limit the
search scope.
def getProjectOpenChanges(self, project):
"""Get the open changes for a project."""
def getGitUrl(self, project):
"""Get the git url for a project."""
def getProject(self, name):
"""Get a project."""
def getProjectBranches(self, project, tenant):
"""Get branches for a project
This method is called very frequently, and should generally
return quickly. The connection is expected to cache branch
lists for all projects queried, and further, to automatically
clear or update that cache when it observes branch creation or
deletion events.
def getRequireFilters(self, config):
"""Return a list of ChangeFilters for the scheduler to match against.
def getRejectFilters(self, config):
"""Return a list of ChangeFilters for the scheduler to match against.
def setChangeAttributes(self, change, **attrs):
""""Set the provided attributes on the given change.
This method must be used when modifying attributes of a change
outside the driver context. The driver needs to make sure that
the change is also reflected in the cache in Zookeeper.
# TODO (swestphahl): Remove this workaround after all drivers
# have been converted to use a Zookeeper backed changed cache.
for name, value in attrs.items():
setattr(change, name, value)