Files
chatservice_concept/vendor/github.com/go-chi/docgen/builder.go
2024-12-29 23:29:33 -05:00

127 lines
2.4 KiB
Go

package docgen
import (
"errors"
"fmt"
"net/http"
"path/filepath"
"strings"
"github.com/go-chi/chi/v5"
)
func BuildDoc(r chi.Routes) (Doc, error) {
d := Doc{}
goPath := getGoPath()
if goPath == "" {
return d, errors.New("docgen: unable to determine your $GOPATH")
}
// Walk and generate the router docs
d.Router = buildDocRouter(r)
return d, nil
}
func buildDocRouter(r chi.Routes) DocRouter {
rts := r
dr := DocRouter{Middlewares: []DocMiddleware{}}
drts := DocRoutes{}
dr.Routes = drts
for _, mw := range rts.Middlewares() {
dmw := DocMiddleware{
FuncInfo: buildFuncInfo(mw),
}
dr.Middlewares = append(dr.Middlewares, dmw)
}
for _, rt := range rts.Routes() {
drt := DocRoute{Pattern: rt.Pattern, Handlers: DocHandlers{}}
if rt.SubRoutes != nil {
subRoutes := rt.SubRoutes
subDrts := buildDocRouter(subRoutes)
drt.Router = &subDrts
} else {
hall := rt.Handlers["*"]
for method, h := range rt.Handlers {
if method != "*" && hall != nil && fmt.Sprintf("%v", hall) == fmt.Sprintf("%v", h) {
continue
}
dh := DocHandler{Method: method, Middlewares: []DocMiddleware{}}
var endpoint http.Handler
chain, _ := h.(*chi.ChainHandler)
if chain != nil {
for _, mw := range chain.Middlewares {
dh.Middlewares = append(dh.Middlewares, DocMiddleware{
FuncInfo: buildFuncInfo(mw),
})
}
endpoint = chain.Endpoint
} else {
endpoint = h
}
dh.FuncInfo = buildFuncInfo(endpoint)
drt.Handlers[method] = dh
}
}
drts[rt.Pattern] = drt
}
return dr
}
func buildFuncInfo(i interface{}) FuncInfo {
fi := FuncInfo{}
frame := getCallerFrame(i)
goPathSrc := filepath.Join(getGoPath(), "src")
if frame == nil {
fi.Unresolvable = true
return fi
}
pkgName := getPkgName(frame.File)
if pkgName == "chi" {
fi.Unresolvable = true
}
funcPath := frame.Func.Name()
idx := strings.Index(funcPath, "/"+pkgName)
if idx > 0 {
fi.Pkg = funcPath[:idx+1+len(pkgName)]
fi.Func = funcPath[idx+2+len(pkgName):]
} else {
fi.Func = funcPath
}
if strings.Index(fi.Func, ".func") > 0 {
fi.Anonymous = true
}
fi.File = frame.File
fi.Line = frame.Line
if filepath.HasPrefix(fi.File, goPathSrc) {
fi.File = fi.File[len(goPathSrc)+1:]
}
// Check if file info is unresolvable
if !strings.Contains(funcPath, pkgName) {
fi.Unresolvable = true
}
if !fi.Unresolvable {
fi.Comment = getFuncComment(frame.File, frame.Line)
}
return fi
}