Skip to content

Commit c7abc22

Browse files
committed
feat(docs): enhance documentation generation with JSON tags and inline references
- Introduced support for using JSON struct tags as field names in generated documentation by adding `UseJSONTags()` DSL function. - Added functionality to inline `$ref` schemas in JSON output with `InlineRefs()` DSL function. - Updated README.md to reflect new features and usage instructions. - Refactored code in `generate.go`, `generate_test.go`, and new `dsl` and `expr` packages to support these features. - Improved test coverage for new functionalities in documentation generation.
1 parent 0df7bcf commit c7abc22

5 files changed

Lines changed: 752 additions & 15 deletions

File tree

docs/README.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,14 @@ agnostic documentation in the form of a JSON document structured as follows:
9898

9999
## Enabling the Plugin
100100

101-
To enable the plugin simply import both the `docs` package as follows:
101+
To enable the plugin, import the docs DSL package in your design. Importing the DSL also registers the plugin automatically:
102102

103103
```go
104104
import (
105-
_ "goa.design/plugins/v3/docs"
105+
. "goa.design/plugins/v3/docs/dsl"
106106
. "goa.design/goa/v3/dsl"
107107
)
108108
```
109-
Note the use of blank identifier to import the `docs` package which is necessary
110-
as the package is imported solely for its side-effects (initialization).
111109

112110
## Effects on Code Generation
113111

@@ -121,3 +119,34 @@ If `goa gen` is invoked with a custom output path (i.e. with the `-o` argument)
121119
then the plugin appends to any pre-existing `doc.json` file instead of
122120
overwriting. Make sure to delete the file prior to running `goa gen` when using
123121
the `-o` option.
122+
123+
### Using JSON tags as field names
124+
125+
By default, the generated documentation uses attribute names as field names in definitions and examples. To instead use JSON struct tags declared via the `Meta("struct:tag:json", ...)` DSL, enable it in your design using the docs DSL (which also registers the plugin):
126+
127+
```go
128+
import (
129+
. "goa.design/plugins/v3/docs/dsl"
130+
. "goa.design/goa/v3/dsl"
131+
)
132+
133+
func init() {
134+
UseJSONTags()
135+
}
136+
```
137+
138+
When enabled, object property names in `definitions`, payloads, results, and error schemas/examples are renamed to match their JSON tag (the part before the first comma, e.g. `name,omitempty` becomes `name`). Fields tagged with `"-"` are ignored for renaming and keep their original names. The transformation does not mutate the Goa OpenAPI global definitions.
139+
140+
### Inlining $refs in JSON Schema
141+
142+
To inline `$ref` schemas where possible (while preserving cycles), enable it via the docs DSL:
143+
144+
```go
145+
import (
146+
. "goa.design/plugins/v3/docs/dsl"
147+
)
148+
149+
func init() {
150+
InlineRefs()
151+
}
152+
```

docs/dsl/docs.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dsl
2+
3+
import (
4+
"goa.design/plugins/v3/docs"
5+
"goa.design/plugins/v3/docs/expr"
6+
)
7+
8+
// init registers the docs plugin when importing the DSL.
9+
func init() { docs.Register() }
10+
11+
// UseJSONTags configures the docs plugin to use JSON struct tags declared via
12+
// Meta("struct:tag:json", ...) as field names in generated docs. This setting
13+
// affects definitions, payloads, results, and error schemas and examples.
14+
func UseJSONTags() { expr.Root.UseJSONTags = true }
15+
16+
// InlineRefs configures the docs plugin to inline referenced schemas in JSON
17+
// Schema output where possible. Cycles are preserved by keeping $ref.
18+
func InlineRefs() { expr.Root.InlineRefs = true }

docs/expr/root.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package expr
2+
3+
import (
4+
"goa.design/goa/v3/eval"
5+
"goa.design/goa/v3/expr"
6+
)
7+
8+
// Root is the design root expression for the docs plugin.
9+
var Root = &RootExpr{}
10+
11+
type (
12+
// RootExpr keeps track of docs plugin configuration toggles.
13+
RootExpr struct {
14+
// UseJSONTags instructs the docs generator to use JSON struct tags
15+
// specified via Meta ("struct:tag:json") as field names.
16+
UseJSONTags bool
17+
// InlineRefs instructs the docs generator to inline $ref schemas by
18+
// replacing them with copies of their referenced definitions where
19+
// possible. Cycles are preserved by leaving $ref in place when needed.
20+
InlineRefs bool
21+
}
22+
)
23+
24+
// Register design root with eval engine.
25+
func init() {
26+
_ = eval.Register(Root)
27+
}
28+
29+
// EvalName returns the name used in error messages.
30+
func (r *RootExpr) EvalName() string { return "Docs plugin" }
31+
32+
// WalkSets implements eval.Root. No-op; configuration is global.
33+
func (*RootExpr) WalkSets(eval.SetWalker) {}
34+
35+
// DependsOn tells the eval engine to run the goa DSL first.
36+
func (*RootExpr) DependsOn() []eval.Root { return []eval.Root{expr.Root} }
37+
38+
// Packages returns the import path to the Go packages that make up the DSL.
39+
// This is used to skip frames that point to files in these packages when
40+
// computing the location of errors.
41+
func (*RootExpr) Packages() []string { return []string{"goa.design/plugins/v3/docs/dsl"} }

0 commit comments

Comments
 (0)