@@ -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,8 +535,9 @@ 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 ()
531- no_builds_yet = enum .auto ()
532541 disconnected_unstable_builder = enum .auto ()
533542 unstable_warnings = enum .auto ()
534543 unstable_builder_failure = enum .auto ()
@@ -546,6 +555,8 @@ class Severity(enum.IntEnum):
546555
547556 @cached_property
548557 def css_color_class (self ):
558+ if self == Severity .NO_INFO :
559+ return 'none'
549560 if self >= Severity .BLOCKING :
550561 return 'danger'
551562 if self >= Severity .CONCERNING :
@@ -554,6 +565,8 @@ def css_color_class(self):
554565
555566 @cached_property
556567 def symbol (self ):
568+ if self == Severity .NO_INFO :
569+ return ''
557570 if self >= Severity .BLOCKING :
558571 return '\N{HEAVY BALLOT X} '
559572 if self >= Severity .CONCERNING :
@@ -562,6 +575,8 @@ def symbol(self):
562575
563576 @cached_property
564577 def releasability (self ):
578+ if self == Severity .NO_INFO :
579+ return 'N/A'
565580 if self >= Severity .BLOCKING :
566581 return 'Unreleasable'
567582 if self >= Severity .CONCERNING :
@@ -650,15 +665,6 @@ def affected_builds(self):
650665 return {"Warning build" : self .build }
651666
652667
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-
662668@dataclass
663669class BuilderDisconnected (Problem ):
664670 """Builder has no finished builds yet"""
@@ -696,6 +702,17 @@ class NoProblem(Problem):
696702 severity = Severity .NO_PROBLEM
697703
698704
705+ @dataclass
706+ class NoBuilds (Problem ):
707+ """Dummy problem"""
708+ builder : None = None
709+
710+ name = "Not built"
711+
712+ description = "No builds"
713+ severity = Severity .NO_INFO
714+
715+
699716class ReleaseDashboard :
700717 # This doesn't get recreated for every render.
701718 # The Flask app and caches go here.
0 commit comments