Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating yaml files from template in golang

I want to create a yaml file from a current tmpl file. Basically I want to insert values in the sample.tmpl files stored in the /templates folder and create a new yaml file in the same folder sample.yml

My sample.tmpl looks like

url : {{ .host }}
namespace: {{ .namespace }}

I'm using the following function:

func ApplyTemplate(filePath string) (err error) {
    // Variables - host, namespace
    type Eingest struct {
        host      string
        namespace string
    }

    ei := Eingest{host: "example.com", namespace: "finance"}
    var templates *template.Template
    var allFiles []string
    files, err := ioutil.ReadDir(filePath)
    if err != nil {
        fmt.Println(err)
    }

    for _, file := range files {
        filename := file.Name()
        fullPath := filePath + "/" + filename
        if strings.HasSuffix(filename, ".tmpl") {
            allFiles = append(allFiles, fullPath)
        }
    }

    fmt.Println("Files in path: ", allFiles)

    // parses all .tmpl files in the 'templates' folder
    templates, err = template.ParseFiles(allFiles...)
    if err != nil {
        fmt.Println(err)
    }

    s1 := templates.Lookup("sample.tmpl")
    s1.ExecuteTemplate(os.Stdout, "sample.yml", ei)
    fmt.Println()
    return
}

s1.ExecuteTemplate() writes to stdout. How can I create a new file in the same folder? I believe something similar is used to build kubernetes yaml files. How do we achieve this using golang template package?

like image 882
nevosial Avatar asked Oct 28 '25 13:10

nevosial


1 Answers

First: since you've already looked up the template, you should use template.Execute instead, but the same works with ExecuteTemplate.

text.Template.Execute takes a io.Writer as first argument. This is an interface with a single method: Write(p []byte) (n int, err error).

Any type that has that method implements the interface and can be used as a valid argument. One such type is a os.File. Simply create a new os.File object and pass it to Execute as follows:

// Build the path:
outputPath := filepath.Join(filepath, "sample.yml")

// Create the file:
f, err := os.Create(outputPath)
if err != nil {
  panic(err)
}

defer f.Close() // don't forget to close the file when finished.

// Write template to file:
err = s1.Execute(f, ei)
if err != nil {
  panic(err)
}

Note: don't forget to check whether s1 is nil, as documented in template.Lookup.

like image 144
Marc Avatar answered Oct 30 '25 08:10

Marc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!