Skip to content

Commit

Permalink
Merge pull request #17 from g4s8/i13-embedded-struct
Browse files Browse the repository at this point in the history
fix: use field doc for embedded struct field type
  • Loading branch information
g4s8 committed Mar 29, 2024
2 parents 4c5f257 + 62ace24 commit 4c4d50f
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 22 deletions.
14 changes: 14 additions & 0 deletions _examples/embedded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import "time"

//go:generate go run ../ -output embedded.md
type Config struct {
// Start date.
Start Date `env:"START,notEmpty"`
}

// Date is a time.Time wrapper that uses the time.DateOnly layout.
type Date struct {
time.Time
}
6 changes: 6 additions & 0 deletions _examples/embedded.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Environment Variables

## Config

- `START` (**required**, non-empty) - Start date.

12 changes: 12 additions & 0 deletions _examples/typedef.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import "time"

//go:generate go run ../ -output typedef.md
type Config struct {
// Start date.
Start Date `env:"START"`
}

// Date is a time.Time wrapper that uses the time.DateOnly layout.
type Date time.Time
2 changes: 1 addition & 1 deletion _examples/typeonly.md → _examples/typedef.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

## Config

- `SOME_TIME` - Some time.
- `START` - Start date.

18 changes: 0 additions & 18 deletions _examples/typeonly.go

This file was deleted.

21 changes: 18 additions & 3 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type visitorNode struct {
names []string // it's possible that a field has multiple names
doc string // field or type documentation or comment if doc is empty
children []*visitorNode // optional children nodes for structs
parent *visitorNode // parent node
typeRef *visitorNode // type reference if field is a struct
tag string // field tag
isArray bool // true if field is an array
Expand Down Expand Up @@ -58,6 +59,7 @@ func newAstVisitor(commentsHandler astCommentsHandler, typeDocsResolver astTypeD
}

func (v *astVisitor) push(node *visitorNode, appendChild bool) *astVisitor {
node.parent = v.currentNode
if appendChild {
v.currentNode.children = append(v.currentNode.children, node)
}
Expand Down Expand Up @@ -89,7 +91,7 @@ func (v *astVisitor) Visit(n ast.Node) ast.Visitor {
}
return v
case *ast.TypeSpec:
v.logger.Printf("ast(%d): visit type: %q", v.depth, t.Name.Name)
v.logger.Printf("ast(%d): visit type (%T): %q", v.depth, t.Type, t.Name.Name)
doc := v.typeDocResolver(t)
name := t.Name.Name
if v.pendingType {
Expand All @@ -105,7 +107,20 @@ func (v *astVisitor) Visit(n ast.Node) ast.Visitor {
}
return v.push(typeNode, true)
case *ast.StructType:
v.logger.Printf("ast(%d): found struct", v.depth)
v.logger.Printf("ast(%d): found struct (`%T`, incomplete: %t, fields: %v)", v.depth, t, t.Incomplete, len(t.Fields.List))
embedStruct := true
for i, f := range t.Fields.List {
if len(f.Names) > 0 {
embedStruct = false
break
}
v.logger.Printf("ast(%d): debug struct field [%d]%v ", v.depth, i, f.Names)
}
if embedStruct {
v.logger.Printf("ast(%d): struct is embedded", v.depth)
return v
}

switch v.currentNode.kind {
case nodeType:
v.currentNode.kind = nodeStruct
Expand All @@ -122,7 +137,7 @@ func (v *astVisitor) Visit(n ast.Node) ast.Visitor {
}
case *ast.Field:
names := fieldNamesToStr(t)
v.logger.Printf("ast(%d): visit field (%v)", v.depth, names)
v.logger.Printf("ast(%d): visit field ([%d]%v)", v.depth, len(names), names)
doc := getFieldDoc(t)
var (
tag string
Expand Down
21 changes: 21 additions & 0 deletions inspector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,27 @@ func TestInspector(t *testing.T) {
},
},
},
{
name: "embedded.go",
typeName: "Config",
expect: []*EnvDocItem{
{
Name: "START",
Doc: "Start date.",
Opts: EnvVarOptions{Required: true, NonEmpty: true},
},
},
},
{
name: "typedef.go",
typeName: "Config",
expect: []*EnvDocItem{
{
Name: "START",
Doc: "Start date.",
},
},
},
} {
scopes := c.expectScopes
if scopes == nil {
Expand Down
13 changes: 13 additions & 0 deletions testdata/embedded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package testdata

import "time"

type Config struct {
// Start date.
Start Date `env:"START,notEmpty"`
}

// Date is a time.Time wrapper that uses the time.DateOnly layout.
type Date struct {
time.Time
}
11 changes: 11 additions & 0 deletions testdata/typedef.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package testdata

import "time"

type Config struct {
// Start date.
Start Date `env:"START"`
}

// Date is a time.Time wrapper that uses the time.DateOnly layout.
type Date time.Time

0 comments on commit 4c4d50f

Please sign in to comment.