Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output doc comments for package, structs, and fields. #405

Merged
merged 4 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/avrogen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type config struct {
TemplateFileName string

Pkg string
PkgDoc string
Out string
Tags string
FullName bool
Expand All @@ -36,6 +37,7 @@ func realMain(args []string, stdout, stderr io.Writer) int {
flgs := flag.NewFlagSet("avrogen", flag.ExitOnError)
flgs.SetOutput(stderr)
flgs.StringVar(&cfg.Pkg, "pkg", "", "The package name of the output file.")
flgs.StringVar(&cfg.PkgDoc, "pkgdoc", "", "The package doc comment to output.")
flgs.StringVar(&cfg.Out, "o", "", "The output file path to write to instead of stdout.")
flgs.StringVar(&cfg.Tags, "tags", "", "The additional field tags <tag-name>:{snake|camel|upper-camel|kebab}>[,...]")
flgs.BoolVar(&cfg.FullName, "fullname", false, "Use the full name of the Record schema to create the struct name.")
Expand Down Expand Up @@ -77,6 +79,7 @@ func realMain(args []string, stdout, stderr io.Writer) int {

opts := []gen.OptsFunc{
gen.WithFullName(cfg.FullName),
gen.WithPackageDoc(cfg.PkgDoc),
gen.WithEncoders(cfg.Encoders),
gen.WithInitialisms(initialisms),
gen.WithTemplate(string(template)),
Expand Down
4 changes: 2 additions & 2 deletions cmd/avrogen/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestAvroGen_RequiredFlags(t *testing.T) {
func TestAvroGen_GeneratesSchemaStdout(t *testing.T) {
var buf bytes.Buffer

args := []string{"avrogen", "-pkg", "testpkg", "testdata/schema.avsc"}
args := []string{"avrogen", "-pkg", "testpkg", "-pkgdoc", "package testpkg is generated from schema.avsc", "testdata/schema.avsc"}
gotCode := realMain(args, &buf, io.Discard)
require.Equal(t, 0, gotCode)

Expand All @@ -80,7 +80,7 @@ func TestAvroGen_GeneratesSchema(t *testing.T) {
t.Cleanup(func() { _ = os.RemoveAll(path) })

file := filepath.Join(path, "test.go")
args := []string{"avrogen", "-pkg", "testpkg", "-o", file, "testdata/schema.avsc"}
args := []string{"avrogen", "-o", file, "-pkg", "testpkg", "-pkgdoc", "package testpkg is generated from schema.avsc", "testdata/schema.avsc"}
gotCode := realMain(args, io.Discard, io.Discard)
require.Equal(t, 0, gotCode)

Expand Down
4 changes: 3 additions & 1 deletion cmd/avrogen/testdata/golden.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/avrogen/testdata/golden_encoders.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/avrogen/testdata/golden_fullname.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/avrogen/testdata/golden_stricttypes.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/avrogen/testdata/schema.avsc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"type": "record",
"name": "test",
"namespace": "a.b",
"doc": "Test is a test struct",
"fields": [
{ "name": "someString", "type": "string" },
{ "name": "someString", "type": "string", "doc": "SomeString is a string" },
{ "name": "someInt", "type": "int" }
]
}
33 changes: 28 additions & 5 deletions gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"maps"
"strings"
"text/template"
"unicode/utf8"

"github.com/ettle/strcase"
"github.com/hamba/avro/v2"
Expand Down Expand Up @@ -147,10 +148,28 @@ func WithStrictTypes(b bool) OptsFunc {
}
}

// WithPackageDoc configures the generator to output the given text as a package doc comment.
func WithPackageDoc(text string) OptsFunc {
return func(g *Generator) {
g.pkgdoc = ensureTrailingPeriod(text)
}
}

func ensureTrailingPeriod(text string) string {
if text == "" {
return text
}
if last, _ := utf8.DecodeLastRuneInString(text); last == '.' {
return text
}
return text + "."
}

// Generator generates Go structs from schemas.
type Generator struct {
template string
pkg string
pkgdoc string
tags map[string]TagStyle
fullName bool
encoders bool
Expand Down Expand Up @@ -257,7 +276,7 @@ func (g *Generator) resolveRecordSchema(schema *avro.RecordSchema) string {

typeName := g.resolveTypeName(schema)
if !g.hasTypeDef(typeName) {
g.typedefs = append(g.typedefs, newType(typeName, fields, schema.String()))
g.typedefs = append(g.typedefs, newType(typeName, schema.Doc(), fields, schema.String()))
}
return typeName
}
Expand Down Expand Up @@ -319,12 +338,12 @@ func (g *Generator) resolveLogicalSchema(logicalType avro.LogicalType) string {
return typ
}

func (g *Generator) newField(name, typ, avroFieldDoc, avroFieldName string) field {
func (g *Generator) newField(name, typ, doc, avroFieldName string) field {
return field{
Name: name,
Type: typ,
AvroFieldName: avroFieldName,
AvroFieldDoc: avroFieldDoc,
Doc: ensureTrailingPeriod(doc),
Tags: g.tags,
}
}
Expand Down Expand Up @@ -364,12 +383,14 @@ func (g *Generator) Write(w io.Writer) error {
data := struct {
WithEncoders bool
PackageName string
PackageDoc string
Imports []string
ThirdPartyImports []string
Typedefs []typedef
}{
WithEncoders: g.encoders,
PackageName: g.pkg,
PackageDoc: g.pkgdoc,
Imports: append(g.imports, g.thirdPartyImports...),
Typedefs: g.typedefs,
}
Expand All @@ -378,13 +399,15 @@ func (g *Generator) Write(w io.Writer) error {

type typedef struct {
Name string
Doc string
Fields []field
Schema string
}

func newType(name string, fields []field, schema string) typedef {
func newType(name string, doc string, fields []field, schema string) typedef {
nrwiersma marked this conversation as resolved.
Show resolved Hide resolved
return typedef{
Name: name,
Doc: ensureTrailingPeriod(doc),
Fields: fields,
Schema: schema,
}
Expand All @@ -393,7 +416,7 @@ func newType(name string, fields []field, schema string) typedef {
type field struct {
Name string
Type string
Doc string
AvroFieldName string
AvroFieldDoc string
Tags map[string]TagStyle
}
10 changes: 10 additions & 0 deletions gen/output_template.tmpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{{- if len .PackageDoc }}
// {{ .PackageDoc }}
{{- end }}
package {{ .PackageName }}

// Code generated by avro/gen. DO NOT EDIT.
Expand All @@ -12,10 +15,17 @@ package {{ .PackageName }}
{{ end }}

{{- range .Typedefs }}
{{- if len .Doc }}
// {{ .Doc }}
{{- else }}
// {{ .Name }} is a generated struct.
{{- end }}
type {{ .Name }} struct {
{{- range .Fields }}
{{- $f := . }}
{{- if len $f.Doc }}
// {{ $f.Doc }}
{{- end }}
{{ .Name }} {{ .Type }} `avro:"{{ $f.AvroFieldName }}"
{{- range $tag, $style := .Tags }}
{{- " "}}{{ $tag }}:"
Expand Down
3 changes: 3 additions & 0 deletions gen/testdata/golden.avsc
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
{
"type": "record",
"name": "test",
"doc": "Test represents a golden record",
"namespace": "a.b",
"fields": [
{
"name": "aString",
"doc": "aString is just a string",
"type": "string"
},
{
"name": "aBoolean",
"doc": "aBoolean is just a boolean.",
"type": "boolean"
},
{
Expand Down
6 changes: 4 additions & 2 deletions gen/testdata/golden.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions gen/testdata/golden_encoders.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions gen/testdata/golden_fullname.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading