package modules import ( "sort" "strconv" "gsg/internal/core" ) // This file is the ENTIRE cost of adding a feature. No core change, no // route change, no registration list to update -- write the module, then // call `mod "authors"` from any template that wants it. type Author struct { Name string Commits int } func init() { core.Register("authors", authorsMod) } // authors: commit counts per author over the last N commits (default 500). func authorsMod(c *core.Ctx, args ...string) (any, error) { n := 500 if len(args) > 0 { if v, err := strconv.Atoi(args[0]); err == nil { n = v } } rev := c.Commit if rev == "" { rev = c.Ref } log, err := c.Repo.Log(rev, n) if err != nil { return nil, err } counts := map[string]int{} for _, cm := range log { counts[cm.Author]++ } out := make([]Author, 0, len(counts)) for name, n := range counts { out = append(out, Author{Name: name, Commits: n}) } sort.Slice(out, func(i, j int) bool { if out[i].Commits != out[j].Commits { return out[i].Commits > out[j].Commits } return out[i].Name < out[j].Name }) return out, nil }