fix yaml format bug and generate file

This commit is contained in:
LinXiaoYi 2021-06-29 01:05:17 +08:00
parent 076856f2c7
commit 1ee9f1326b
4 changed files with 85 additions and 23 deletions

1
go.mod
View File

@ -19,6 +19,7 @@ require (
github.com/stretchr/testify v1.7.0
github.com/talos-systems/talos/pkg/machinery v0.0.0-20210625144407-2060ceaa0b16
golang.org/x/mod v0.4.2 // indirect
golang.org/x/text v0.3.6
golang.org/x/tools v0.1.3
gopkg.in/yaml.v2 v2.4.0
honnef.co/go/tools v0.1.4 // indirect

View File

@ -2,6 +2,7 @@ package beeParser
import (
"fmt"
"go/types"
"strconv"
"strings"
)
@ -33,7 +34,7 @@ func handleTailWhitespace(s string) string {
return s[0:i]
}
//handle value to remove head and tail space.
// Handle value to remove head and tail space.
func handleWhitespaceValues(values []string) []interface{} {
res := make([]interface{}, 0)
for _, v := range values {
@ -44,7 +45,7 @@ func handleWhitespaceValues(values []string) []interface{} {
return res
}
//try to transfer string to original type
// Transfer string to original type
func transferType(str string) interface{} {
if res, err := strconv.Atoi(str); err == nil {
return res
@ -55,8 +56,8 @@ func transferType(str string) interface{} {
return str
}
//parse annotation to generate array with key and values
//start with "@" as a key-value pair,key and values are separated by a space,wrap to distinguish values.
// Parse annotation to generate array with key and values
// start with "@" as a key-value pair,key and values are separated by a space,wrap to distinguish values.
func (a *Annotation) Annotate(annotation string) map[string]interface{} {
results := make(map[string]interface{})
//split annotation with '@'
@ -75,20 +76,54 @@ func (a *Annotation) Annotate(annotation string) map[string]interface{} {
return results
}
//create new annotation
//parse "Key","Default","Description" by annotation
//the type of "Key" and "Description" is string, "Default" is interface{}
func NewAnnotation(annotation string) *Annotation {
// Create new annotation,parse "Key","Default","Description" by annotation.
// If key and default value is empty by annotaion, set default key and value
// by params, default value according defaultType to generate
func NewAnnotation(annotation, defaultKey string, defaultType types.Type) *Annotation {
a := &Annotation{}
kvs := a.Annotate(annotation)
if v, ok := kvs["Key"]; ok {
a.Key = fmt.Sprintf("%v", v)
}
if v, ok := kvs["Description"]; ok {
a.Description = fmt.Sprintf("%v", v)
if ss, ok := v.([]interface{}); ok {
for i, s := range ss {
if i == 0 {
a.Description += s.(string)
continue
}
a.Description += "\n" + s.(string)
}
} else {
a.Description = fmt.Sprintf("%v", v)
}
}
if v, ok := kvs["Default"]; ok {
a.Default = v
}
if a.Key == "" {
//if key by parse is empty, set a default key
a.Key = defaultKey
}
if a.Default == nil {
//if default value is nil, set the default value according to the defaultType
a.Default = getDefaultValue(defaultType)
}
return a
}
// Get the default value according to the t, process bool/string/int
func getDefaultValue(t types.Type) interface{} {
switch tys := t.(type) {
case *types.Basic:
switch tys.Kind() {
case types.Bool:
return false
case types.Int, types.Int16, types.Int8, types.Int32, types.Int64, types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64, types.Uintptr, types.Float32, types.Float64:
return 0
case types.String:
return ""
}
}
return nil
}

View File

@ -2,6 +2,8 @@ package beeParser
import (
"encoding/json"
"io/ioutil"
"strings"
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
)
@ -10,10 +12,7 @@ type JsonFormatter struct {
}
func (f *JsonFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
annotation := NewAnnotation(field.Doc + field.Comment)
if annotation.Key == "" {
annotation.Key = field.Name
}
annotation := NewAnnotation(field.Doc+field.Comment, field.Name, field.Type)
res := map[string]interface{}{}
if field.NestedType != nil {
res[annotation.Key] = field.NestedType
@ -41,24 +40,34 @@ type Result map[string]interface{}
func (c Result) Doc() *encoder.Doc {
return &result
}
func (f *YamlFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
annotation := NewAnnotation(field.Doc + field.Comment)
if annotation.Key == "" {
annotation.Key = field.Name
}
annotation := NewAnnotation(field.Doc+field.Comment, field.Name, field.Type)
res := Result{}
// add head comment for this field
res.Doc().Comments[encoder.HeadComment] = annotation.Description
if field.NestedType != nil {
b, _ := field.NestedType.FormatFunc(field.NestedType)
// nestedType format result as this field value
b, err := field.NestedType.FormatFunc(field.NestedType)
if err != nil {
return nil, err
}
res[annotation.Key] = string(b)
} else {
res[annotation.Key] = annotation.Default
}
encoder := encoder.NewEncoder(&res, []encoder.Option{
encoder.WithComments(encoder.CommentsAll),
}...)
return encoder.Encode()
encodeByte, err := encoder.Encode()
if err != nil {
return nil, err
}
// when field.NestedType != nil, the key and nested value strings are encoded with "|"
// remove "|" by string replace
encodeByte = []byte(strings.Replace(string(encodeByte), annotation.Key+": |", annotation.Key+":", 1))
return encodeByte, nil
}
func (f *YamlFormatter) StructFormatFunc(node *StructNode) ([]byte, error) {
@ -71,5 +80,10 @@ func (f *YamlFormatter) StructFormatFunc(node *StructNode) ([]byte, error) {
}
func (f *YamlFormatter) Marshal(node *StructNode) ([]byte, error) {
return node.FormatFunc(node)
res, err := node.FormatFunc(node)
if err != nil {
return nil, err
}
ioutil.WriteFile(node.Name+".yaml", res, 0667)
return res, nil
}

View File

@ -25,6 +25,7 @@ type StructA struct {
// @Default https://github.com/beego/bee
// https://github.com/beego
// @Description comment of a of field2
// ssssss
a string
// @Key b
// @Default https://github.com/beego/bee https://github.com/beego
@ -38,6 +39,11 @@ type StructA struct {
// @Key NestField
// @Description comment of NestField
NestField StructB
Field5 float32
Field6 bool
Field7 string
Field8 interface{}
Field9 *StructB
}
`
@ -105,16 +111,22 @@ func ExampleYamlFormatter() {
// # comment of field1
// Field1: test
// # comment of b of field2
// Field2: |
// Field2:
// # comment of a of field2
// # ssssss
// a:
// - https://github.com/beego/bee
// - https://github.com/beego
// # comment of b of field2
// b: https://github.com/beego/bee https://github.com/beego
// # comment of field3
// Field3: null
// Field3: 0
// Field4: false
// NestField: |
// NestField:
// FieldB1: null
// Field5: 0
// Field6: false
// Field7: ""
// Field8: null
// Field9: null
}