diff --git a/docs/state-model.md b/docs/state-model.md index 95e9290..ec8d712 100644 --- a/docs/state-model.md +++ b/docs/state-model.md @@ -98,6 +98,7 @@ Rules: `Submodule.HiddenIssues()` counts the issues of **all** loaded descendants and returns the most severe level. A collapsed submodule shows this as `·k` in that level's color, so a danger can never hide inside a collapsed subtree. +A descendant whose load failed (`error`) counts as one danger. ## Resolving a pin to a ref diff --git a/internal/submodule/status.go b/internal/submodule/status.go index f0b41d0..19f6040 100644 --- a/internal/submodule/status.go +++ b/internal/submodule/status.go @@ -61,9 +61,14 @@ func (s *Status) Issues() []Issue { } // HiddenIssues counts the issues of all loaded descendants and returns the -// most severe level among them. +// most severe level among them. A descendant whose load failed counts as one +// danger, since its state is unknown. func (m *Submodule) HiddenIssues() (count int, worst Level) { Walk(m.Children, func(c *Submodule) { + if c.Status == nil && c.Err != nil { + count++ + worst = max(worst, LevelDanger) + } for _, is := range c.Status.Issues() { count++ worst = max(worst, is.Level) diff --git a/internal/submodule/status_test.go b/internal/submodule/status_test.go index 4b38123..d4af037 100644 --- a/internal/submodule/status_test.go +++ b/internal/submodule/status_test.go @@ -1,6 +1,7 @@ package submodule import ( + "errors" "slices" "testing" ) @@ -69,3 +70,12 @@ func TestUntrackedRepositoryWording(t *testing.T) { } } } + +func TestHiddenIssuesCountLoadErrors(t *testing.T) { + bad := &Submodule{Err: errors.New("boom")} + loading := &Submodule{} + parent := &Submodule{Children: []*Submodule{bad, loading}} + if n, w := parent.HiddenIssues(); n != 1 || w != LevelDanger { + t.Errorf("got %d, %v; want 1, danger", n, w) + } +}