Refactor out Changeish
This makes everything a child of Ref. As a result of this rearrangement,
NullChanges are awkward to use, and thus, have been replaced by enqueued
Refs where the 'ref' attribute is still unknown. As a result,
status.json will show timer-created jobs with an ID, where they used to
show a null, which is why that change to test_timer is necessary.
Change-Id: Ief0d3dde089b5529b9df7a804f6fea72b8b7dc48
Story: 2000781
Task: 3300
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index ec88737..8c5ef06 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -2806,7 +2806,6 @@
for q in p['change_queues']:
for head in q['heads']:
for change in head:
- self.assertEqual(change['id'], None)
for job in change['jobs']:
status_jobs.add(job['name'])
self.assertIn('project-bitrot-stable-old', status_jobs)
diff --git a/zuul/change_matcher.py b/zuul/change_matcher.py
index 845ba1c..1da1d2c 100644
--- a/zuul/change_matcher.py
+++ b/zuul/change_matcher.py
@@ -62,7 +62,8 @@
def matches(self, change):
return (
(hasattr(change, 'branch') and self.regex.match(change.branch)) or
- (hasattr(change, 'ref') and self.regex.match(change.ref))
+ (hasattr(change, 'ref') and
+ change.ref is not None and self.regex.match(change.ref))
)
diff --git a/zuul/driver/gerrit/gerritconnection.py b/zuul/driver/gerrit/gerritconnection.py
index 286006f..829c175 100644
--- a/zuul/driver/gerrit/gerritconnection.py
+++ b/zuul/driver/gerrit/gerritconnection.py
@@ -26,7 +26,7 @@
import voluptuous as v
from zuul.connection import BaseConnection
-from zuul.model import TriggerEvent, Project, Change, Ref, NullChange
+from zuul.model import TriggerEvent, Project, Change, Ref
from zuul import exceptions
@@ -292,7 +292,13 @@
change.url = self._getGitwebUrl(project, sha=event.newrev)
else:
project = self.getProject(event.project_name)
- change = NullChange(project)
+ change = Ref(project)
+ branch = event.branch or 'master'
+ change.ref = 'refs/heads/%s' % branch
+ refs = self.getInfoRefs(project)
+ change.oldrev = refs[change.ref]
+ change.newrev = refs[change.ref]
+ change.url = self._getGitwebUrl(project, sha=change.newrev)
return change
def _getChange(self, number, patchset, refresh=False, history=None):
diff --git a/zuul/driver/zuul/__init__.py b/zuul/driver/zuul/__init__.py
index 1bc0ee9..47ccec0 100644
--- a/zuul/driver/zuul/__init__.py
+++ b/zuul/driver/zuul/__init__.py
@@ -87,7 +87,7 @@
def _createParentChangeEnqueuedEvents(self, change, pipeline):
self.log.debug("Checking for changes needing %s:" % change)
if not hasattr(change, 'needed_by_changes'):
- self.log.debug(" Changeish does not support dependencies")
+ self.log.debug(" %s does not support dependencies" % type(change))
return
for needs in change.needed_by_changes:
self._createParentChangeEnqueuedEvent(needs, pipeline)
diff --git a/zuul/executor/client.py b/zuul/executor/client.py
index 31646f8..476c238 100644
--- a/zuul/executor/client.py
+++ b/zuul/executor/client.py
@@ -258,7 +258,7 @@
params['ZUUL_CHANGE_IDS'] = zuul_changes
params['ZUUL_CHANGE'] = str(item.change.number)
params['ZUUL_PATCHSET'] = str(item.change.patchset)
- if hasattr(item.change, 'ref'):
+ if hasattr(item.change, 'ref') and item.change.ref is not None:
params['ZUUL_REFNAME'] = item.change.ref
params['ZUUL_OLDREV'] = item.change.oldrev
params['ZUUL_NEWREV'] = item.change.newrev
diff --git a/zuul/manager/dependent.py b/zuul/manager/dependent.py
index f5fa579..4c48568 100644
--- a/zuul/manager/dependent.py
+++ b/zuul/manager/dependent.py
@@ -89,7 +89,7 @@
to_enqueue = []
self.log.debug("Checking for changes needing %s:" % change)
if not hasattr(change, 'needed_by_changes'):
- self.log.debug(" Changeish does not support dependencies")
+ self.log.debug(" %s does not support dependencies" % type(change))
return
for other_change in change.needed_by_changes:
with self.getChangeQueue(other_change) as other_change_queue:
@@ -133,7 +133,7 @@
# Return true if okay to proceed enqueing this change,
# false if the change should not be enqueued.
if not hasattr(change, 'needs_changes'):
- self.log.debug(" Changeish does not support dependencies")
+ self.log.debug(" %s does not support dependencies" % type(change))
return True
if not change.needs_changes:
self.log.debug(" No changes needed")
diff --git a/zuul/manager/independent.py b/zuul/manager/independent.py
index 3d28327..9e2a7d6 100644
--- a/zuul/manager/independent.py
+++ b/zuul/manager/independent.py
@@ -62,7 +62,7 @@
# Return true if okay to proceed enqueing this change,
# false if the change should not be enqueued.
if not hasattr(change, 'needs_changes'):
- self.log.debug(" Changeish does not support dependencies")
+ self.log.debug(" %s does not support dependencies" % type(change))
return True
if not change.needs_changes:
self.log.debug(" No changes needed")
diff --git a/zuul/model.py b/zuul/model.py
index 3676b68..4663a5a 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -1578,27 +1578,49 @@
return ret
-class Changeish(object):
- """Base class for Change and Ref."""
+class Ref(object):
+ """An existing state of a Project."""
def __init__(self, project):
self.project = project
+ self.ref = None
+ self.oldrev = None
+ self.newrev = None
def getBasePath(self):
base_path = ''
- if hasattr(self, 'refspec'):
- base_path = "%s/%s/%s" % (
- self.number[-2:], self.number, self.patchset)
- elif hasattr(self, 'ref'):
+ if hasattr(self, 'ref'):
base_path = "%s/%s" % (self.newrev[:2], self.newrev)
return base_path
+ def _id(self):
+ return self.newrev
+
+ def __repr__(self):
+ rep = None
+ if self.newrev == '0000000000000000000000000000000000000000':
+ rep = '<Ref 0x%x deletes %s from %s' % (
+ id(self), self.ref, self.oldrev)
+ elif self.oldrev == '0000000000000000000000000000000000000000':
+ rep = '<Ref 0x%x creates %s on %s>' % (
+ id(self), self.ref, self.newrev)
+ else:
+ # Catch all
+ rep = '<Ref 0x%x %s updated %s..%s>' % (
+ id(self), self.ref, self.oldrev, self.newrev)
+
+ return rep
+
def equals(self, other):
- raise NotImplementedError()
+ if (self.project == other.project
+ and self.ref == other.ref
+ and self.newrev == other.newrev):
+ return True
+ return False
def isUpdateOf(self, other):
- raise NotImplementedError()
+ return False
def filterJobs(self, jobs):
return filter(lambda job: job.changeMatches(self), jobs)
@@ -1610,7 +1632,7 @@
return False
-class Change(Changeish):
+class Change(Ref):
"""A proposed new state for a Project."""
def __init__(self, project):
super(Change, self).__init__(project)
@@ -1638,6 +1660,12 @@
def __repr__(self):
return '<Change 0x%x %s>' % (id(self), self._id())
+ def getBasePath(self):
+ if hasattr(self, 'refspec'):
+ return "%s/%s/%s" % (
+ self.number[-2:], self.number, self.patchset)
+ return super(Change, self).getBasePath()
+
def equals(self, other):
if self.number == other.number and self.patchset == other.patchset:
return True
@@ -1667,44 +1695,7 @@
return False
-class Ref(Changeish):
- """An existing state of a Project."""
- def __init__(self, project):
- super(Ref, self).__init__(project)
- self.ref = None
- self.oldrev = None
- self.newrev = None
-
- def _id(self):
- return self.newrev
-
- def __repr__(self):
- rep = None
- if self.newrev == '0000000000000000000000000000000000000000':
- rep = '<Ref 0x%x deletes %s from %s' % (
- id(self), self.ref, self.oldrev)
- elif self.oldrev == '0000000000000000000000000000000000000000':
- rep = '<Ref 0x%x creates %s on %s>' % (
- id(self), self.ref, self.newrev)
- else:
- # Catch all
- rep = '<Ref 0x%x %s updated %s..%s>' % (
- id(self), self.ref, self.oldrev, self.newrev)
-
- return rep
-
- def equals(self, other):
- if (self.project == other.project
- and self.ref == other.ref
- and self.newrev == other.newrev):
- return True
- return False
-
- def isUpdateOf(self, other):
- return False
-
-
-class NullChange(Changeish):
+class NullChange(Ref):
# TODOv3(jeblair): remove this in favor of enqueueing Refs (eg
# current master) instead.
def __repr__(self):