Skip to content

Commit

Permalink
It's now possible to have template files be rendered into regex-repla…
Browse files Browse the repository at this point in the history
…ced filenames
  • Loading branch information
Stefan Zwanenburg committed Jan 25, 2020
1 parent a6db267 commit 3983f89
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 8 deletions.
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi
github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw=
github.com/cbroglie/mustache v1.0.1 h1:ivMg8MguXq/rrz2eu3tw6g3b16+PQhoTn6EZAhst2mw=
github.com/cbroglie/mustache v1.0.1/go.mod h1:R/RUa+SobQ14qkP4jtx5Vke5sDytONDQXNLPY/PO69g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
86 changes: 78 additions & 8 deletions mustache-then-exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"syscall"
)

type template struct {
source string
regex *regexp.Regexp
replacement string
}

type args struct {
AllowMissing bool `arg:"-a,--allow-missing" help:"whether to allow missing variables (default: false)"`
Templates []string `arg:"-t,--template,separate" placeholder:"TEMPLATE" help:"path to a template to be rendered"`
Expand Down Expand Up @@ -39,15 +46,24 @@ func environmentAsMap() map[string]string {
return envMap
}

func renderTemplate(template string, environment map[string]string) error {
fmt.Printf("Filling template: %s\n", template)
func renderTemplate(template template, environment map[string]string) error {
outputFileName := template.source
if template.regex != nil {
outputFileName = template.regex.ReplaceAllString(template.source, template.replacement)
}
fmt.Printf("Rendering template: %s; output: %s\n", template.source, outputFileName)

renderedTemplate, err := mustache.RenderFile(template, environment)
renderedTemplate, err := mustache.RenderFile(template.source, environment)
if err != nil {
return err
}

err = ioutil.WriteFile(template, []byte(renderedTemplate), 0)
fileInfo, err := os.Stat(template.source)
if err != nil {
return err
}

err = ioutil.WriteFile(outputFileName, []byte(renderedTemplate), fileInfo.Mode())
if err != nil {
return err
}
Expand All @@ -64,22 +80,76 @@ func parseArgs() args {
return args
}

func parseTemplate(templateFileName string) template {
currentString := []rune{}
splits := []string{}
isEscaped := false

for _, c := range templateFileName {
if c == '\\' {
isEscaped = true
currentString = append(currentString[:], c)
} else if c == ':' {
if isEscaped {
currentString = append(currentString[0:len(currentString)-1], c)
} else {
splits = append(splits, string(currentString))
currentString = []rune{}
}
isEscaped = false
} else {
currentString = append(currentString, c)
isEscaped = false
}
}

splits = append(splits, string(currentString))

if len(splits) == 1 {
return template{source: splits[0]}
} else if len(splits) != 3 {
fail("Template '%s' is invalid (have you escaped colons properly?)", templateFileName)
}

regex, err := regexp.Compile(splits[1])
if err != nil {
failErr(err)
}

return template{
source: splits[0],
regex: regex,
replacement: splits[2],
}
}

func main() {
args := parseArgs()

environment := environmentAsMap()

matchedFiles := []string{}
templates := []template{}
for _, templateGlob := range args.GlobTemplates {
templates, err := filepath.Glob(templateGlob)
parsedTemplateGlob := parseTemplate(templateGlob)
matchingTemplateFileNames, err := filepath.Glob(parsedTemplateGlob.source)
if err != nil {
failErr(err)
}

matchedFiles = append(matchedFiles, templates...)
for _, matchingTemplateFileName := range matchingTemplateFileNames {
templates = append(templates, template{
source: matchingTemplateFileName,
regex: parsedTemplateGlob.regex,
replacement: parsedTemplateGlob.replacement,
})
}
}

for _, template := range args.Templates {
templates = append(templates, parseTemplate(template))
}

for _, template := range append(args.Templates, matchedFiles...) {
for _, template := range templates {
err := renderTemplate(template, environment)
if err != nil {
failErr(err)
Expand Down

0 comments on commit 3983f89

Please sign in to comment.