F-catalog-B: the catalogue's Go is as gofmt writes it, and checks/gofmt holds it so

buildstep's generated.go and generated_test.go and claude-code's config_test.go reached the join
unformatted: the second of a kind, which no check caught since each module's tests hold only themselves.
All three are formatted, and checks/gofmt refuses a Go file of the catalogue gofmt would change.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 17:18:45 +01:00
parent d8e43b48c4
commit d320a19a8c
6 changed files with 117 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
module git.novox.be/novox/mesh-catalog/checks/gofmt
go 1.22
+58
View File
@@ -0,0 +1,58 @@
// Package gofmt refuses a Go file of the catalogue that gofmt would change (the second of a kind in one milestone:
// buildstep's generated.go and claude-code's config_test.go reached a join unformatted). A check here holds every
// module to it, where a module's own tests hold only themselves.
package gofmt
import (
"bytes"
"go/format"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
)
// Files are the Go files under root, relative to it: every .go file but those in .git, node_modules and a testdata
// directory (a test's fixture may be anything).
func Files(root string) ([]string, error) {
var out []string
err := filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
switch d.Name() {
case ".git", "node_modules", "testdata":
return filepath.SkipDir
}
return nil
}
if strings.HasSuffix(d.Name(), ".go") && d.Type().IsRegular() {
rel, _ := filepath.Rel(root, p)
out = append(out, filepath.ToSlash(rel))
}
return nil
})
sort.Strings(out)
return out, err
}
// Unformatted are the files gofmt would change, and why for one that does not parse.
func Unformatted(root string, files []string) (map[string]string, error) {
out := map[string]string{}
for _, f := range files {
src, err := os.ReadFile(filepath.Join(root, f))
if err != nil {
return nil, err
}
got, err := format.Source(src)
switch {
case err != nil:
out[f] = "it does not parse: " + err.Error()
case !bytes.Equal(got, src):
out[f] = "gofmt changes it: run gofmt -w " + f
}
}
return out, nil
}
+53
View File
@@ -0,0 +1,53 @@
package gofmt
import (
"os"
"path/filepath"
"testing"
)
func TestUnformattedNamesWhatGofmtChanges(t *testing.T) {
root := t.TempDir()
for f, src := range map[string]string{
"modules/a/a.go": "package a\n",
"modules/b/b.go": "package b\nimport (\n\t\"os\"\n\t\"fmt\"\n)\nvar _, _ = fmt.Sprint, os.Exit\n",
"modules/c/testdata/c.go": "package c",
"modules/d/node_modules/d.go": "package d",
} {
p := filepath.Join(root, f)
_ = os.MkdirAll(filepath.Dir(p), 0o755)
if err := os.WriteFile(p, []byte(src), 0o644); err != nil {
t.Fatal(err)
}
}
files, err := Files(root)
if err != nil {
t.Fatal(err)
}
got, err := Unformatted(root, files)
if err != nil {
t.Fatal(err)
}
if len(files) != 2 || len(got) != 1 || got["modules/b/b.go"] == "" {
t.Errorf("files %v, unformatted %v; want a.go and b.go read, b.go named", files, got)
}
}
// The catalogue's own Go files are as gofmt writes them.
func TestTheCataloguesGoIsFormatted(t *testing.T) {
root := filepath.Join("..", "..")
files, err := Files(root)
if err != nil {
t.Fatal(err)
}
if len(files) == 0 {
t.Fatal("no Go file found: the check reads nothing")
}
got, err := Unformatted(root, files)
if err != nil {
t.Fatal(err)
}
for f, why := range got {
t.Errorf("%s: %s", f, why)
}
}
@@ -269,7 +269,7 @@ func TestTheManifestListsEveryToolServed(t *testing.T) {
t.Fatal(err)
}
var m struct {
Tools []string `json:"tools"`
Tools []string `json:"tools"`
Invokes []string `json:"invokes"`
Reads []string `json:"reads"`
Consumes []string `json:"consumes"`
+1 -1
View File
@@ -20,8 +20,8 @@ import (
"sort"
"strings"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep/seatgen"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// GeneratedRootGo and GeneratedRootTS are the generated roots of a contracts module, one per build module.
@@ -10,8 +10,8 @@ import (
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/delivery"
"git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep/seatgen"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
// contracts writes a contracts module of one seat, its generated files as the generator writes them, and answers its