Golang模板与开关&的ForEach

时间:2017-10-01 10:06:27

标签: templates go

我需要从golang程序创建 bash.sh 文件 应该执行以下操作:

在依赖项上创建 ForEach 循环,并根据类型读取类型 打印不同的回显消息(命令)我需要它来使用开关 在与Golang的依赖关系type

e.g。类似于以下内容

对于每个依赖项,添加echo

的类型消息
#!/bin/bash
for a in $(dependencies.type) 
  echo $runner  //from type 
done

我所做的是以下哪些不起作用

  1. 依赖关系类型" runner1" 的想法(请参阅依赖关系结构实例中的type属性值)我需要运行几个命令并且" runner2" 我需要运行几个不同的命令
  2. 上面的那些命令(比如echo1的echo api1)应该写在我需要从模板创建的bash.script中
  3. package main

    import (
        "fmt"
        "log"
        "text/template"
        "gopkg.in/yaml.v2"
        "os"
    )
    
    type File struct {
        TypeVersion string `yaml:"_type-version"`
        Dependency  []Dependency
    }
    
    type Dependency struct {
        Name    string
        Type    string
        CWD     string
        Install []Install
    }
    
    type Install map[string]string
    
    var data = `
    _type-version: "1.0.0"
    dependency:
      - name: ui
        type: runner
        cwd: /ui
        install:
           - name: api
    
      - name: ui2
        type: runner2
        cwd: /ui2
        install:
           - name: api2
    
    `
    
    func main() {
        f := File{}
    
        err := yaml.Unmarshal([]byte(data), &f)
        if err != nil {
            log.Fatalf("error: %v", err)
        }
    
        d, err := yaml.Marshal(&f)
        if err != nil {
            log.Fatalf("error: %v", err)
        }
        fmt.Printf("--- t dump:\n%s\n\n", string(d))
    
        wd, _ := os.Getwd()
    
        newfile, err := os.Create(wd + "/" + "bash.sh") // Truncates if file already exists
        if err != nil {
            fmt.Errorf("Failed to create file: %s , %s", wd+"/"+"bash.sh", err)
        }
    
        fmt.Println(newfile)
    
        const File = `
    #!/bin/bash
    {{.dependency}},
    {{if .Type runner2}}
     echo "type is runner2"
    {{- else}}
    echo "type is %S"
    {{- end}}
    {{end}}
    `
    
        t := template.Must(template.New("bash.sh").Parse(File))
    
        for _, r := range f.Dependency {
            err := t.Execute(os.Stdout, r)
            if err != nil {
                log.Println("executing template:", err)
            }
        }
    
    }
    

    更新

    例如

    让我说我的映射如下,依赖结构应该与API结构一起使用,以了解为每个类型值运行的命令

    API := map[string]string {
    {
    “runner1” : “api1”,
    },
    {
    “runner2” : “api2”,
    }
    }
    

    这就是脚本在最后应该是什么样子

    #bin/bash
    
    // in context of dep1
    echo runner1
    submitting api1
    
    
    // in context of dep2
    echo runner2
    submitting api2
    

1 个答案:

答案 0 :(得分:2)

上面的一些最小变化是:

package main

import (
    "log"
    "text/template"
    "gopkg.in/yaml.v2"
    "os"
)

type File struct {
    TypeVersion string `yaml:"_type-version"`
    Dependency  []Dependency
}

type Dependency struct {
    Name    string
    Type    string
    CWD     string
    Install []Install
}

type Install map[string]string

var data = `
_type-version: "1.0.0"
dependency:
  - name: ui
    type: runner
    cwd: /ui
    install:
       - name: api

  - name: ui2
    type: runner2
    cwd: /ui2
    install:
       - name: api2

`

func main() {
    f := File{}

    err := yaml.Unmarshal([]byte(data), &f)
    if err != nil {
        log.Fatalf("error: %v", err)
    }

   const t = `
#!/bin/bash

{{range .Dependency}}
echo "type is {{.Type}}"
echo "cwd is {{.CWD}}"
{{range .Install}}
echo "install {{.name}}"
{{end}}
{{end}}
`

    tt := template.Must(template.New("").Parse(t))
    err = tt.Execute(os.Stdout, f)
    if err != nil {
        log.Println("executing template:", err)
    }
}

这会产生

$ go run main.go 

#!/bin/bash


echo "type is runner"
echo "cwd is /ui"

echo "install api"


echo "type is runner2"
echo "cwd is /ui2"

echo "install api2"

关键的变化是让模板完成工作 - 使用Dependency数组上的range函数,然后再使用Install数组来遍历数据结构。

另一个变化就是写入stdout而不是写入文件。如果需要将其转换为脚本,只需将其传递给文件即可。

更广泛地说,我认为数据模型在安装步骤的所有权方面存在紧张。是否为每种跑步者类型修复了安装步骤?或者他们会变化吗?如果它们被修复,那么将一个map [string] [string]的runner类型转换为安装步骤数组可能是有意义的,这将减轻Dependency对象的安装步骤副本。

我也想知道YAML-它是真相的来源吗?还是衍生品?如果衍生,也许它是不必要的。可能更好的让go程序询问实际的事实来源并生成一个脚本。

无论如何,我希望这对你有帮助。