Skip to content

Commit e3bb142

Browse files
NerzalTobias Theel
authored andcommitted
Implementing OpenAPI 3.1.0 spec (#1513)
* fix x-tagGroups * fix module name * change paths * refactoring * update dependencies * stuff * add log * fix finding of main file * fix broken type resolution * fix bug * clean deps * fix tool after merging upstream * use json-iterator to marshal json * fix generating of json examples * update config used by jsoniter * bump version * update dependencies * resolve merge conflicts * use newest go in docker * yep * fix gen * fix gen * update swag version * yep * fix parser * fix some tests * fix all tests * parse most of general api description * implement security scheme parsing * parse oauth2 specs * parse scopes and extensions in security schemes * extend parsing security stuff * process v3 routes * meh * find unimported types * parse basic operation info * parse primitive and object parameters * generate openapi spec * fix module name * cleanup * update version to 2.0 * fix issues that appread after merging * cleanup after merge conflicts * fix all tests * add go 1.19 to workflows * pin dockerfile to 1.19.7 * Set minimum supported Go version to 1.18.x * parse response headers * copy readme * started to implement field parser * Refactor: use RefOrSpec instead of Spec * start to add tests for operationv3 * fix tests * implement allOf with primitive types * Add NestedPrimitiveArrayType test * implement TestParseResponseCommentWithNestedFieldsV3 * add more tests * parse arrays and maps * fix implementation of map types * implement more tests * fix example docs * adjust example * fix example jsons * support array types in Parameters * implement more tests, implement correct collectionFormat handling * finish implementation of operationv3 tests * all tests green * fix parsing of security definitions * add test for generalAPI info * end of day checkin * Update example.json * fix codeSamples from file and fix creation of operations * fix resolving of schema ref errors * fix tests that broke due to fixes on model parsing * Fix creating schemes of array types of custom objects * Fix resolution of refSchemas * cleanup * update dependencies * cleanup * Update README.md reset readme.md * Update README_zh-CN.md reset readme_zh-CN * update dependency * reset test file --------- Co-authored-by: Tobias Theel <[email protected]>
1 parent c85d570 commit e3bb142

File tree

3 files changed

+204
-1
lines changed

3 files changed

+204
-1
lines changed

field_parser.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const (
2121
swaggerTypeTag = "swaggertype"
2222
swaggerIgnoreTag = "swaggerignore"
2323
)
24+
var _ FieldParser = &tagBaseFieldParser{}
2425

2526
var _ FieldParser = &tagBaseFieldParser{}
2627

gen/genv3.go

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package gen
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io"
7+
"os"
8+
"path"
9+
"path/filepath"
10+
"strings"
11+
"text/template"
12+
"time"
13+
14+
"github.com/sv-tools/openapi/spec"
15+
"github.com/swaggo/swag"
16+
)
17+
18+
type openAPITypeWriter func(*Config, *spec.OpenAPI) error
19+
20+
func (g *Gen) writeDocOpenAPI(config *Config, openAPI *spec.OpenAPI) error {
21+
var filename = "docs.go"
22+
23+
if config.InstanceName != swag.Name {
24+
filename = config.InstanceName + "_" + filename
25+
}
26+
27+
docFileName := path.Join(config.OutputDir, filename)
28+
29+
absOutputDir, err := filepath.Abs(config.OutputDir)
30+
if err != nil {
31+
return err
32+
}
33+
34+
packageName := filepath.Base(absOutputDir)
35+
36+
docs, err := os.Create(docFileName)
37+
if err != nil {
38+
return err
39+
}
40+
defer docs.Close()
41+
42+
// Write doc
43+
err = g.writeGoDocV3(packageName, docs, openAPI, config)
44+
if err != nil {
45+
return err
46+
}
47+
48+
g.debug.Printf("create docs.go at %+v", docFileName)
49+
50+
return nil
51+
}
52+
53+
func (g *Gen) writeJSONOpenAPI(config *Config, swagger *spec.OpenAPI) error {
54+
var filename = "swagger.json"
55+
56+
if config.InstanceName != swag.Name {
57+
filename = config.InstanceName + "_" + filename
58+
}
59+
60+
jsonFileName := path.Join(config.OutputDir, filename)
61+
62+
b, err := g.jsonIndent(swagger)
63+
if err != nil {
64+
return err
65+
}
66+
67+
err = g.writeFile(b, jsonFileName)
68+
if err != nil {
69+
return err
70+
}
71+
72+
g.debug.Printf("create swagger.json at %+v", jsonFileName)
73+
74+
return nil
75+
}
76+
77+
func (g *Gen) writeYAMLOpenAPI(config *Config, swagger *spec.OpenAPI) error {
78+
var filename = "swagger.yaml"
79+
80+
if config.InstanceName != swag.Name {
81+
filename = config.InstanceName + "_" + filename
82+
}
83+
84+
yamlFileName := path.Join(config.OutputDir, filename)
85+
86+
b, err := g.json(swagger)
87+
if err != nil {
88+
return err
89+
}
90+
91+
y, err := g.jsonToYAML(b)
92+
if err != nil {
93+
return fmt.Errorf("cannot covert json to yaml error: %s", err)
94+
}
95+
96+
err = g.writeFile(y, yamlFileName)
97+
if err != nil {
98+
return err
99+
}
100+
101+
g.debug.Printf("create swagger.yaml at %+v", yamlFileName)
102+
103+
return nil
104+
}
105+
106+
func (g *Gen) writeGoDocV3(packageName string, output io.Writer, openAPI *spec.OpenAPI, config *Config) error {
107+
generator, err := template.New("swagger_info").Funcs(template.FuncMap{
108+
"printDoc": func(v string) string {
109+
// Add schemes
110+
v = "{\n \"schemes\": {{ marshal .Schemes }}," + v[1:]
111+
// Sanitize backticks
112+
return strings.Replace(v, "`", "`+\"`\"+`", -1)
113+
},
114+
}).Parse(packageTemplateV3)
115+
if err != nil {
116+
return err
117+
}
118+
119+
openAPISpec := spec.OpenAPI{
120+
Components: openAPI.Components,
121+
OpenAPI: openAPI.OpenAPI,
122+
Info: &spec.Extendable[spec.Info]{
123+
Spec: &spec.Info{
124+
Description: "{{escape .Description}}",
125+
Title: "{{.Title}}",
126+
Version: "{{.Version}}",
127+
TermsOfService: openAPI.Info.Spec.TermsOfService,
128+
Contact: openAPI.Info.Spec.Contact,
129+
License: openAPI.Info.Spec.License,
130+
Summary: openAPI.Info.Spec.Summary,
131+
},
132+
Extensions: openAPI.Info.Extensions,
133+
},
134+
ExternalDocs: openAPI.ExternalDocs,
135+
Paths: openAPI.Paths,
136+
WebHooks: openAPI.WebHooks,
137+
JsonSchemaDialect: openAPI.JsonSchemaDialect,
138+
Security: openAPI.Security,
139+
Tags: openAPI.Tags,
140+
Servers: openAPI.Servers,
141+
}
142+
143+
// crafted docs.json
144+
buf, err := g.jsonIndent(openAPISpec)
145+
if err != nil {
146+
return err
147+
}
148+
149+
buffer := &bytes.Buffer{}
150+
151+
err = generator.Execute(buffer, struct {
152+
Timestamp time.Time
153+
Doc string
154+
PackageName string
155+
Title string
156+
Description string
157+
Version string
158+
InstanceName string
159+
GeneratedTime bool
160+
}{
161+
Timestamp: time.Now(),
162+
GeneratedTime: config.GeneratedTime,
163+
Doc: string(buf),
164+
PackageName: packageName,
165+
Title: openAPI.Info.Spec.Title,
166+
Description: openAPI.Info.Spec.Description,
167+
Version: openAPI.Info.Spec.Version,
168+
InstanceName: config.InstanceName,
169+
})
170+
if err != nil {
171+
return err
172+
}
173+
174+
code := g.formatSource(buffer.Bytes())
175+
176+
// write
177+
_, err = output.Write(code)
178+
179+
return err
180+
}
181+
182+
var packageTemplateV3 = `// Code generated by swaggo/swag{{ if .GeneratedTime }} at {{ .Timestamp }}{{ end }}. DO NOT EDIT
183+
184+
package docs
185+
186+
import "github.com/swaggo/swag"
187+
188+
const docTemplate{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }} = ` + "`{{ printDoc .Doc}}`" + `
189+
190+
// SwaggerInfo{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }} holds exported Swagger Info so clients can modify it
191+
var SwaggerInfo{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }} = &swag.Spec{
192+
Version: {{ printf "%q" .Version}},
193+
Title: {{ printf "%q" .Title}},
194+
Description: {{ printf "%q" .Description}},
195+
InfoInstanceName: {{ printf "%q" .InstanceName }},
196+
SwaggerTemplate: docTemplate{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }},
197+
}
198+
199+
func init() {
200+
swag.Register(SwaggerInfo{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }}.InstanceName(), SwaggerInfo{{ if ne .InstanceName "swagger" }}{{ .InstanceName }} {{- end }})
201+
}
202+
`

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/swaggo/swag/v2
1+
module github.com/swaggo/swag
22

33
go 1.18
44

0 commit comments

Comments
 (0)