Files
zzet--gortex/internal/docs/render.go
T
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

123 lines
3.3 KiB
Go

package docs
import (
"encoding/json"
"fmt"
"strings"
"time"
)
// RenderMarkdown projects a Bundle to markdown. Section order follows
// Bundle.Sections.
func RenderMarkdown(b *Bundle) string {
if b == nil {
return ""
}
var sb strings.Builder
fmt.Fprintf(&sb, "# Docs Bundle\n\n")
fmt.Fprintf(&sb, "Generated %s. Window since %s.\n\n",
b.GeneratedAt.Format(time.RFC3339), b.Since.Format(time.RFC3339))
for _, section := range b.Sections {
switch strings.ToLower(section) {
case "recent":
renderRecent(&sb, b.RecentChanges)
case "ownership":
renderOwnership(&sb, b.OwnershipRows)
case "stale":
renderStale(&sb, b.StaleCodeRows)
case "blame":
renderBlame(&sb, b.Blame)
}
}
return sb.String()
}
// RenderJSON marshals a Bundle to indented JSON.
func RenderJSON(b *Bundle) ([]byte, error) {
return json.MarshalIndent(b, "", " ")
}
func renderRecent(sb *strings.Builder, evs []HistoryEvent) {
sb.WriteString("## Recent Changes\n\n")
if len(evs) == 0 {
sb.WriteString("_No file changes recorded in this window. (Was the watcher attached?)_\n\n")
return
}
sb.WriteString("| Timestamp | Kind | File | +Nodes | -Nodes |\n")
sb.WriteString("|-----------|------|------|--------|--------|\n")
for _, ev := range evs {
fmt.Fprintf(sb, "| %s | %s | `%s` | %d | %d |\n",
ev.Timestamp.Format(time.RFC3339), ev.Kind, ev.FilePath,
ev.NodesAdded, ev.NodesRemoved)
}
sb.WriteString("\n")
}
func renderOwnership(sb *strings.Builder, rows []OwnershipRow) {
sb.WriteString("## Ownership\n\n")
if len(rows) == 0 {
sb.WriteString("_No blame metadata on graph nodes. Run `gortex enrich blame` or `analyze kind:blame` first._\n\n")
return
}
sb.WriteString("| Author | Symbols | Files | Oldest | Newest |\n")
sb.WriteString("|--------|---------|-------|--------|--------|\n")
for _, r := range rows {
fmt.Fprintf(sb, "| %s | %d | %d | %s | %s |\n",
r.Email, r.Symbols, r.Files,
formatTimestamp(r.Oldest), formatTimestamp(r.Newest))
}
sb.WriteString("\n")
}
func renderStale(sb *strings.Builder, rows []StaleCodeRow) {
sb.WriteString("## Stale Code\n\n")
if len(rows) == 0 {
sb.WriteString("_No stale code older than 365 days, or blame metadata missing._\n\n")
return
}
sb.WriteString("| Age (days) | Symbol | Author | Commit |\n")
sb.WriteString("|------------|--------|--------|--------|\n")
for _, r := range rows {
commitShort := r.Commit
if len(commitShort) > 8 {
commitShort = commitShort[:8]
}
sym := r.ID
if r.File != "" {
sym = fmt.Sprintf("`%s` (%s:%d)", r.ID, r.File, r.Line)
}
fmt.Fprintf(sb, "| %d | %s | %s | `%s` |\n",
r.AgeDays, sym, r.Email, commitShort)
}
sb.WriteString("\n")
}
func renderBlame(sb *strings.Builder, sum *BlameSummary) {
sb.WriteString("## Blame Enrichment\n\n")
if sum == nil {
sb.WriteString("_Blame re-run was not requested in this bundle._\n\n")
return
}
if sum.Error != "" {
fmt.Fprintf(sb, "Error: `%s`\n\n", sum.Error)
return
}
fmt.Fprintf(sb, "Enriched %d nodes.\n\n", sum.Enriched)
if len(sum.PerRepo) > 0 {
sb.WriteString("| Repo prefix | Nodes enriched |\n")
sb.WriteString("|-------------|----------------|\n")
for repo, count := range sum.PerRepo {
fmt.Fprintf(sb, "| `%s` | %d |\n", repo, count)
}
sb.WriteString("\n")
}
}
func formatTimestamp(ts int64) string {
if ts == 0 {
return "—"
}
return time.Unix(ts, 0).UTC().Format("2006-01-02")
}