Skip to content

Commit 518b18d

Browse files
authored
openapi3: move ref codegen to Go (#956)
* Move ref code gen from bash to go Keeps things in the go ecosystem and it will make a change I'll like to do far easier with go available. No changes to the generated refs.go other than a warning that it's generated to devs and IDEs. * Re-run ./docs.sh
1 parent 45b4399 commit 518b18d

File tree

6 files changed

+74
-42
lines changed

6 files changed

+74
-42
lines changed

.github/docs/openapi3.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Package openapi3 parses and writes OpenAPI 3 specification documents.
44

55
See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md
66

7+
Code generated by go generate; DO NOT EDIT.
8+
79
CONSTANTS
810

911
const (

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252

5353
- uses: actions/checkout@v2
5454

55-
- run: ./refs.sh | tee openapi3/refs.go
55+
- run: go generate openapi3/refsgenerator.go
5656
- run: git --no-pager diff --exit-code
5757

5858
- run: ./maps.sh

openapi3/ref.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package openapi3
22

3+
//go:generate go run refsgenerator.go
4+
35
// Ref is specified by OpenAPI/Swagger 3.0 standard.
46
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object
57
type Ref struct {

openapi3/refs.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
1-
#!/bin/bash -eux
2-
set -o pipefail
3-
4-
types=()
5-
types+=("Callback")
6-
types+=("Example")
7-
types+=("Header")
8-
types+=("Link")
9-
types+=("Parameter")
10-
types+=("RequestBody")
11-
types+=("Response")
12-
types+=("Schema")
13-
types+=("SecurityScheme")
14-
15-
cat <<EOF
16-
package openapi3
1+
// Code generated by go generate; DO NOT EDIT.
2+
package {{ .Package }}
173

184
import (
195
"context"
@@ -24,44 +10,38 @@ import (
2410
"github.com/go-openapi/jsonpointer"
2511
"github.com/perimeterx/marshmallow"
2612
)
27-
EOF
28-
29-
for type in "${types[@]}"; do
30-
cat <<EOF
31-
32-
// ${type}Ref represents either a ${type} or a \$ref to a ${type}.
13+
{{ range $type := .Types }}
14+
// {{ $type }}Ref represents either a {{ $type }} or a $ref to a {{ $type }}.
3315
// When serializing and both fields are set, Ref is preferred over Value.
34-
type ${type}Ref struct {
16+
type {{ $type }}Ref struct {
3517
Ref string
36-
Value *${type}
18+
Value *{{ $type }}
3719
extra []string
3820
}
3921

40-
var _ jsonpointer.JSONPointable = (*${type}Ref)(nil)
22+
var _ jsonpointer.JSONPointable = (*{{ $type }}Ref)(nil)
4123

42-
func (x *${type}Ref) isEmpty() bool { return x == nil || x.Ref == "" && x.Value == nil }
24+
func (x *{{ $type }}Ref) isEmpty() bool { return x == nil || x.Ref == "" && x.Value == nil }
4325

44-
// MarshalYAML returns the YAML encoding of ${type}Ref.
45-
func (x ${type}Ref) MarshalYAML() (interface{}, error) {
26+
// MarshalYAML returns the YAML encoding of {{ $type }}Ref.
27+
func (x {{ $type }}Ref) MarshalYAML() (interface{}, error) {
4628
if ref := x.Ref; ref != "" {
4729
return &Ref{Ref: ref}, nil
4830
}
4931
return x.Value.MarshalYAML()
5032
}
5133

52-
// MarshalJSON returns the JSON encoding of ${type}Ref.
53-
func (x ${type}Ref) MarshalJSON() ([]byte, error) {
34+
// MarshalJSON returns the JSON encoding of {{ $type }}Ref.
35+
func (x {{ $type }}Ref) MarshalJSON() ([]byte, error) {
5436
y, err := x.MarshalYAML()
5537
if err != nil {
5638
return nil, err
5739
}
5840
return json.Marshal(y)
59-
EOF
60-
cat <<EOF
6141
}
6242

63-
// UnmarshalJSON sets ${type}Ref to a copy of data.
64-
func (x *${type}Ref) UnmarshalJSON(data []byte) error {
43+
// UnmarshalJSON sets {{ $type }}Ref to a copy of data.
44+
func (x *{{ $type }}Ref) UnmarshalJSON(data []byte) error {
6545
var refOnly Ref
6646
if extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != "" {
6747
x.Ref = refOnly.Ref
@@ -77,8 +57,8 @@ func (x *${type}Ref) UnmarshalJSON(data []byte) error {
7757
return json.Unmarshal(data, &x.Value)
7858
}
7959

80-
// Validate returns an error if ${type}Ref does not comply with the OpenAPI spec.
81-
func (x *${type}Ref) Validate(ctx context.Context, opts ...ValidationOption) error {
60+
// Validate returns an error if {{ $type }}Ref does not comply with the OpenAPI spec.
61+
func (x *{{ $type }}Ref) Validate(ctx context.Context, opts ...ValidationOption) error {
8262
ctx = WithValidationOptions(ctx, opts...)
8363
if extra := x.extra; len(extra) != 0 {
8464
extras := make([]string, 0, len(extra))
@@ -102,13 +82,11 @@ func (x *${type}Ref) Validate(ctx context.Context, opts ...ValidationOption) err
10282
}
10383

10484
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
105-
func (x *${type}Ref) JSONLookup(token string) (interface{}, error) {
106-
if token == "\$ref" {
85+
func (x *{{ $type }}Ref) JSONLookup(token string) (interface{}, error) {
86+
if token == "$ref" {
10787
return x.Ref, nil
10888
}
10989
ptr, _, err := jsonpointer.GetForToken(x.Value, token)
11090
return ptr, err
11191
}
112-
EOF
113-
114-
done
92+
{{ end -}}

openapi3/refsgenerator.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//go:build ignore
2+
// +build ignore
3+
4+
// The program generates refs.go, invoke `go generate ./...` to run.
5+
package main
6+
7+
import (
8+
_ "embed"
9+
"os"
10+
"text/template"
11+
)
12+
13+
//go:embed refs.tmpl
14+
var tmplData string
15+
16+
func main() {
17+
file, err := os.Create("refs.go")
18+
if err != nil {
19+
panic(err)
20+
}
21+
22+
defer func() {
23+
if err := file.Close(); err != nil {
24+
panic(err)
25+
}
26+
}()
27+
28+
packageTemplate := template.Must(template.New("openapi3-refs").Parse(tmplData))
29+
30+
if err := packageTemplate.Execute(file, struct {
31+
Package string
32+
Types []string
33+
}{
34+
Package: os.Getenv("GOPACKAGE"), // set by the go:generate directive
35+
Types: []string{
36+
"Callback",
37+
"Example",
38+
"Header",
39+
"Link",
40+
"Parameter",
41+
"RequestBody",
42+
"Response",
43+
"Schema",
44+
"SecurityScheme",
45+
},
46+
}); err != nil {
47+
panic(err)
48+
}
49+
}

0 commit comments

Comments
 (0)