Compare commits
3 commits
413904c457
...
69674ffaa7
| Author | SHA1 | Date | |
|---|---|---|---|
| 69674ffaa7 | |||
| 9e4d1a6a28 | |||
| bf78461bbb |
18 changed files with 87 additions and 52 deletions
7
embed/embed.go
Normal file
7
embed/embed.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package embed
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed templates/*.tmpl templates/**/*
|
||||||
|
var Templates embed.FS
|
||||||
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"{{.ModName}}/internal/logger"
|
"{{.ModName}}/internal/logger"
|
||||||
)
|
)
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
default = pkgs.callPackage (
|
default = pkgs.callPackage (
|
||||||
{ buildGoModule }:
|
{ buildGoModule }:
|
||||||
buildGoModule {
|
buildGoModule {
|
||||||
pname = "wand-templater";
|
pname = "bubblewand";
|
||||||
version = "0.0.1";
|
version = "0.0.1";
|
||||||
src = builtins.path {
|
src = builtins.path {
|
||||||
name = "source";
|
name = "source";
|
||||||
|
|
|
||||||
|
|
@ -1,71 +1,100 @@
|
||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"io/fs"
|
||||||
"path/filepath"
|
"os"
|
||||||
"strings"
|
"path/filepath"
|
||||||
"text/template"
|
"strings"
|
||||||
"specCon18/bubblewand/internal/logger"
|
"text/template"
|
||||||
|
|
||||||
|
"specCon18/bubblewand/embed" // Import embedded template files
|
||||||
|
"specCon18/bubblewand/internal/logger" // Import logger for logging output
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProgramData holds user-supplied template values
|
// ProgramData holds user-supplied values for template substitution.
|
||||||
type ProgramData struct {
|
type ProgramData struct {
|
||||||
ModName string
|
ModName string // Module name
|
||||||
PackageName string
|
PackageName string // Go package name
|
||||||
ProgramVersion string
|
ProgramVersion string // Version string
|
||||||
ProgramDesc string
|
ProgramDesc string // Description of the program
|
||||||
OutputDir string
|
OutputDir string // Target output directory for rendered files
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderTemplates renders all .tmpl files from the templates/ directory into outputDir
|
// RenderTemplates renders embedded .tmpl files into outputDir
|
||||||
func RenderTemplates(data ProgramData, outputDir string, verbose bool) error {
|
func RenderTemplates(data ProgramData, outputDir string, verbose bool) error {
|
||||||
var renderedFiles int
|
var renderedFiles int // Count of successfully rendered files
|
||||||
|
|
||||||
err := filepath.Walk("templates", func(path string, info os.FileInfo, err error) error {
|
// Walk through the embedded templates filesystem starting at "templates"
|
||||||
if err != nil {
|
err := fs.WalkDir(embed.Templates, "templates", func(path string, d fs.DirEntry, err error) error {
|
||||||
return err
|
if err != nil {
|
||||||
}
|
// Log and return error encountered while walking the filesystem
|
||||||
if info.IsDir() || !strings.HasSuffix(info.Name(), ".tmpl") {
|
logger.Log.Errorf("Error walking path %q: %v", path, err)
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
relPath, err := filepath.Rel("templates", path)
|
// Skip directories and files that do not end with ".tmpl"
|
||||||
if err != nil {
|
if d.IsDir() || !strings.HasSuffix(d.Name(), ".tmpl") {
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
outputPath := filepath.Join(outputDir, strings.TrimSuffix(relPath, ".tmpl"))
|
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
|
// Strip the "templates/" prefix from path and remove ".tmpl" extension
|
||||||
return err
|
relPath := strings.TrimPrefix(path, "templates/")
|
||||||
}
|
outputPath := filepath.Join(outputDir, strings.TrimSuffix(relPath, ".tmpl"))
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles(path)
|
// Ensure the parent directory for the output file exists
|
||||||
if err != nil {
|
if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
|
||||||
return err
|
logger.Log.Errorf("Failed to create directory for %s: %v", outputPath, err)
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
outFile, err := os.Create(outputPath)
|
// Read the embedded template file
|
||||||
if err != nil {
|
tmplBytes, err := embed.Templates.ReadFile(path)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
logger.Log.Errorf("Failed to read template %s: %v", path, err)
|
||||||
defer outFile.Close()
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if verbose {
|
// Parse the template content
|
||||||
logger.Log.Infof("Rendering %s → %s", path, outputPath)
|
tmpl, err := template.New(d.Name()).Parse(string(tmplBytes))
|
||||||
}
|
if err != nil {
|
||||||
|
logger.Log.Errorf("Failed to parse template %s: %v", path, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
renderedFiles++
|
// Create the output file for writing the rendered content
|
||||||
return tmpl.Execute(outFile, data)
|
outFile, err := os.Create(outputPath)
|
||||||
})
|
if err != nil {
|
||||||
|
logger.Log.Errorf("Failed to create output file %s: %v", outputPath, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer outFile.Close()
|
||||||
|
|
||||||
if err != nil {
|
// Log the render operation if verbose mode is enabled
|
||||||
return err
|
if verbose {
|
||||||
}
|
logger.Log.Infof("Rendering %s → %s", path, outputPath)
|
||||||
|
}
|
||||||
|
|
||||||
if !verbose && renderedFiles > 0 {
|
// Execute the template using the provided data and write to file
|
||||||
logger.Log.Info("Rendering templates")
|
if err := tmpl.Execute(outFile, data); err != nil {
|
||||||
}
|
logger.Log.Errorf("Failed to execute template %s: %v", path, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
renderedFiles++
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
// If any error occurred during the walk/render process, log and return it
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf("Template rendering failed: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not verbose and at least one file was rendered, print a summary log
|
||||||
|
if !verbose && renderedFiles > 0 {
|
||||||
|
logger.Log.Info("Rendering templates")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue