Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/textutil/textutil.go
2610 views
1
// SPDX-FileCopyrightText: Copyright The Lima Authors
2
// SPDX-License-Identifier: Apache-2.0
3
4
package textutil
5
6
import (
7
"bytes"
8
"encoding/json"
9
"errors"
10
"fmt"
11
"strings"
12
"text/template"
13
14
"github.com/goccy/go-yaml"
15
)
16
17
// ExecuteTemplate executes a text/template template.
18
func ExecuteTemplate(tmpl string, args any) ([]byte, error) {
19
x, err := template.New("").Parse(tmpl)
20
if err != nil {
21
return nil, err
22
}
23
var b bytes.Buffer
24
if err := x.Execute(&b, args); err != nil {
25
return nil, err
26
}
27
return b.Bytes(), nil
28
}
29
30
// PrefixString adds prefix to beginning of each line.
31
func PrefixString(prefix, text string) string {
32
lines := strings.Split(text, "\n")
33
for i, line := range lines {
34
if line != "" {
35
lines[i] = prefix + line
36
}
37
}
38
return strings.Join(lines, "\n")
39
}
40
41
// IndentString add spaces to beginning of each line.
42
func IndentString(size int, text string) string {
43
prefix := strings.Repeat(" ", size)
44
return PrefixString(prefix, text)
45
}
46
47
// MissingString returns message if the text is empty.
48
func MissingString(message, text string) string {
49
if text == "" {
50
return message
51
}
52
return text
53
}
54
55
// TemplateFuncMap is a text/template FuncMap.
56
var TemplateFuncMap = template.FuncMap{
57
"json": func(v any) string {
58
var b bytes.Buffer
59
enc := json.NewEncoder(&b)
60
enc.SetEscapeHTML(false)
61
if err := enc.Encode(v); err != nil {
62
panic(fmt.Errorf("failed to marshal as JSON: %+v: %w", v, err))
63
}
64
return strings.TrimSuffix(b.String(), "\n")
65
},
66
"yaml": func(v any) string {
67
var b bytes.Buffer
68
enc := yaml.NewEncoder(&b)
69
if err := enc.Encode(v); err != nil {
70
panic(fmt.Errorf("failed to marshal as YAML: %+v: %w", v, err))
71
}
72
return "---\n" + strings.TrimSuffix(b.String(), "\n")
73
},
74
"indent": func(a ...any) (string, error) {
75
if len(a) == 0 {
76
return "", errors.New("function takes at least one string argument")
77
}
78
if len(a) > 2 {
79
return "", errors.New("function takes at most 2 arguments")
80
}
81
var ok bool
82
size := 2
83
if len(a) > 1 {
84
if size, ok = a[0].(int); !ok {
85
return "", errors.New("optional first argument must be an integer")
86
}
87
}
88
text := ""
89
if text, ok = a[len(a)-1].(string); !ok {
90
return "", errors.New("last argument must be a string")
91
}
92
return IndentString(size, text), nil
93
},
94
"missing": func(a ...any) (string, error) {
95
if len(a) == 0 {
96
return "", errors.New("function takes at least one string argument")
97
}
98
if len(a) > 2 {
99
return "", errors.New("function takes at most 2 arguments")
100
}
101
var ok bool
102
message := "<missing>"
103
if len(a) > 1 {
104
if message, ok = a[0].(string); !ok {
105
return "", errors.New("optional first argument must be a string")
106
}
107
}
108
text := ""
109
if text, ok = a[len(a)-1].(string); !ok {
110
return "", errors.New("last argument must be a string")
111
}
112
return MissingString(message, text), nil
113
},
114
}
115
116
// FuncHelp is help for TemplateFuncMap.
117
var FuncHelp = []string{
118
"indent <size>: add spaces to beginning of each line",
119
"missing <message>: return message if the text is empty",
120
}
121
122