mirror of
https://github.com/beego/bee.git
synced 2024-11-24 08:30:53 +00:00
Merge pull request #792 from Codexiaoyi/parse-config
fix yaml format bug and generate file
This commit is contained in:
commit
0fd25d719b
1
go.mod
1
go.mod
@ -19,6 +19,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/talos-systems/talos/pkg/machinery v0.0.0-20210625144407-2060ceaa0b16
|
github.com/talos-systems/talos/pkg/machinery v0.0.0-20210625144407-2060ceaa0b16
|
||||||
golang.org/x/mod v0.4.2 // indirect
|
golang.org/x/mod v0.4.2 // indirect
|
||||||
|
golang.org/x/text v0.3.6
|
||||||
golang.org/x/tools v0.1.3
|
golang.org/x/tools v0.1.3
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
honnef.co/go/tools v0.1.4 // indirect
|
honnef.co/go/tools v0.1.4 // indirect
|
||||||
|
@ -2,6 +2,7 @@ package beeParser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/types"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -33,7 +34,7 @@ func handleTailWhitespace(s string) string {
|
|||||||
return s[0:i]
|
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{} {
|
func handleWhitespaceValues(values []string) []interface{} {
|
||||||
res := make([]interface{}, 0)
|
res := make([]interface{}, 0)
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
@ -44,7 +45,7 @@ func handleWhitespaceValues(values []string) []interface{} {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to transfer string to original type
|
// Transfer string to original type
|
||||||
func transferType(str string) interface{} {
|
func transferType(str string) interface{} {
|
||||||
if res, err := strconv.Atoi(str); err == nil {
|
if res, err := strconv.Atoi(str); err == nil {
|
||||||
return res
|
return res
|
||||||
@ -55,8 +56,8 @@ func transferType(str string) interface{} {
|
|||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
//parse annotation to generate array with key and 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.
|
// 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{} {
|
func (a *Annotation) Annotate(annotation string) map[string]interface{} {
|
||||||
results := make(map[string]interface{})
|
results := make(map[string]interface{})
|
||||||
//split annotation with '@'
|
//split annotation with '@'
|
||||||
@ -75,20 +76,54 @@ func (a *Annotation) Annotate(annotation string) map[string]interface{} {
|
|||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
//create new annotation
|
// Create new annotation,parse "Key","Default","Description" by annotation.
|
||||||
//parse "Key","Default","Description" by annotation
|
// If key and default value is empty by annotaion, set default key and value
|
||||||
//the type of "Key" and "Description" is string, "Default" is interface{}
|
// by params, default value according defaultType to generate
|
||||||
func NewAnnotation(annotation string) *Annotation {
|
func NewAnnotation(annotation, defaultKey string, defaultType types.Type) *Annotation {
|
||||||
a := &Annotation{}
|
a := &Annotation{}
|
||||||
kvs := a.Annotate(annotation)
|
kvs := a.Annotate(annotation)
|
||||||
if v, ok := kvs["Key"]; ok {
|
if v, ok := kvs["Key"]; ok {
|
||||||
a.Key = fmt.Sprintf("%v", v)
|
a.Key = fmt.Sprintf("%v", v)
|
||||||
}
|
}
|
||||||
if v, ok := kvs["Description"]; ok {
|
if v, ok := kvs["Description"]; ok {
|
||||||
|
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)
|
a.Description = fmt.Sprintf("%v", v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if v, ok := kvs["Default"]; ok {
|
if v, ok := kvs["Default"]; ok {
|
||||||
a.Default = v
|
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
|
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
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@ package beeParser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
"github.com/talos-systems/talos/pkg/machinery/config/encoder"
|
||||||
)
|
)
|
||||||
@ -10,10 +12,7 @@ type JsonFormatter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *JsonFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
|
func (f *JsonFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
|
||||||
annotation := NewAnnotation(field.Doc + field.Comment)
|
annotation := NewAnnotation(field.Doc+field.Comment, field.Name, field.Type)
|
||||||
if annotation.Key == "" {
|
|
||||||
annotation.Key = field.Name
|
|
||||||
}
|
|
||||||
res := map[string]interface{}{}
|
res := map[string]interface{}{}
|
||||||
if field.NestedType != nil {
|
if field.NestedType != nil {
|
||||||
res[annotation.Key] = field.NestedType
|
res[annotation.Key] = field.NestedType
|
||||||
@ -41,24 +40,34 @@ type Result map[string]interface{}
|
|||||||
func (c Result) Doc() *encoder.Doc {
|
func (c Result) Doc() *encoder.Doc {
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *YamlFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
|
func (f *YamlFormatter) FieldFormatFunc(field *StructField) ([]byte, error) {
|
||||||
annotation := NewAnnotation(field.Doc + field.Comment)
|
annotation := NewAnnotation(field.Doc+field.Comment, field.Name, field.Type)
|
||||||
if annotation.Key == "" {
|
|
||||||
annotation.Key = field.Name
|
|
||||||
}
|
|
||||||
res := Result{}
|
res := Result{}
|
||||||
// add head comment for this field
|
// add head comment for this field
|
||||||
res.Doc().Comments[encoder.HeadComment] = annotation.Description
|
res.Doc().Comments[encoder.HeadComment] = annotation.Description
|
||||||
if field.NestedType != nil {
|
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)
|
res[annotation.Key] = string(b)
|
||||||
} else {
|
} else {
|
||||||
res[annotation.Key] = annotation.Default
|
res[annotation.Key] = annotation.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder := encoder.NewEncoder(&res, []encoder.Option{
|
encoder := encoder.NewEncoder(&res, []encoder.Option{
|
||||||
encoder.WithComments(encoder.CommentsAll),
|
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) {
|
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) {
|
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
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ type StructA struct {
|
|||||||
// @Default https://github.com/beego/bee
|
// @Default https://github.com/beego/bee
|
||||||
// https://github.com/beego
|
// https://github.com/beego
|
||||||
// @Description comment of a of field2
|
// @Description comment of a of field2
|
||||||
|
// ssssss
|
||||||
a string
|
a string
|
||||||
// @Key b
|
// @Key b
|
||||||
// @Default https://github.com/beego/bee https://github.com/beego
|
// @Default https://github.com/beego/bee https://github.com/beego
|
||||||
@ -38,6 +39,11 @@ type StructA struct {
|
|||||||
// @Key NestField
|
// @Key NestField
|
||||||
// @Description comment of NestField
|
// @Description comment of NestField
|
||||||
NestField StructB
|
NestField StructB
|
||||||
|
Field5 float32
|
||||||
|
Field6 bool
|
||||||
|
Field7 string
|
||||||
|
Field8 interface{}
|
||||||
|
Field9 *StructB
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -105,16 +111,22 @@ func ExampleYamlFormatter() {
|
|||||||
// # comment of field1
|
// # comment of field1
|
||||||
// Field1: test
|
// Field1: test
|
||||||
// # comment of b of field2
|
// # comment of b of field2
|
||||||
// Field2: |
|
// Field2:
|
||||||
// # comment of a of field2
|
// # comment of a of field2
|
||||||
|
// # ssssss
|
||||||
// a:
|
// a:
|
||||||
// - https://github.com/beego/bee
|
// - https://github.com/beego/bee
|
||||||
// - https://github.com/beego
|
// - https://github.com/beego
|
||||||
// # comment of b of field2
|
// # comment of b of field2
|
||||||
// b: https://github.com/beego/bee https://github.com/beego
|
// b: https://github.com/beego/bee https://github.com/beego
|
||||||
// # comment of field3
|
// # comment of field3
|
||||||
// Field3: null
|
// Field3: 0
|
||||||
// Field4: false
|
// Field4: false
|
||||||
// NestField: |
|
// NestField:
|
||||||
// FieldB1: null
|
// FieldB1: null
|
||||||
|
// Field5: 0
|
||||||
|
// Field6: false
|
||||||
|
// Field7: ""
|
||||||
|
// Field8: null
|
||||||
|
// Field9: null
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user