Skip to content

Commit a96fcbf

Browse files
Refactor branch cancellation logic to provide detailed rejection reasons
1 parent 77ca6a5 commit a96fcbf

1 file changed

Lines changed: 43 additions & 10 deletions

File tree

utils.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -723,17 +723,45 @@ def _fmt_ss(ss):
723723
)
724724

725725
@staticmethod
726-
def _branch_is_cancelable(branch):
727-
"""Only let disposable normal branch pushes yield to pull request builds."""
726+
def _branch_rejection_reasons(branch):
727+
"""Explain why a branch push must not yield to a pull request build."""
728+
reasons = []
729+
728730
if not branch:
729-
return False
731+
return ["branch is missing"]
730732

731733
branch_lc = branch.lower()
732-
return (
733-
len(branch) > 5
734-
and not branch_lc.startswith("refs/")
735-
and not fnmatch_any(branch, SAVED_PACKAGE_BRANCHES)
736-
)
734+
if len(branch) <= 5:
735+
reasons.append(
736+
f"branch is only {len(branch)} characters; it must be longer than 5"
737+
)
738+
if branch_lc.startswith("refs/"):
739+
reasons.append("branch starts with 'refs/'")
740+
741+
matching_patterns = [
742+
pattern
743+
for pattern in SAVED_PACKAGE_BRANCHES
744+
if fnmatch.fnmatch(branch, pattern)
745+
]
746+
if matching_patterns:
747+
reasons.append(
748+
f"branch matches saved-package pattern(s) {matching_patterns!r}"
749+
)
750+
751+
return reasons
752+
753+
@classmethod
754+
def _branch_is_cancelable(cls, branch):
755+
"""Only let disposable normal branch pushes yield to pull request builds."""
756+
return not cls._branch_rejection_reasons(branch)
757+
758+
@classmethod
759+
def _sourcestamp_rejection_reasons(cls, ss):
760+
reasons = []
761+
if ss.get("revision") is None:
762+
reasons.append("revision is missing")
763+
reasons.extend(cls._branch_rejection_reasons(ss.get("branch")))
764+
return reasons
737765

738766
@defer.inlineCallbacks
739767
def _find_pull_request_matches(self, buildrequests, current_targets, source):
@@ -830,9 +858,14 @@ def run(self):
830858

831859
if not current_targets:
832860
lines.append(
833-
"Current buildset has no cancelable push sourcestamp with a "
834-
"revision; nothing to do."
861+
"No current sourcestamp is eligible for duplicate cancellation; "
862+
"nothing to do."
835863
)
864+
lines.append("Sourcestamp rejection details:")
865+
for i, ss in enumerate(current_sourcestamps, 1):
866+
reasons = self._sourcestamp_rejection_reasons(ss)
867+
lines.append(f" [{i}] {self._fmt_ss(ss)}")
868+
lines.extend(f" - {reason}" for reason in reasons)
836869
self.addCompleteLog("duplicate-buildrequests", "\n".join(lines) + "\n")
837870
return SUCCESS
838871

0 commit comments

Comments
 (0)