【问题标题】:Golang template with switch & ForEach带有 switch 和 ForEach 的 Golang 模板
【发布时间】:2017-10-01 10:06:27
【问题描述】:

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

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

例如类似以下

为每个依赖项添加回显类型消息

#!/bin/bash
for a in $(dependencies.type) 
  echo $runner  //from type 
done

我所做的是以下不起作用

  1. 对于依赖类型 "runner1"(请参阅依赖结构实例中的类型属性值)我需要运行 几个命令 和对于 "runner2 " 我需要运行几个不同的命令
  2. 上面的那些命令(比如 echo api1 for runner1 等)应该写在我需要从模板创建的 bash.script 中

主包

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

【问题讨论】:

  • 您可能希望为此使用会话,因为您在此处所做的操作也不适用于多用户。
  • 看看这里,github.com/expressjs/session 一旦你有了一个会话处理程序,你就可以像 -> req.session.aaa = req.body.aa..
  • @JennyHilton 你在找这样的东西吗? play.golang.org/p/v65jr0Hr5v2
  • @mkopriva - 谢谢,我需要两件事 1. 使用模板的结果生成 bash.script 2. 对于每个条目(依赖类型)我需要调用 echo api1 和第二个echo api2 ,这是在安装对象中。
  • 请阅读此处的文档:golang.org/pkg/text/template 您的所有模板需求都在此处详细解释。请理解,您自己投入一些工作来解决问题是很重要的。我来这里是因为我想提供帮助和学习,我不是来这里免费工作的。

标签: templates go


【解决方案1】:

这里有一些最小的变化来解决上述问题:

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 数组上再次使用,遍历数据结构。

另一个变化只是写入标准输出,而不是写入文件。如果希望将其转换为脚本,只需将其通过管道传输到文件即可。

更广泛地说,我认为数据模型中围绕安装步骤的所有权存在张力。每种跑步者类型的安装步骤是否固定?或者它们可能会有所不同?如果它们是固定的,那么将运行器类型的 map[string][string] 映射到安装步骤数组可能是有意义的,这将减轻 Dependency 对象的安装步骤副本。

我也想知道 YAML - 它是真实的来源吗?还是衍生品?如果是导数,也许就没有必要了。让 go 程序询问真实的真实来源并生成脚本可能会更好。

无论如何,我希望这会有所帮助。

【讨论】:

  • 我无法测试它,我会给你分数,我有几个问题希望你能帮助......谢谢
  • @jennyhilton 当然,很高兴进一步交谈。
猜你喜欢
  • 2014-04-26
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多