mirror of https://github.com/databricks/cli.git
92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
package template
|
|
|
|
import (
|
|
"errors"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
// Executes the template by applying config on it. Returns the materialized config
|
|
// as a string
|
|
func executeTemplate(config map[string]any, templateDefinition string) (string, error) {
|
|
// configure template with helper functions
|
|
tmpl, err := template.New("").Funcs(HelperFuncs).Parse(templateDefinition)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// execute template
|
|
result := strings.Builder{}
|
|
err = tmpl.Execute(&result, config)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return result.String(), nil
|
|
}
|
|
|
|
func generateFile(config map[string]any, pathTemplate, contentTemplate string, perm fs.FileMode) error {
|
|
// compute file content
|
|
fileContent, err := executeTemplate(config, contentTemplate)
|
|
if errors.Is(err, errSkipThisFile) {
|
|
// skip this file
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// compute the path for this file
|
|
path, err := executeTemplate(config, pathTemplate)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// create any intermediate directories required. Directories are lazily generated
|
|
// only when they are required for a file.
|
|
err = os.MkdirAll(filepath.Dir(path), 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// write content to file
|
|
return os.WriteFile(path, []byte(fileContent), perm)
|
|
}
|
|
|
|
func walkFileTree(config map[string]any, templateRoot, instanceRoot string) error {
|
|
return filepath.WalkDir(templateRoot, func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// skip if current entry is a directory
|
|
if d.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
// read template file to get the templatized content for the file
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
contentTemplate := string(b)
|
|
|
|
// get relative path to the template file, This forms the template for the
|
|
// path to the file
|
|
relPathTemplate, err := filepath.Rel(templateRoot, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Get info about the template file. Used to ensure instance path also
|
|
// has the same permission bits
|
|
info, err := d.Info()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return generateFile(config, filepath.Join(instanceRoot, relPathTemplate), contentTemplate, info.Mode().Perm())
|
|
})
|
|
}
|