From 864749f6817c85a0cdda9fe58064ebf3a9d9a0fb Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 26 Feb 2026 06:11:09 -0500 Subject: [PATCH] feat(go-analyzer): add file-to-module grouping logic --- tools/go-analyzer/grouper.go | 113 +++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tools/go-analyzer/grouper.go diff --git a/tools/go-analyzer/grouper.go b/tools/go-analyzer/grouper.go new file mode 100644 index 0000000..1309bb2 --- /dev/null +++ b/tools/go-analyzer/grouper.go @@ -0,0 +1,113 @@ +package main + +import ( + "path/filepath" + "sort" + "strings" +) + +// ModuleGrouper groups Go source files into logical modules. +type ModuleGrouper struct { + Prefixes map[string]string +} + +// DefaultGrouper creates a grouper with default prefix rules for nats-server. +func DefaultGrouper() *ModuleGrouper { + return &ModuleGrouper{ + Prefixes: map[string]string{ + "jetstream": "jetstream", + "consumer": "jetstream", + "stream": "jetstream", + "store": "jetstream", + "filestore": "jetstream", + "memstore": "jetstream", + "raft": "raft", + "gateway": "gateway", + "leafnode": "leafnode", + "route": "route", + "client": "client", + "client_proxyproto": "client", + "server": "core", + "service": "core", + "signal": "core", + "reload": "core", + "opts": "config", + "auth": "auth", + "auth_callout": "auth", + "jwt": "auth", + "nkey": "auth", + "accounts": "accounts", + "ocsp": "tls", + "ocsp_peer": "tls", + "ocsp_responsecache": "tls", + "ciphersuites": "tls", + "parser": "protocol", + "proto": "protocol", + "sublist": "subscriptions", + "subject_transform": "subscriptions", + "monitor": "monitoring", + "monitor_sort_opts": "monitoring", + "mqtt": "mqtt", + "websocket": "websocket", + "events": "events", + "msgtrace": "events", + "log": "logging", + "errors": "errors", + "errors_gen": "errors", + "const": "core", + "util": "core", + "ring": "core", + "sendq": "core", + "ipqueue": "core", + "rate_counter": "core", + "scheduler": "core", + "sdm": "core", + "dirstore": "core", + "disk_avail": "core", + "elastic": "core", + }, + } +} + +// GroupFiles takes a flat list of Go files and returns them grouped by module name. +func (g *ModuleGrouper) GroupFiles(files []string) map[string][]string { + groups := make(map[string][]string) + + for _, f := range files { + base := filepath.Base(f) + base = strings.TrimSuffix(base, ".go") + base = strings.TrimSuffix(base, "_test") + + for _, suffix := range []string{"_windows", "_linux", "_darwin", "_bsd", + "_solaris", "_wasm", "_netbsd", "_openbsd", "_dragonfly", "_zos", "_other"} { + base = strings.TrimSuffix(base, suffix) + } + + module := g.classify(base) + groups[module] = append(groups[module], f) + } + + for k := range groups { + sort.Strings(groups[k]) + } + + return groups +} + +// classify determines which module a file belongs to based on its base name. +func (g *ModuleGrouper) classify(baseName string) string { + if module, ok := g.Prefixes[baseName]; ok { + return module + } + + bestMatch := "" + bestModule := "core" + for prefix, module := range g.Prefixes { + if strings.HasPrefix(baseName, prefix) && len(prefix) > len(bestMatch) { + bestMatch = prefix + bestModule = module + } + } + + return bestModule +}