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 }