feat(#141): export FileCoveredByDocMap helper in review/docmap.go

Adds FileCoveredByDocMap(cfg *DocMapConfig, file string) bool — a thin wrapper
over the existing unexported mappingMatches that lets cmd/ check per-file docmap
coverage without duplicating glob logic.

Also adds unit tests covering matched globs, non-matching paths, empty file,
and empty config.
This commit is contained in:
Rodin
2026-05-15 04:46:38 +00:00
parent 04b24256c0
commit 93268869c5
2 changed files with 61 additions and 0 deletions
+12
View File
@@ -66,6 +66,18 @@ func ParseDocMapConfig(localPath string) (*DocMapConfig, error) {
return &cfg, nil
}
// FileCoveredByDocMap reports whether at least one paths: glob in any mapping
// of cfg matches the given file path. It is used by static validation tooling
// (e.g. the validate-docmap subcommand) to check per-file docmap coverage.
func FileCoveredByDocMap(cfg *DocMapConfig, file string) bool {
for _, mapping := range cfg.Mappings {
if mappingMatches(mapping.Paths, []string{file}) {
return true
}
}
return false
}
// MatchDocs returns deduplicated doc paths for the given changed file paths.
// A mapping matches if any of its path globs matches any of the changed files.
func MatchDocs(cfg *DocMapConfig, changedFiles []string) []string {
+49
View File
@@ -436,3 +436,52 @@ func writeTempYAML(t *testing.T, content string) string {
}
return filepath.Clean(f.Name())
}
// ============================================================
// FileCoveredByDocMap
// ============================================================
func TestFileCoveredByDocMap(t *testing.T) {
cfg := &DocMapConfig{
Mappings: []DocMapping{
{
Paths: []string{"lib/foo/**", "lib/bar/*.go"},
Docs: []string{"docs/foo.md"},
},
{
Paths: []string{"cmd/**"},
Docs: []string{"docs/cmd.md"},
},
},
}
cases := []struct {
file string
covered bool
}{
{"lib/foo/baz.ex", true},
{"lib/foo/sub/deep.ex", true},
{"lib/bar/util.go", true},
{"lib/bar/sub/util.go", false}, // *.go only matches one level
{"cmd/main.go", true},
{"cmd/sub/main.go", true},
{"internal/secret.go", false},
{"", false},
}
for _, tc := range cases {
t.Run(tc.file, func(t *testing.T) {
got := FileCoveredByDocMap(cfg, tc.file)
if got != tc.covered {
t.Errorf("FileCoveredByDocMap(%q) = %v, want %v", tc.file, got, tc.covered)
}
})
}
}
func TestFileCoveredByDocMap_EmptyConfig(t *testing.T) {
cfg := &DocMapConfig{}
if FileCoveredByDocMap(cfg, "lib/foo/bar.go") {
t.Error("expected false for empty config, got true")
}
}