forked from ignite/cli
/
generate_openapi.go
103 lines (84 loc) · 2.39 KB
/
generate_openapi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package cosmosgen
import (
"os"
"path/filepath"
"sort"
"github.com/iancoleman/strcase"
"github.com/notional-labs/tinyport/tinyport/pkg/cosmosanalysis/module"
swaggercombine "github.com/notional-labs/tinyport/tinyport/pkg/nodetime/programs/swagger-combine"
"github.com/notional-labs/tinyport/tinyport/pkg/protoc"
)
var openAPIOut = []string{
"--openapiv2_out=logtostderr=true,allow_merge=true,fqn_for_openapi_name=true,simple_operation_ids=true,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types:.",
}
func generateOpenAPISpec(g *generator) error {
out := filepath.Join(g.appPath, g.o.specOut)
var (
specDirs []string
conf = swaggercombine.Config{
Swagger: "2.0",
Info: swaggercombine.Info{
Title: "HTTP API Console",
},
}
)
defer func() {
for _, dir := range specDirs {
os.RemoveAll(dir)
}
}()
// gen generates a spec for a module where it's source code resides at src.
// and adds needed swaggercombine configure for it.
gen := func(src string, m module.Module) (err error) {
include, err := g.resolveInclude(src)
if err != nil {
return err
}
dir, err := os.MkdirTemp("", "gen-openapi-module-spec")
if err != nil {
return err
}
err = protoc.Generate(
g.ctx,
dir,
m.Pkg.Path,
include,
openAPIOut,
)
if err != nil {
return err
}
specDirs = append(specDirs, dir)
specPath := filepath.Join(dir, "apidocs.swagger.json")
return conf.AddSpec(strcase.ToCamel(m.Pkg.Name), specPath)
}
// generate specs for each module and persist them in the file system
// after add their path and config to swaggercombine.Config so we can combine them
// into a single spec.
add := func(src string, modules []module.Module) error {
for _, m := range modules {
m := m
if err := gen(src, m); err != nil {
return err
}
}
return nil
}
// protoc openapi generator acts weird on conccurrent run, so do not use goroutines here.
if err := add(g.appPath, g.appModules); err != nil {
return err
}
for src, modules := range g.thirdModules {
if err := add(src, modules); err != nil {
return err
}
}
sort.Slice(conf.APIs, func(a, b int) bool { return conf.APIs[a].ID < conf.APIs[b].ID })
// ensure out dir exists.
outDir := filepath.Dir(out)
if err := os.MkdirAll(outDir, 0766); err != nil {
return err
}
// combine specs into one and save to out.
return swaggercombine.Combine(g.ctx, conf, out)
}