Skip to content

Commit 6d1a7ba

Browse files
committed
feat: groups and apis can sort with order attr, api version attr output, remove main file args
1 parent 913e9d9 commit 6d1a7ba

File tree

12 files changed

+170
-117
lines changed

12 files changed

+170
-117
lines changed

cmd/apidoc/main.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,29 @@ import (
1111
func main() {
1212
var searchDir string
1313
var outputDir string
14-
var mainFile string
1514
var isSingle bool
1615
var isHelp bool
1716
flag.StringVar(&searchDir, "dir", ".", "--dir")
1817
flag.StringVar(&outputDir, "output", "./docs/", "--output")
19-
flag.StringVar(&mainFile, "main", "main.go", "--main")
2018
flag.BoolVar(&isSingle, "single", false, "--single")
2119
flag.BoolVar(&isHelp, "help", false, "--help")
2220
flag.Parse()
2321
if isHelp {
2422
fmt.Println(`apidoc is a tool for Go to generate apis markdown docs.
2523
2624
Usage:
27-
apidoc --dir= --output= --main= --single
25+
apidoc --dir= --output= --single
2826
2927
Flags:
3028
--dir: search apis dir, default .
3129
--output: generate markdown files dir, default ./docs/
32-
--main: the path of main go file, default main.go
3330
--single: generate single markdown file, default multi group files`)
3431
return
3532
}
3633
g := gen.New(&gen.Config{
37-
SearchDir: searchDir,
38-
MainFile: mainFile,
39-
OutputDir: outputDir,
40-
IsGenGroupFile: !isSingle,
34+
SearchDir: searchDir,
35+
OutputDir: outputDir,
36+
IsGenSingleFile: isSingle,
4137
})
4238
if err := g.Build(); err != nil {
4339
log.Fatal(err)

examples/docs/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ version: [email protected]_
2222

2323
2.5. [获取地址列表](./apis-address.md#5-获取地址列表)(Deprecated)
2424

25-
3. [资料管理](./apis-profile.md)
25+
3. [菜单管理](./apis-menu.md)
2626

27-
3.1. [获取用户资料](./apis-profile.md#1-获取用户资料)
27+
3.1. [获取菜单节点](./apis-menu.md#1-获取菜单节点)
2828

29-
4. [菜单管理](./apis-menu.md)
29+
4. [资料管理](./apis-profile.md)
3030

31-
4.1. [获取菜单节点](./apis-menu.md#1-获取菜单节点)
31+
4.1. [获取用户资料](./apis-profile.md#1-获取用户资料)
3232

3333
5. [测试示例](./apis-demo.md)
3434

examples/docs/apis-demo.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
### 1. struct数组
1616

17+
version: _1.0.2.1_
18+
1719
```text
1820
GET /user/demo/struct_array
1921
```
@@ -212,9 +214,9 @@ __Response__:
212214
{ //object(common.Response), 通用返回结果
213215
"code": 0, //int, 返回状态码
214216
"data": { //object(handler.DemoTime)
215-
"time_1": "2022-05-16T11:38:50.59873+08:00", //object(time.Time), example1
217+
"time_1": "2022-05-16T16:47:48.741899+08:00", //object(time.Time), example1
216218
"time_2": "2022-05-14 15:04:05", //object(time.Time), example2
217-
"time_3": "2022-05-16T11:38:50.598876+08:00" //object(time.Time)
219+
"time_3": "2022-05-16T16:47:48.742123+08:00" //object(time.Time)
218220
},
219221
"msg": "success" //string, 返回消息
220222
}

examples/svc-user/handler/account.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type RegisterResponse struct {
3535
//@response 200 common.Response{code=10011,msg="password format error"} "密码格式错误"
3636
//@author alovn
3737
//@desc 用户注册接口说明
38+
//@order -1
3839
func (h *AccountHandler) Register(w http.ResponseWriter, r *http.Request) {
3940
res := common.NewResponse(200, "注册成功", &RegisterResponse{
4041
Username: "abc",

examples/svc-user/handler/demo.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type DemoMap map[string]DemoData
3737
//@title struct数组
3838
//@group demo
3939
//@response 200 []DemoData "demo struct array"
40+
//@version 1.0.2.1
4041
func (h *DemoHandler) StructArray(w http.ResponseWriter, r *http.Request) {
4142

4243
}

examples/svc-user/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func main() {
5353
//@group demo
5454
//@title 测试示例
5555
//@desc 其它一些示例演示
56+
//@order 6
5657
{
5758
demo := handler.NewDemoHandler()
5859
mux.HandleFunc("/user/demo/struct_array", demo.StructArray)

gen/gen.go

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"sort"
9+
"strings"
810
"text/template"
911

1012
"github.com/alovn/apidoc"
@@ -21,35 +23,50 @@ func New(c *Config) *Gen {
2123
}
2224

2325
type Config struct {
24-
SearchDir string
25-
OutputDir string
26-
TemplateFile string
27-
MainFile string
28-
IsGenGroupFile bool
26+
SearchDir string
27+
OutputDir string
28+
TemplateFile string
29+
IsGenSingleFile bool
2930
}
3031

3132
func (g *Gen) Build() error {
3233
if g.c == nil {
3334
return errors.New("error config")
3435
}
3536
p := apidoc.New()
36-
if err := p.Parse(g.c.SearchDir, g.c.MainFile); err != nil {
37+
if err := p.Parse(g.c.SearchDir); err != nil {
3738
return err
3839
}
3940
doc := p.GetApiDoc()
40-
if doc.Title == "" && doc.Service == "" && len(doc.Apis) == 0 {
41-
fmt.Println("can't find apis")
41+
if doc.Service == "" {
42+
fmt.Println("apidoc @service is not set")
43+
return nil
44+
}
45+
if doc.Title == "" {
46+
fmt.Println("apidoc @title is not set")
47+
return nil
48+
}
49+
if doc.TotalCount == 0 {
50+
fmt.Println("apis count is 0")
4251
return nil
4352
}
4453

45-
if len(doc.Apis) > 0 {
54+
if len(doc.UngroupedApis) > 0 {
4655
doc.Groups = append(doc.Groups, &apidoc.ApiGroupSpec{
4756
Group: "ungrouped",
4857
Title: "ungrouped",
4958
Description: "Ungrouped apis",
50-
Apis: doc.Apis,
59+
Apis: doc.UngroupedApis,
5160
})
61+
doc.UngroupedApis = doc.UngroupedApis[:0]
5262
}
63+
sort.Slice(doc.Groups, func(i, j int) bool {
64+
a, b := doc.Groups[i], doc.Groups[j]
65+
if a.Order == b.Order {
66+
return strings.Compare(a.Group, b.Group) < 0
67+
}
68+
return a.Order < b.Order
69+
})
5370

5471
if err := os.MkdirAll(g.c.OutputDir, os.ModePerm); err != nil {
5572
return err
@@ -60,16 +77,44 @@ func (g *Gen) Build() error {
6077
return a + b
6178
},
6279
}
80+
sortApis := func(apis []*apidoc.ApiSpec) {
81+
less := func(i, j int) bool {
82+
a, b := apis[i], apis[j]
83+
return a.Order < b.Order
84+
}
85+
sort.Slice(apis, less)
86+
}
6387

64-
if g.c.IsGenGroupFile {
88+
if g.c.IsGenSingleFile {
89+
t := template.New("apis-single").Funcs(funcMap)
90+
t, err := t.Parse(singleApisTemplate)
91+
if err != nil {
92+
return err
93+
}
94+
f, err := os.Create(filepath.Join(g.c.OutputDir, "README.md"))
95+
if err != nil {
96+
return err
97+
}
98+
defer f.Close()
99+
for _, g := range doc.Groups {
100+
apis := g.Apis
101+
sortApis(apis)
102+
}
103+
104+
if err = t.Execute(f, doc); err != nil {
105+
return err
106+
}
107+
fmt.Println("generated: README.md")
108+
} else {
65109
//group
66-
t := template.New("group").Funcs(funcMap)
110+
t := template.New("group-apis").Funcs(funcMap)
67111
t, err := t.Parse(groupApisTemplate)
68112
if err != nil {
69113
return err
70114
}
71115
for _, v := range doc.Groups {
72116
group := v
117+
sortApis(group.Apis)
73118
fileName := fmt.Sprintf("apis-%s.md", group.Group)
74119
f, err := os.Create(filepath.Join(g.c.OutputDir, fileName))
75120
if err != nil {
@@ -83,7 +128,7 @@ func (g *Gen) Build() error {
83128
}
84129

85130
//readme
86-
t = template.New("apis").Funcs(funcMap)
131+
t = template.New("group-readme").Funcs(funcMap)
87132
t, err = t.Parse(groupReadmeTemplate)
88133
if err != nil {
89134
return err
@@ -97,26 +142,7 @@ func (g *Gen) Build() error {
97142
return err
98143
}
99144
fmt.Println("generated: README.md")
100-
101-
return nil
102-
}
103-
104-
t := template.New("apis-single").Funcs(funcMap)
105-
t, err := t.Parse(singleApisTemplate)
106-
if err != nil {
107-
return err
108-
}
109-
f, err := os.Create(filepath.Join(g.c.OutputDir, "README.md"))
110-
if err != nil {
111-
return err
112-
}
113-
defer f.Close()
114-
for _, g := range doc.Groups {
115-
doc.Apis = append(g.Apis, doc.Apis...)
116-
}
117-
if err = t.Execute(f, doc); err != nil {
118-
return err
119145
}
120-
fmt.Println("generated: README.md")
146+
fmt.Println("apis total count:", doc.TotalCount)
121147
return nil
122148
}

gen/template/group_apis.tpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ ___Deprecated___
2727
author: _{{$v.Author}}_
2828
{{- end}}
2929

30+
{{- if $v.Version}}
31+
32+
version: _{{$v.Version}}_
33+
{{- end}}
34+
3035
```text
3136
{{$v.HTTPMethod}} {{$v.FullURL}}
3237
```

gen/template/single.tpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ ___Deprecated___
3737
author: _{{$v.Author}}_
3838
{{- end}}
3939

40+
{{- if $v.Version}}
41+
42+
version: _{{$v.Version}}_
43+
{{- end}}
44+
4045
```text
4146
{{$v.HTTPMethod}} {{$v.FullURL}}
4247
```

operation.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
7474
return operation.ParseParametersComment(strings.TrimPrefix(lowerAttribute, "@"), lineRemainder, astFile)
7575
case deprecatedAttr, "deprecated:":
7676
operation.Deprecated = true
77+
case orderAttr:
78+
if i, err := strconv.Atoi(lineRemainder); err == nil {
79+
operation.Order = i
80+
}
81+
case versionAttr:
82+
operation.Version = lineRemainder
7783
}
7884
return nil
7985
}
@@ -105,7 +111,6 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
105111

106112
operation.HTTPMethod = httpMethod
107113
operation.Api = matches[2]
108-
operation.FullURL = fmt.Sprintf("%s/%s", strings.TrimSuffix(operation.parser.doc.BaseURL, "/"), strings.TrimPrefix(operation.Api, "/"))
109114
return nil
110115
}
111116

0 commit comments

Comments
 (0)