Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/backlog/build-ignore-file-mixes-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
worth: maybe
where: internal/generator/generator.go:Parse
added: 2026-10-31
---
# build-ignored file of another package makes the package clause random

`Parse` reads every non-test `.go` file in the directory without evaluating build constraints, groups
them by package and keeps whichever package the map visits last. A `//go:build ignore` helper of
`package main` next to the enum (a common pattern for generator scripts) gives the generated file
`package main` in some runs: 2 of 6 in a probe after the `_test.go` skip landed.

Two shapes are open: honour build constraints (`go/build` or `build.Default.MatchFile`), or pick the
package the enum type is declared in instead of the last one seen. Surfaced reviewing
https://github.com/go-pkgz/enum/discussions/11.
11 changes: 11 additions & 0 deletions docs/backlog/readme-test-files-ignored.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
worth: later
where: README.md
added: 2026-10-31
---
# README does not say _test.go files are ignored

`Parse` skips `_test.go` files, so enum constants declared in tests are never collected. The README
describes which constants are picked up but says nothing about test files, so someone declaring an
enum in a test file gets "no const values found" with no hint why. One line in the constants section
covers it.
3 changes: 2 additions & 1 deletion internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ func (g *Generator) Parse(dir string) error {
// group parsed files by package name; mirrors the behaviour of the deprecated parser.ParseDir
pkgFiles := map[string][]*ast.File{}
for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") {
// the generated file is not a test file, so it can't reference anything declared in tests
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || strings.HasSuffix(entry.Name(), "_test.go") {
continue
}
file, err := parser.ParseFile(fset, filepath.Join(dir, entry.Name()), nil, parser.ParseComments)
Expand Down
26 changes: 25 additions & 1 deletion internal/generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,30 @@ func TestGenerator(t *testing.T) {
})
}

func TestParseSkipsTestFiles(t *testing.T) {
// regression: a black-box test package next to the enum made the package clause random
tmpDir := t.TempDir()
files := map[string]string{
"status.go": "package p1\ntype status int\nconst (\n\tstatusUnknown status = iota\n\tstatusActive\n)\n",
"status_internal_test.go": "package p1\nconst statusFromInternalTest status = 10\n",
"status_external_test.go": "package p1_test\nconst statusFromExternalTest = 20\n",
}
for name, body := range files {
require.NoError(t, os.WriteFile(filepath.Join(tmpDir, name), []byte(body), 0o600))
}

gen, err := New("status", tmpDir)
require.NoError(t, err)
require.NoError(t, gen.Parse(tmpDir))

assert.Equal(t, "p1", gen.pkgName)
values := map[string]int64{}
for name := range gen.values {
values[name] = constVal(t, gen, name)
}
assert.Equal(t, map[string]int64{"statusUnknown": 0, "statusActive": 1}, values)
}

func TestGeneratorValues(t *testing.T) {
tmpDir := t.TempDir()

Expand Down Expand Up @@ -665,7 +689,7 @@ const (

func TestNoLinterWarningsForUnusedConstants(t *testing.T) {
tmpDir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpDir, "linter_test.go"), []byte(`
err := os.WriteFile(filepath.Join(tmpDir, "linter.go"), []byte(`
package test
type linterTest uint8
const (
Expand Down
Loading