Golang模板,带开关&的ForEach [英] Golang template with switch & ForEach

查看:90
本文介绍了Golang模板,带开关&的ForEach的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

创建 ForEach 循环依赖关系并读取类型并根据类型
打印不同的echo消息(命令)我需要它在<$ c上使用 switch
$ c>输入与Golang的依赖关系



例如如下所示



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

 #!/ bin / bash 
for $(dependencies.type)
echo $ runner //从类型
完成

我所做的是以下哪项行不通


  1. 为依赖关系输入runner1(请参阅依赖关系结构实例中的type属性值)我需要运行几个命令runner2我需要运行几个不同的命令

  2. 这些命令(比如runner1的echo api1等)应该写在我需要的bash.script中从模板创建

package main

  
fmt
log
text / template
gopkg.in/yaml.v2
os


类型文件struct {
TypeVersion string`yaml:_ type-ver sion`
依赖项[]依赖项
}

类型依赖项struct {
名称字符串
类型字符串
CWD字符串
安装[]安装
}

类型安装映射[字符串]字符串

var data =`
_type-version:1.0.0
依赖项:
- 名称:ui
类型:runner
cwd:/ ui
安装:
- 名称: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)
}
$ bd,err:= yaml.Marshal(& f)
if err!=无{
log.Fatalf(error:%v,err)
}
fmt.Printf(--- t dump:\ n%s \\\
\\\
,string(d))

wd,_:= os.Getwd()

newfile,err:= os.Create(wd +/+bash .sh)//截断如果文件已经存在
if err!= nil {
fmt.Errorf(创建文件失败:%s,%s,wd +/+bash.sh,err)


fmt.Println(newfile)

const File =`
#!/ bin / bash
{{.dependency}} ,
{{if .Type runner2}}
echotype is runner2
{{else}}
echotype is%S
{{ - 结束}}
{{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(执行模板:,err)
}
}

}

更新

例如

可以说我已经绘制了如下图,并且依赖关系结构应该与API结构一起使用,以便知道为每个类型值运行哪个命令。

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

这就是脚本最后的样子

 #bin / bash 

//在dep1的上下文中
echo runner1
提交api1


//在上下文中dep2
echo runner2
submitting api2


解决方案

<

  package main 

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


类型文件struct {
TypeVersion字符串`yaml:_ type-version`
依赖项[]依赖项
}

类型依赖项结构{
名称字符串
类型字符串
CWD字符串
安装[]安装
}

类型安装映射[字符串]字符串

var数据=`
_type-version:1.0.0
依赖密码:
- 名称:ui
类型:runner
cwd:/ ui
安装:
- 名称:api

- 名称: ui2
类型: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}}
echotype is {{.Type}}
echocwd is {{.CWD}}
{{range .Install}}
echoinstall {{.name}}
{{end}}
{{end}}
`

tt:= template.Must(template .new()。Parse(t))
err = tt.Execute(os.Stdout,f)
if err!= nil {
log.Println(execution template: ,err)
}
}

这会产生

  $ go run main.go 

#!/ bin / bash


回声类型是亚军
回声cw d是/ ui

echoinstall api


echotype is runner2
echocwd is / ui2

echoinstall api2

关键更改是让模板执行工作 - 在依赖数组上使用范围函数,然后在安装数组上再次遍历数据结构。

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

更广泛地说,我认为数据模型在安装步骤的所有权方面存在紧张局势。每个跑步者类型的安装步骤是否都已修复?或者它们可能有所不同如果它们是固定的,那么将runner类型的map [string] [string]映射到安装步骤数组可能是有道理的,然后可以减轻Dependency对象的安装步骤副本。

我也想知道YAML--它是真相的来源吗?或者它是衍生的?如果派生,也许这是没有必要的。可能更好的是让程序查询真实的真实来源并生成一个脚本。

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

I need to create bash.sh file from golang program which should do the following:

Create ForEach loop on dependencies and read the type and according to type print different echo message (commands) I need it to work with switch on the type of the dependency with Golang

e.g. something like following

For each dependency entry add the type message of echo

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

what I did is the following which doesn't work

  1. The idea that for dependencies type "runner1"(see the type property value in dependency struct instance) I need to run several commands and for "runner2" I need to run several different commands
  2. And those commands (like echo api1 for runner1 etc )above should be written in the bash.script that I need to create from the template

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)
        }
    }

}

update

For example

lets say i’ve map like following and the dependencies struct should work with the API struct to know which command to run for each type value

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

This is how should the script look like at the end

#bin/bash

// in context of dep1
echo runner1
submitting api1


// in context of dep2
echo runner2
submitting api2

解决方案

Some minimal changes to get to working for the above are here:

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)
    }
}

This produces

$ 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"

The key change is to let the template do the work- use the range function on the Dependency array, and then again on the Install array, to traverse the data structure.

The other change is just to write to stdout, rather than to a file. If it is desirable to turn this into a script, just pipe it to a file.

More broadly, I think there is a tension in the data model around ownership of the install steps. Are the install steps fixed for each runner type? Or may they vary? If they are fixed, then having a map[string][string] of runner type to array of install steps probably makes sense, which would then relieve the Dependency object of having a copy of install steps.

I also wonder about the YAML- is it a source of truth? Or is it derivative? If derivative, perhaps it is unnecessary. Probably better to have the go program interrogate the actual source of truth and generate a script.

In any event, I hope that's helpful.

这篇关于Golang模板,带开关&amp;的ForEach的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆