@@ -301,20 +301,28 @@ def title(self):
301301 @cached_sorted_property ()
302302 def problems (self ):
303303 problems = []
304+ for builder in self .builders :
305+ if builder .problems :
306+ problems .extend (builder .problems )
307+ else :
308+ problems .append (NoProblem (builder ))
309+ return problems
310+
311+ @cached_sorted_property ()
312+ def builders (self ):
304313 for builder in self ._root .builders :
305314 if builder .branch == self :
306- if builder .problems :
307- problems .extend (builder .problems )
308- else :
309- problems .append (NoProblem (builder ))
310- return problems
315+ yield builder
311316
312317 @cached_property
313318 def featured_problem (self ):
314319 try :
315320 return self .problems [0 ]
316321 except IndexError :
317- return NoProblem ()
322+ if self .builders :
323+ return NoProblem ()
324+ else :
325+ return NoBuilds ()
318326
319327 def get_grouped_problems (self ):
320328 def key (problem ):
@@ -527,6 +535,8 @@ class Change(DashboardObject):
527535class Severity (enum .IntEnum ):
528536 # "Headings" and concrete values are all sortable enum items
529537
538+ NO_INFO = enum .auto ()
539+
530540 NO_PROBLEM = enum .auto ()
531541 no_builds_yet = enum .auto ()
532542 disconnected_unstable_builder = enum .auto ()
@@ -546,6 +556,8 @@ class Severity(enum.IntEnum):
546556
547557 @cached_property
548558 def css_color_class (self ):
559+ if self == Severity .NO_INFO :
560+ return 'none'
549561 if self >= Severity .BLOCKING :
550562 return 'danger'
551563 if self >= Severity .CONCERNING :
@@ -554,6 +566,8 @@ def css_color_class(self):
554566
555567 @cached_property
556568 def symbol (self ):
569+ if self == Severity .NO_INFO :
570+ return ''
557571 if self >= Severity .BLOCKING :
558572 return '\N{HEAVY BALLOT X} '
559573 if self >= Severity .CONCERNING :
@@ -562,6 +576,8 @@ def symbol(self):
562576
563577 @cached_property
564578 def releasability (self ):
579+ if self == Severity .NO_INFO :
580+ return 'N/A'
565581 if self >= Severity .BLOCKING :
566582 return 'Unreleasable'
567583 if self >= Severity .CONCERNING :
@@ -650,15 +666,6 @@ def affected_builds(self):
650666 return {"Warning build" : self .build }
651667
652668
653- @dataclass
654- class NoBuilds (Problem ):
655- """Builder has no finished builds yet"""
656- builder : Builder
657-
658- description = "Builder has no builds"
659- severity = Severity .no_builds_yet
660-
661-
662669@dataclass
663670class BuilderDisconnected (Problem ):
664671 """Builder has no finished builds yet"""
@@ -696,6 +703,17 @@ class NoProblem(Problem):
696703 severity = Severity .NO_PROBLEM
697704
698705
706+ @dataclass
707+ class NoBuilds (Problem ):
708+ """Dummy problem"""
709+ builder : None = None
710+
711+ name = "Not built"
712+
713+ description = "No builds"
714+ severity = Severity .NO_INFO
715+
716+
699717class ReleaseDashboard :
700718 # This doesn't get recreated for every render.
701719 # The Flask app and caches go here.
0 commit comments