mirror of
https://github.com/anotherhadi/iknowyou.git
synced 2026-04-12 00:47:26 +02:00
156 lines
4.1 KiB
Go
156 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/anotherhadi/iknowyou/internal/registry"
|
|
"github.com/anotherhadi/iknowyou/internal/tools"
|
|
)
|
|
|
|
func main() {
|
|
out := flag.String("out", "../.github/docs", "output directory for generated docs")
|
|
flag.Parse()
|
|
|
|
toolsDir := filepath.Join(*out, "tools")
|
|
if _, err := os.Stat(toolsDir); err == nil {
|
|
if err := os.RemoveAll(toolsDir); err != nil {
|
|
fatalf("removing tools dir: %v", err)
|
|
}
|
|
}
|
|
|
|
if err := os.MkdirAll(toolsDir, 0o755); err != nil {
|
|
fatalf("mkdir: %v", err)
|
|
}
|
|
|
|
runners := make([]tools.ToolRunner, len(registry.Factories))
|
|
for i, f := range registry.Factories {
|
|
runners[i] = f()
|
|
}
|
|
|
|
if err := writeIndex(*out, runners); err != nil {
|
|
fatalf("index: %v", err)
|
|
}
|
|
for _, r := range runners {
|
|
if err := writeTool(*out, r); err != nil {
|
|
fatalf("tool %s: %v", r.Name(), err)
|
|
}
|
|
}
|
|
|
|
fmt.Printf("✓ generated docs for %d tools → %s\n", len(runners), *out)
|
|
}
|
|
|
|
// writeIndex writes the tools.md index table.
|
|
func writeIndex(outDir string, runners []tools.ToolRunner) error {
|
|
var b strings.Builder
|
|
|
|
b.WriteString("# Tools\n\n")
|
|
fmt.Fprintf(&b, "_%d tools registered._\n\n", len(runners))
|
|
|
|
b.WriteString("| Tool | Input types | Description | Link |\n")
|
|
b.WriteString("|------|-------------|-------------|------|\n")
|
|
|
|
for _, r := range runners {
|
|
types := make([]string, len(r.InputTypes()))
|
|
for i, t := range r.InputTypes() {
|
|
types[i] = fmt.Sprintf("`%s`", t)
|
|
}
|
|
link := fmt.Sprintf("[`%s`](tools/%s.md)", r.Name(), r.Name())
|
|
projectLink := ""
|
|
if r.Link() != "" {
|
|
projectLink = fmt.Sprintf("[Link](%s)", r.Link())
|
|
}
|
|
fmt.Fprintf(&b, "| %s | %s | %s | %s |\n",
|
|
link,
|
|
strings.Join(types, ", "),
|
|
r.Description(),
|
|
projectLink,
|
|
)
|
|
}
|
|
|
|
return writeFile(filepath.Join(outDir, "tools.md"), b.String())
|
|
}
|
|
|
|
// writeTool writes the per-tool detail page.
|
|
func writeTool(outDir string, r tools.ToolRunner) error {
|
|
var b strings.Builder
|
|
|
|
fmt.Fprintf(&b, "# `%s`\n\n", r.Name())
|
|
fmt.Fprintf(&b, "%s\n\n", r.Description())
|
|
|
|
if r.Link() != "" {
|
|
fmt.Fprintf(&b, "**Source / documentation:** [%s](%s)\n\n", r.Link(), r.Link())
|
|
}
|
|
|
|
// Input types
|
|
b.WriteString("## Input types\n\n")
|
|
for _, t := range r.InputTypes() {
|
|
fmt.Fprintf(&b, "- `%s`\n", t)
|
|
}
|
|
b.WriteString("\n")
|
|
|
|
// External binary dependencies
|
|
if lister, ok := r.(tools.DependencyLister); ok {
|
|
if deps := lister.Dependencies(); len(deps) > 0 {
|
|
b.WriteString("## External dependencies\n\n")
|
|
b.WriteString("The following binaries must be installed and available in `$PATH`:\n\n")
|
|
for _, dep := range deps {
|
|
fmt.Fprintf(&b, "- `%s`\n", dep)
|
|
}
|
|
b.WriteString("\n")
|
|
}
|
|
}
|
|
|
|
// Configuration
|
|
if d, ok := r.(tools.ConfigDescriber); ok {
|
|
fields := d.ConfigFields()
|
|
if len(fields) > 0 {
|
|
b.WriteString("## Configuration\n\n")
|
|
b.WriteString("Configure globally via the Tools page or override per profile.\n\n")
|
|
b.WriteString("| Field | Type | Required | Default | Description |\n")
|
|
b.WriteString("|-------|------|:--------:|---------|-------------|\n")
|
|
for _, f := range fields {
|
|
req := "-"
|
|
if f.Required {
|
|
req = "**yes**"
|
|
}
|
|
def := "-"
|
|
if f.Default != nil && fmt.Sprintf("%v", f.Default) != "" {
|
|
def = fmt.Sprintf("`%v`", f.Default)
|
|
}
|
|
desc := f.Description
|
|
if desc == "" {
|
|
desc = "-"
|
|
}
|
|
fmt.Fprintf(&b, "| `%s` | `%s` | %s | %s | %s |\n",
|
|
f.Name, f.Type, req, def, desc,
|
|
)
|
|
}
|
|
b.WriteString("\n")
|
|
} else {
|
|
b.WriteString("## Configuration\n\nThis tool has no configuration fields.\n\n")
|
|
}
|
|
} else if _, ok := r.(tools.Configurable); ok {
|
|
b.WriteString("## Configuration\n\nThis tool is configurable but does not expose field metadata.\n\n")
|
|
} else {
|
|
b.WriteString("## Configuration\n\nThis tool requires no configuration.\n\n")
|
|
}
|
|
|
|
b.WriteString("---\n\n")
|
|
b.WriteString("[← Back to tools index](../tools.md)\n")
|
|
|
|
return writeFile(filepath.Join(outDir, "tools", r.Name()+".md"), b.String())
|
|
}
|
|
|
|
func writeFile(path, content string) error {
|
|
return os.WriteFile(path, []byte(content), 0o644)
|
|
}
|
|
|
|
func fatalf(format string, args ...any) {
|
|
fmt.Fprintf(os.Stderr, "gendocs: "+format+"\n", args...)
|
|
os.Exit(1)
|
|
}
|