From 06358f94bd7ae74df86bd92ea3c7b5ec3e36ba71 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 2 Nov 2026 16:17:41 +0100 Subject: [PATCH] mesh-build-go: a unit level whose gofmt or vet fails still runs its tests, so one check names every failure The operator, 2026-11-02: a failed check showed only its first fault, and a group needed a run per fault. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL --- .../mesh-build-go/cmd/mesh-build-go/lint_test.go | 13 ++++++++----- modules/mesh-build-go/cmd/mesh-build-go/test.go | 9 +++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go b/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go index f5cef2eb..3836304a 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/lint_test.go @@ -72,7 +72,8 @@ func TestTheUnitLevelRunsGofmtAndVetWithEveryTag(t *testing.T) { } } -// 1887/D7-go: through the step, the unit level of a tree holding an unformatted file fails, naming the file. +// 1887/D7-go: through the step, the unit level of a tree holding an unformatted file fails, naming the file; its tests +// still run, so one check names the lint's failure and every failing test (the operator, 2026-11-02). func TestAnUnformattedFileFailsTheUnitLevel(t *testing.T) { m, states, ws, calls := workspaceFor(t, "empty") tree := filepath.Join(m.Work, ws, "tree") @@ -85,11 +86,13 @@ func TestAnUnformattedFileFailsTheUnitLevel(t *testing.T) { if res.Passed || len(res.Failed) != 1 || res.Failed[0].Test != "gofmt" || !strings.Contains(res.Failed[0].Output, "x.go") { t.Fatalf("result = %+v, want the level failed naming x.go", res) } - // Review round 2 item 5: before the level's tests, which do not run once gofmt failed. + // Review round 2 item 5: before the level's tests, which still run once gofmt failed. + tested := false for _, c := range *calls { - if strings.Contains(c.line, " test -json") { - t.Errorf("the tests ran after gofmt failed: %s", c.line) - } + tested = tested || strings.Contains(c.line, " test -json") + } + if !tested { + t.Errorf("the tests did not run after gofmt failed: %v", *calls) } } diff --git a/modules/mesh-build-go/cmd/mesh-build-go/test.go b/modules/mesh-build-go/cmd/mesh-build-go/test.go index d165124c..cbc53a33 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/test.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/test.go @@ -250,7 +250,8 @@ func (m *Module) runLevel(ctx context.Context, tree string, o levelOpts) (*TestR } if o.level == LevelUnit { // gofmt and go vet of each directory the level runs come before its tests (ADR 0529 ยง1; issue 1887 D7-go): a - // directory that fails them fails the level at once, and their time is the result's Lint. + // directory that fails them fails the level, named first, and the tests still run, so one check names the lint's + // failures and every failing test (the operator, 2026-11-02); their time is the result's Lint. linted := m.clock() failed, err := m.lintAll(ctx, run, tree, todo, func(d string) []string { return append(m.goEnvFor(filepath.Join(tree, d)), o.env...) @@ -259,11 +260,7 @@ func (m *Module) runLevel(ctx context.Context, tree string, o levelOpts) (*TestR return nil, err } res.Lint = m.clock().Sub(linted).Seconds() - if len(failed) > 0 { - res.Failed = failed - res.judge(o.bounds) - return res, nil - } + res.Failed = failed began = m.clock() // the level's running time is its tests' } runs := make([]dirRun, len(todo))