Skip to content

Commit

Permalink
feat: add built-in apidocs template
Browse files Browse the repository at this point in the history
  • Loading branch information
alovn committed May 18, 2022
1 parent 313ee51 commit 3f6eb48
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 49 deletions.
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apidocgen is a tool for Go to generate apis markdown docs.
## Install

```bash
go install github.com/alovn/apidocgen/@latest
go install github.com/alovn/apidocgen@latest
```

## Usage
Expand All @@ -21,8 +21,43 @@ Flags:
--dir: Search apis dir, comma separated, default .
--excludes: Exclude directories and files when searching, comma separated
--output: Generate markdown files dir, default ./docs/
--template: Custom template files dir.
--template: Template name or custom template directory, built-in includes markdown and apidocs, default markdown.
--single: If true, generate a single markdown file, default false
```

built-in templates include `markdown`, `apidocs`, default is `markdown`.

run the command in the go module directory.

```bash
cd your-api-service-dir
apidocgen \
--dir=svc-user,common \
--output=./docs

apidocgen \
--dir=svc-user,common \
--template=apidocs \
--output=./docs


```

## Template

The built-in includes `markdown` and `apidocs`.

The built-in template `apidocs` is the template for generate website [apidocs](git@github.com:alovn/apidocs.git).

You can also use the custom template:

```bash
apidocgen \
--dir=svc-user,common \
--template=/Users/xxx/workspace/apidocs/custom-template-direcoty \
--output=./docs
```

## Examples

Some examples and generated markdown docs are here: [apidocgen/examples](https://github.com/alovn/apidocgen/tree/main/examples).
84 changes: 45 additions & 39 deletions gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,47 @@ import (
type Gen struct {
c *Config
templateFS fs.FS
defaultFS fs.FS
}

func New(c *Config) *Gen {
return &Gen{
c: c,
}
}

type Config struct {
SearchDir string
OutputDir string
TemplateDir string
ExcludesDir string
IsGenSingleFile bool
SearchDir string
OutputDir string
TemplateName string
CustomTemplateDir string
ExcludesDir string
IsGenSingleFile bool
}

type TemplateConfig struct {
Name string `json:"name"`
Index string `json:"index"`
}

func New(c *Config) *Gen {
var defaultTemplateName = "markdown"
if c.TemplateName == "" {
c.TemplateName = defaultTemplateName
}
if strings.ContainsAny(c.TemplateName, "/\\") {
c.CustomTemplateDir = c.TemplateName
c.TemplateName = ""
}
return &Gen{
c: c,
}
}

func (g *Gen) readTemplate(name string) (s string, err error) {
var bs []byte
if g.templateFS != nil {
if bs, err = fs.ReadFile(g.templateFS, name); err != nil {
return
} else {
s = string(bs)
return
}
if g.templateFS == nil {
err = errors.New("error: templateFS nil")
return
}
if bs, err = fs.ReadFile(g.templateFS, name); err != nil {
return
} else {
if bs, err = fs.ReadFile(g.defaultFS, name); err != nil {
return
} else {
s = string(bs)
return
}
s = string(bs)
return
}
}

Expand All @@ -69,29 +72,19 @@ func (g *Gen) Build() error {
}
}
var err error
if g.defaultFS == nil {
if g.defaultFS, err = fs.Sub(defaultTemplateFS, "template"); err != nil {
if g.c.CustomTemplateDir != "" {
g.templateFS = os.DirFS(g.c.CustomTemplateDir)
} else {
if g.templateFS, err = fs.Sub(defaultTemplateFS, fmt.Sprintf("template/%s", g.c.TemplateName)); err != nil {
return err
}
}

if g.templateFS == nil && g.c.TemplateDir != "" {
g.templateFS = os.DirFS(g.c.TemplateDir)
}
var templateSingleIndex string
var templateGroupIndex string
var templateGroupApis string
var templateConfig TemplateConfig

if templateSingleIndex, err = g.readTemplate("single_index.tpl"); err != nil {
return err
}
if templateGroupIndex, err = g.readTemplate("group_index.tpl"); err != nil {
return err
}
if templateGroupApis, err = g.readTemplate("group_apis.tpl"); err != nil {
return err
}
if s, err := g.readTemplate("config.json"); err != nil {
return err
} else {
Expand All @@ -104,6 +97,19 @@ func (g *Gen) Build() error {
fmt.Println("use template:", templateConfig.Name)
}

if g.c.IsGenSingleFile {
if templateSingleIndex, err = g.readTemplate("single_index.tpl"); err != nil {
return err
}
} else {
if templateGroupIndex, err = g.readTemplate("group_index.tpl"); err != nil {
return err
}
if templateGroupApis, err = g.readTemplate("group_apis.tpl"); err != nil {
return err
}
}

p := parser.New()
parser.SetExcludedDirsAndFiles(g.c.ExcludesDir)(p)
if err := p.Parse(searchDirs); err != nil {
Expand Down
4 changes: 4 additions & 0 deletions gen/template/apidocs/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name":"apidocs",
"index":"_index.md"
}
76 changes: 76 additions & 0 deletions gen/template/apidocs/group_apis.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: {{.Title}}
navtitle: {{.Title}}
weight: 3
---


## {{.Title}}
{{- if .Description}}

{{.Description}}
{{- end}}
{{range $k,$api := $.Apis}}
{{add $k 1}}. [{{$api.Title}}](#{{add $k 1}}-{{$api.Title}}) {{- if $api.Deprecated}}(Deprecated){{end}}
{{- end}}

## apis
{{- range $k,$v := .Apis}}

### {{add $k 1}}. {{$v.Title}}

{{- if $v.Deprecated}}

___Deprecated___
{{- end}}

{{- if $v.Description}}

{{$v.Description}}
{{- end}}

{{- if $v.Author}}

author: _{{$v.Author}}_
{{- end}}

{{- if $v.Version}}

version: _{{$v.Version}}_
{{- end}}

```text
{{$v.HTTPMethod}} {{$v.FullURL}}
```
{{- if $v.Requests.Parameters}}

__Request__:

parameter|parameterType|dataType|required|validate|example|description
--|--|--|--|--|--|--
{{- range $p:= $v.Requests.Parameters}}
__{{$p.Name}}__|_{{$p.ParameterTypes}}_|{{$p.DataType}}|{{$p.Required}}|{{$p.Validate}}|{{$p.Example}}|{{$p.Description}}
{{- end}}
{{- if $v.Requests.Body}}

_body_:

```{{if eq $v.Accept "json"}}javascript{{else}}{{$v.Accept}}{{end}}
{{$v.Requests.Body}}
```
{{- end}}
{{- end}}
{{- if $v.Responses}}

__Response__:
{{- range $res := $v.Responses}}

```{{if eq $v.Format "json"}}javascript{{else}}{{$v.Format}}{{end}}
//StatusCode: {{$res.StatusCode}} {{$res.Description}}
{{$res.Body}}
```
{{- end}}

---
{{- end}}
{{- end}}
21 changes: 21 additions & 0 deletions gen/template/apidocs/group_index.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: {{.Title}}
weight: 1
---

## {{.Title}} ({{.Service}})

{{- if .Version}}

version: _@{{.Version}}_
{{- end}}

{{- if .Description}}

{{.Description}}
{{- end}}
{{range $k,$v := .Groups}}
{{add $k 1}}. [{{$v.Title}}](./apis-{{$v.Group}})
{{range $k2,$api := $v.Apis}}
{{add $k 1}}.{{add $k2 1}}. [{{$api.Title}}](./apis-{{$api.Group}}#{{add $k2 1}}-{{$api.Title}}) {{- if $api.Deprecated}}(Deprecated){{end}}
{{end}}{{end}}
80 changes: 80 additions & 0 deletions gen/template/apidocs/single_index.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# {{.Title}} {{if .Service}} ({{.Service}}){{end}}

{{- if .Version}}

version: _@{{.Version}}_
{{- end}}

{{- if .Description}}

{{.Description}}
{{- end}}
{{range $k,$v := .Groups}}
{{add $k 1}}. [{{$v.Title}}](#{{add $k 1}}-{{$v.Title}})
{{range $k2,$api := $v.Apis}}
{{add $k 1}}.{{add $k2 1}}. [{{$api.Title}}](#{{add $k 1}}{{add $k2 1}}-{{$api.Title}}) {{- if $api.Deprecated}}(Deprecated){{end}}
{{end}}{{end}}
## apis
{{- range $k,$v := .Groups}}

### {{add $k 1}}. {{$v.Title}}
{{- range $k2,$v := $v.Apis}}

#### {{add $k 1}}.{{add $k2 1}}. {{$v.Title}}

{{- if $v.Deprecated}}

___Deprecated___
{{- end}}

{{- if $v.Description}}

{{$v.Description}}
{{- end}}

{{- if $v.Author}}

author: _{{$v.Author}}_
{{- end}}

{{- if $v.Version}}

version: _{{$v.Version}}_
{{- end}}

```text
{{$v.HTTPMethod}} {{$v.FullURL}}
```
{{- if $v.Requests.Parameters}}

__Request__:

parameter|parameterType|dataType|required|validate|example|description
--|--|--|--|--|--|--
{{- range $p:= $v.Requests.Parameters}}
__{{$p.Name}}__|_{{$p.ParameterTypes}}_|{{$p.DataType}}|{{$p.Required}}|{{$p.Validate}}|{{$p.Example}}|{{$p.Description}}
{{- end}}
{{- if $v.Requests.Body}}

_body_:

```{if eq $v.Accept "json"}}javascript{{else}}{{$v.Accept}}{{end}}
{{$v.Requests.Body}}
```
{{- end}}
{{- end}}
{{- if $v.Responses}}

__Response__:
{{- range $res := $v.Responses}}

```{if eq $v.Format "json"}}javascript{{else}}{{$v.Format}}{{end}}
//StatusCode: {{$res.StatusCode}} {{$res.Description}}
{{$res.Body}}
```
{{- end}}

---
{{- end}}
{{- end}}
{{- end}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name":"default",
"name":"markdown",
"index":"README.md"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 3f6eb48

Please sign in to comment.