将通用地图转换为 YAML。语言

Convert a generic map to YAML. GoLang

因此,我正在开发一个程序,您必须在其中生成代表给定目录位置 (path) 的目录树的 YAML 文件。例如..

sc
├── file.go
├── file_test.go
└── src
    ├── deploy
    │   ├── deploy.go
    │   └── deploy_test.go
    ├── pod.go
    └── pod_test.go

这应该转换成

sc:
  fileTest: "true"
  src:
    deploy:
      deployTest: "true"
  podTest: "true"

注意上面只选择了带_test的文件(这是有条件的,问题不大)。我的问题是如何从可以通过 YAML 表示的目录树生成通用 map[string]interface{} 类型的映射。我已经尝试编写一个 DFS 实现来遍历树并生成一个 n-ary 树。其中有以下输出。我得到树的根 Node 对象。

name: sc
children:
- name: file.go
  children: []
- name: file_test.go
  children: []
- name: src
  children:
  - name: deploy
    children:
    - name: deploy.go
      children: []
    - name: deploy_test.go
      children: []
  - name: pod.go
    children: []
  - name: pod_test.go
    children: []

但如您所见,它是 unmarshalled 使用代表每个节点的数据类型。

//Node is the datatype which stores information regarding the file/directory
type Node struct {
    Name     string
    Path     string
    Children []*Node
}

我想要一个每个密钥都不同的通用 YAML。有任何想法吗?这样的事情会有所帮助。

func (node *Node) ToMap() map[string]interface{}{
 //Logic
}

生成树的 DFS 代码

func IteratePath(path string) {
    rootFile, err := os.Stat(path)
    if err != nil {
        logrus.Error("Path : ", path, " doesn't exist. ", err)
    }
    rootfile := ToFile(rootFile, path)
    stack := []*tree.Node{rootfile}
    for len(stack) > 0 {
        file := stack[len(stack)-1]
        stack = stack[:len(stack)-1]
        children, _ := ioutil.ReadDir(file.Path)
        for _, chld := range children {
            child := ToFile(chld, filepath.Join(file.Path, chld.Name()))
            file.Children = append(file.Children, child)
            stack = append(stack, child)
        }
    }

func ToFile(file os.FileInfo, path string) *tree.Node {
    outFile := tree.Node{
        Name:     file.Name(),
        Children: []*tree.Node{},
        Path:     path,
    }
    return &outFile
}

您已经在使用递归(使用堆栈变量而不是调用堆栈),那么为什么不再次使用递归将您的树转换为嵌套映射。这是我写的一个从节点开始的方法(基于上面的 Node 结构):

树到嵌套映射的方法:

type Node struct {
    Name     string
    Children []*Node
}

func (n *Node) ToMap() interface{} {
    if len(n.Children) < 1 {
        return "true"
    }

    yamlMap := make(map[string]interface{})

    for _, child := range n.Children {
        yamlMap[child.Name] = child.ToMap()
    }

    return yamlMap
}

此函数生成的地图可以通过 gopkg.in/yaml.v2 编组为您想要的格式的 YAML 文件。

这是 Go Playground 中的代码 运行,包括编组到 YAML