Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# docgen

Route documentation generator for [chi](https://github.com/go-chi/chi) routers.

## Install

```bash
go get github.com/go-chi/docgen
```

## Usage

Generate markdown API docs from your router:

```go
package main

import (
"net/http"

"github.com/go-chi/chi/v5"
"github.com/go-chi/docgen"
)

func main() {
r := chi.NewRouter()
r.Get("/", func(w http.ResponseWriter, r *http.Request) {})

md := docgen.NewMarkdownDoc(r)
md.Opts.ProjectPath = "github.com/my/app"
md.Opts.URLMap = map[string]string{
"github.com/go-chi/chi/v5": "https://github.com/go-chi/chi/tree/master",
}
println(md.Markdown())
}
```

See `docgen_test.go` and `raml/raml_test.go` for more examples.

## License

MIT
1 change: 1 addition & 0 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/go-chi/chi/v5"
)

// BuildDoc walks a chi router and builds structured route documentation.
func BuildDoc(r chi.Routes) (Doc, error) {
d := Doc{}

Expand Down
4 changes: 4 additions & 0 deletions docgen.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package docgen generates route documentation from chi routers.
package docgen

import (
Expand All @@ -7,6 +8,7 @@ import (
"github.com/go-chi/chi/v5"
)

// Doc is the JSON-serializable documentation for a chi router tree.
type Doc struct {
Router DocRouter `json:"router"`
}
Expand Down Expand Up @@ -36,6 +38,7 @@ type DocHandler struct {

type DocHandlers map[string]DocHandler // Method : DocHandler

// PrintRoutes prints route patterns from a chi router to stdout.
func PrintRoutes(r chi.Routes) {
var printRoutes func(parentPattern string, r chi.Routes)
printRoutes = func(parentPattern string, r chi.Routes) {
Expand All @@ -54,6 +57,7 @@ func PrintRoutes(r chi.Routes) {
printRoutes("", r)
}

// JSONRoutesDoc returns indented JSON documentation for a chi router.
func JSONRoutesDoc(r chi.Routes) string {
doc, _ := BuildDoc(r)
v, err := json.MarshalIndent(doc, "", " ")
Expand Down
1 change: 1 addition & 0 deletions funcinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type FuncInfo struct {
Unresolvable bool `json:"unresolvable,omitempty"`
}

// GetFuncInfo returns source location and comment metadata for a handler.
func GetFuncInfo(i interface{}) FuncInfo {
fi := FuncInfo{}
frame := getCallerFrame(i)
Expand Down
7 changes: 7 additions & 0 deletions markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import (
"bytes"
"errors"
"fmt"
"regexp"
"sort"
"strings"

"github.com/go-chi/chi/v5"
)

// moduleVersionInPath matches Go module cache version segments (e.g. @v5.0.11).
var moduleVersionInPath = regexp.MustCompile(`@v[^/]+`)

type MarkdownDoc struct {
Opts MarkdownOpts
Router chi.Router
Expand All @@ -36,6 +40,7 @@ type MarkdownOpts struct {
URLMap map[string]string
}

// MarkdownRoutesDoc renders route documentation as Markdown for a chi router.
func MarkdownRoutesDoc(r chi.Router, opts MarkdownOpts) string {
md := &MarkdownDoc{Router: r, Opts: opts}
if err := md.Generate(); err != nil {
Expand Down Expand Up @@ -193,6 +198,8 @@ func (md *MarkdownDoc) WriteRoutes() {
}

func (md *MarkdownDoc) githubSourceURL(file string, line int) string {
file = moduleVersionInPath.ReplaceAllString(file, "")

// Currently, we only automatically link to source for github projects
if strings.Index(file, "github.com/") != 0 && !md.Opts.ForceRelativeLinks {
return ""
Expand Down
21 changes: 21 additions & 0 deletions markdown_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package docgen

import "testing"

func TestGithubSourceURLStripsModuleVersion(t *testing.T) {
md := &MarkdownDoc{
Opts: MarkdownOpts{
ProjectPath: "github.com/go-chi/chi/v5",
URLMap: map[string]string{
"github.com/go-chi/chi/v5": "https://github.com/go-chi/chi/tree/master",
},
},
}

file := "github.com/go-chi/chi/v5@v5.0.11/middleware/logger.go"
got := md.githubSourceURL(file, 39)
want := "https://github.com/go-chi/chi/tree/master/middleware/logger.go#L39"
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
}