blob: 594a09d258847b1c54ebfd2f30389540a410bba4 [file] [log] [blame]
from twisted.internet import defer
@defer.inlineCallbacks
def collapseRequests(master, builder, req1, req2):
"""
Returns true if both buildrequest can be merged, via Deferred.
This implements Zorg's default collapse strategy.
"""
# If these are for the same buildset, collapse away.
if req1['buildsetid'] == req2['buildsetid']:
return True
# Check properties and do not collapse if properties do not match.
if req1.get('properties', None) != req2.get('properties', None):
return False
# Get the buidlsets for each buildrequest.
selfBuildsets = yield master.data.get(
('buildsets', str(req1['buildsetid'])))
otherBuildsets = yield master.data.get(
('buildsets', str(req2['buildsetid'])))
# Fetch the buildset properties.
selfBuildsetPoperties = yield \
master.db.buildsets.getBuildsetProperties(
str(req1['buildsetid'])
)
otherBuildsetPoperties = yield \
master.db.buildsets.getBuildsetProperties(
str(req2['buildsetid'])
)
# Check buildsets properties and do not collapse
# if properties do not match. This includes the check
# for different schedulers.
if selfBuildsetPoperties != otherBuildsetPoperties:
return False
# Extract sourcestamps, as dictionaries by codebase.
selfSources = dict((ss['codebase'], ss)
for ss in selfBuildsets['sourcestamps'])
otherSources = dict((ss['codebase'], ss)
for ss in otherBuildsets['sourcestamps'])
# If the sets of codebases do not match, we can't collapse.
if set(selfSources) != set(otherSources):
return False
for c, selfSS in selfSources.items():
otherSS = otherSources[c]
if selfSS['repository'] != otherSS['repository']:
return False
if selfSS['branch'] != otherSS['branch']:
return False
# TODO: Handle projects matching if we ever would have
# a mix of projects from the monorepo and outside of
# the monorepo. For now, we consider all of them being
# a part of the monorepo, so all of them are compatible
# and could be collapsed.
# Anything with a patch won't be collapsed.
if selfSS['patch'] or otherSS['patch']:
return False
# Get changes & compare.
selfChanges = yield master.data.get(('sourcestamps', selfSS['ssid'], 'changes'))
otherChanges = yield master.data.get(('sourcestamps', otherSS['ssid'], 'changes'))
# If both have changes - proceed, else fail.
# If no changes - check revision instead.
if selfChanges and otherChanges:
continue
if selfChanges and not otherChanges:
return False
if not selfChanges and otherChanges:
return False
# Else check revisions.
if selfSS['revision'] != otherSS['revision']:
return False
# Build requests with different reasons should be built separately.
if req1.get('reason', None) == req2.get('reason', None):
return True
else:
return False