mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 09:08:43 +08:00
fix: use yaml.v2 as yaml parser (#37423)
issue: #34298 Viper uses yaml.v2 as the parser. This PR will adopt the parsing logic from Viper to handle YAML files, ensuring maximum consistency in parsing. Signed-off-by: xianliang.li <xianliang.li@zilliz.com>
This commit is contained in:
parent
1b6edd0b4b
commit
81141bd18d
@ -17,10 +17,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"gopkg.in/yaml.v3"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/milvus-io/milvus/pkg/util/typeutil"
|
||||
)
|
||||
@ -80,48 +81,41 @@ func formatKey(key string) string {
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenNode(node *yaml.Node, parentKey string, result map[string]string) {
|
||||
// The content of the node should contain key-value pairs in a MappingNode
|
||||
if node.Kind == yaml.MappingNode {
|
||||
for i := 0; i < len(node.Content); i += 2 {
|
||||
keyNode := node.Content[i]
|
||||
valueNode := node.Content[i+1]
|
||||
func flattenAndMergeMap(prefix string, m map[string]interface{}, result map[string]string) {
|
||||
for k, v := range m {
|
||||
fullKey := k
|
||||
if prefix != "" {
|
||||
fullKey = prefix + "." + k
|
||||
}
|
||||
|
||||
key := keyNode.Value
|
||||
// Construct the full key with parent hierarchy
|
||||
fullKey := key
|
||||
if parentKey != "" {
|
||||
fullKey = parentKey + "." + key
|
||||
}
|
||||
|
||||
switch valueNode.Kind {
|
||||
case yaml.ScalarNode:
|
||||
// handle null value
|
||||
if valueNode.Tag == "!!null" {
|
||||
result[lowerKey(fullKey)] = ""
|
||||
result[formatKey(fullKey)] = ""
|
||||
switch val := v.(type) {
|
||||
case map[string]interface{}:
|
||||
flattenAndMergeMap(fullKey, val, result)
|
||||
case map[interface{}]interface{}:
|
||||
flattenAndMergeMap(fullKey, cast.ToStringMap(val), result)
|
||||
case []interface{}:
|
||||
str := ""
|
||||
for i, item := range val {
|
||||
itemStr, err := cast.ToStringE(item)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if i == 0 {
|
||||
str = itemStr
|
||||
} else {
|
||||
// Scalar value, store it as a string
|
||||
result[lowerKey(fullKey)] = valueNode.Value
|
||||
result[formatKey(fullKey)] = valueNode.Value
|
||||
str = str + "," + itemStr
|
||||
}
|
||||
case yaml.MappingNode:
|
||||
// Nested map, process recursively
|
||||
flattenNode(valueNode, fullKey, result)
|
||||
case yaml.SequenceNode:
|
||||
// List (sequence), process elements
|
||||
var listStr string
|
||||
for j, item := range valueNode.Content {
|
||||
if j > 0 {
|
||||
listStr += ","
|
||||
}
|
||||
if item.Kind == yaml.ScalarNode {
|
||||
listStr += item.Value
|
||||
}
|
||||
}
|
||||
result[lowerKey(fullKey)] = listStr
|
||||
result[formatKey(fullKey)] = listStr
|
||||
}
|
||||
result[lowerKey(fullKey)] = str
|
||||
result[formatKey(fullKey)] = str
|
||||
default:
|
||||
str, err := cast.ToStringE(val)
|
||||
if err != nil {
|
||||
fmt.Printf("cast to string failed %s, error = %s\n", fullKey, err.Error())
|
||||
continue
|
||||
}
|
||||
result[lowerKey(fullKey)] = str
|
||||
result[formatKey(fullKey)] = str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,9 +17,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
@ -27,7 +25,7 @@ import (
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/samber/lo"
|
||||
"go.uber.org/zap"
|
||||
"gopkg.in/yaml.v3"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/milvus-io/milvus/pkg/log"
|
||||
)
|
||||
@ -131,7 +129,7 @@ func (fs *FileSource) loadFromFile() error {
|
||||
}
|
||||
|
||||
ext := filepath.Ext(configFile)
|
||||
if len(ext) == 0 || ext[1:] != "yaml" {
|
||||
if len(ext) == 0 || (ext[1:] != "yaml" && ext[1:] != "yml") {
|
||||
return fmt.Errorf("Unsupported Config Type: " + ext)
|
||||
}
|
||||
|
||||
@ -140,26 +138,13 @@ func (fs *FileSource) loadFromFile() error {
|
||||
return errors.Wrap(err, "Read config failed: "+configFile)
|
||||
}
|
||||
|
||||
// handle empty file
|
||||
if len(data) == 0 {
|
||||
continue
|
||||
var config map[string]interface{}
|
||||
err = yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unmarshal yaml file "+configFile+" failed")
|
||||
}
|
||||
|
||||
var node yaml.Node
|
||||
decoder := yaml.NewDecoder(bytes.NewReader(data))
|
||||
if err := decoder.Decode(&node); err != nil && !errors.Is(err, io.EOF) {
|
||||
return errors.Wrap(err, "YAML unmarshal failed: "+configFile)
|
||||
}
|
||||
|
||||
if node.Kind == yaml.DocumentNode && len(node.Content) > 0 {
|
||||
// Get the content of the Document Node
|
||||
contentNode := node.Content[0]
|
||||
|
||||
// Recursively process the content of the Document Node
|
||||
flattenNode(contentNode, "", newConfig)
|
||||
} else if node.Kind == yaml.MappingNode {
|
||||
flattenNode(&node, "", newConfig)
|
||||
}
|
||||
flattenAndMergeMap("", config, newConfig)
|
||||
}
|
||||
|
||||
return fs.update(newConfig)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user