-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtemplate.go
70 lines (60 loc) · 1.62 KB
/
template.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main
import (
"embed"
"fmt"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
)
//go:embed templates/*.tmpl
var templateFS embed.FS
var nixTemplates = template.New("nix").Funcs(sprig.FuncMap()).Funcs(funcMap)
func execTemplate(t *template.Template) func(string, any) (string, error) {
return func(name string, v any) (string, error) {
var s strings.Builder
err := t.ExecuteTemplate(&s, name, v)
return s.String(), err
}
}
func derefInt(v *int) int {
return *v
}
func toNixValue(v any) any {
switch v := v.(type) {
case string:
return fmt.Sprintf("%q", escapeNixString(v))
default:
return v
}
}
func toNixList(s []string) string {
b := strings.Builder{}
for i, e := range s {
// We purposefully do not use %q to avoid Go's built-in string escaping.
b.WriteString(fmt.Sprintf(`"%s"`, escapeNixString(e)))
if i < len(s)-1 {
b.WriteString(" ")
}
}
return fmt.Sprintf("[ %s ]", b.String())
}
func escapeNixString(s string) string {
// https://nix.dev/manual/nix/latest/language/syntax#string-literal
s = strings.ReplaceAll(s, `\`, `\\`)
s = strings.ReplaceAll(s, `"`, `\"`)
s = strings.ReplaceAll(s, `${`, `\${`)
return s
}
func escapeIndentedNixString(s string) string {
// https://nix.dev/manual/nix/latest/language/syntax#string-literal
s = strings.ReplaceAll(s, `''`, `'''`)
s = strings.ReplaceAll(s, `$`, `''$`)
return s
}
var funcMap template.FuncMap = template.FuncMap{
"derefInt": derefInt,
"toNixValue": toNixValue,
"toNixList": toNixList,
"escapeNixString": escapeNixString,
"escapeIndentedNixString": escapeIndentedNixString,
}