Files
natsnet/tools/go-analyzer/grouper.go
2026-02-26 06:11:09 -05:00

114 lines
3.2 KiB
Go

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
}