From cfa02ea26e6a5f3c7805abd3fa28deb223072dfc Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 10:22:17 +0100 Subject: [PATCH] Join 11: refuse a committed program anywhere in the repository A compiled program reached a commit a second time (the view's 18 MB program at its module's root, which the command-folder pattern did not cover): the sdk's nobinaries test refuses every tracked executable, as the catalogue's checks/nobinaries does, and .gitignore covers a module's root. Builds: design 47 G join (the kind's guard, fix-a-bug-met-twice) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h --- .gitignore | 2 + sdk/nobinaries/nobinaries_test.go | 90 +++++++++++++++++++++++++++++++ sdk/nobinaries/reads-outside | 1 + 3 files changed, 93 insertions(+) create mode 100644 sdk/nobinaries/nobinaries_test.go create mode 100644 sdk/nobinaries/reads-outside diff --git a/.gitignore b/.gitignore index 420d8ac7..50cdf9c1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ vendor/ # A compiled program never enters a commit (issue 1577): `go build .` in a command directory leaves one there. modules/*/cmd/*/mesh-* !modules/*/cmd/*/mesh-*.go +# `go build .` at a module's root leaves its program there too (the view's, met a second time). +modules/*/mesh-* diff --git a/sdk/nobinaries/nobinaries_test.go b/sdk/nobinaries/nobinaries_test.go new file mode 100644 index 00000000..3d371e13 --- /dev/null +++ b/sdk/nobinaries/nobinaries_test.go @@ -0,0 +1,90 @@ +// Package nobinaries refuses a compiled program anywhere in the repository, as the catalogue's checks/nobinaries does +// (issue 1577): a compiled program is build output, made by the module's build step, and `go build` in a module's +// folder writes one beside go.mod where `git add -A` takes it (met a second time: the view's 18 MB program at the +// module's root, which the command-folder pattern of .gitignore does not cover). +package nobinaries + +import ( + "bytes" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +// kind says what executable format the first bytes of a file are, or "" when they are none. +func kind(head []byte) string { + switch { + case bytes.HasPrefix(head, []byte("\x7fELF")): + return "ELF" + case bytes.HasPrefix(head, []byte("MZ")): + return "PE" + case bytes.HasPrefix(head, []byte{0xcf, 0xfa, 0xed, 0xfe}), bytes.HasPrefix(head, []byte{0xce, 0xfa, 0xed, 0xfe}), + bytes.HasPrefix(head, []byte{0xfe, 0xed, 0xfa, 0xcf}), bytes.HasPrefix(head, []byte{0xfe, 0xed, 0xfa, 0xce}), + bytes.HasPrefix(head, []byte{0xca, 0xfe, 0xba, 0xbe}) && len(head) >= 8 && head[7] < 0x20 && head[6] == 0 && head[5] == 0 && head[4] == 0: + return "Mach-O" + } + return "" +} + +// found names each tracked file under root that is a compiled program, with its format. +func found(t *testing.T, root string) []string { + t.Helper() + out, err := exec.Command("git", "-C", root, "ls-files", "-z").Output() + if err != nil { + t.Fatalf("git ls-files in %s: %v", root, err) + } + var names []string + for _, f := range strings.Split(strings.TrimRight(string(out), "\x00"), "\x00") { + if f == "" { + continue + } + p := filepath.Join(root, f) + st, err := os.Lstat(p) + if err != nil || !st.Mode().IsRegular() { // a file the change deletes is not there + continue + } + fh, err := os.Open(p) + if err != nil { + t.Fatal(err) + } + head := make([]byte, 8) + n, err := io.ReadFull(fh, head) + fh.Close() + if err != nil && err != io.ErrUnexpectedEOF && err != io.EOF { + t.Fatal(err) + } + if k := kind(head[:n]); k != "" { + names = append(names, f+" ("+k+")") + } + } + return names +} + +func TestKindNamesEachExecutableFormatAndNothingElse(t *testing.T) { + for _, c := range []struct { + head []byte + want string + }{ + {[]byte("\x7fELF\x02\x01\x01\x00"), "ELF"}, + {[]byte("MZ\x90\x00"), "PE"}, + {[]byte{0xcf, 0xfa, 0xed, 0xfe, 7, 0, 0, 1}, "Mach-O"}, + {[]byte("package main\n"), ""}, + {[]byte("\x7f"), ""}, + {nil, ""}, + {[]byte{0xca, 0xfe, 0xba, 0xbe, 0, 0, 0, 52}, ""}, // a Java class, not a Mach-O + } { + if got := kind(c.head); got != c.want { + t.Errorf("kind(%q) = %q, want %q", c.head, got, c.want) + } + } +} + +// The repository holds no compiled program, in any module or outside one. +func TestTheRepositoryHoldsNoCompiledProgram(t *testing.T) { + for _, f := range found(t, filepath.Join("..", "..")) { + t.Errorf("%s: a compiled program is build output: remove it and add it to .gitignore (issue 1577)", f) + } +} diff --git a/sdk/nobinaries/reads-outside b/sdk/nobinaries/reads-outside new file mode 100644 index 00000000..2608ca02 --- /dev/null +++ b/sdk/nobinaries/reads-outside @@ -0,0 +1 @@ +# every tracked file of the repository (git ls-files, no path limit): the whole tree, so this package's verdict is never kept.