Merge branch 'master' of github.com:containers/common into dependabot/go_modules/github.com/opencontainers/runc-1.0.0-rc93

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2021-02-05 11:44:39 -05:00
commit c18f0fa0cf
2 changed files with 57 additions and 18 deletions

View File

@ -1,6 +1,8 @@
package report package report
import ( import (
"bytes"
"encoding/json"
"reflect" "reflect"
"strings" "strings"
"text/template" "text/template"
@ -21,22 +23,30 @@ type FuncMap template.FuncMap
var tableReplacer = strings.NewReplacer( var tableReplacer = strings.NewReplacer(
"table ", "", "table ", "",
`\t`, "\t", `\t`, "\t",
`\n`, "\n",
" ", "\t", " ", "\t",
) )
// escapedReplacer will clean up escaped characters from CLI // escapedReplacer will clean up escaped characters from CLI
var escapedReplacer = strings.NewReplacer( var escapedReplacer = strings.NewReplacer(
`\t`, "\t", `\t`, "\t",
`\n`, "\n",
) )
var defaultFuncs = FuncMap{ var DefaultFuncs = FuncMap{
"join": strings.Join, "join": strings.Join,
"lower": strings.ToLower, "json": func(v interface{}) string {
"split": strings.Split, buf := &bytes.Buffer{}
"title": strings.Title, enc := json.NewEncoder(buf)
"upper": strings.ToUpper, enc.SetEscapeHTML(false)
enc.Encode(v)
// Remove the trailing new line added by the encoder
return strings.TrimSpace(buf.String())
},
"lower": strings.ToLower,
"pad": padWithSpace,
"split": strings.Split,
"title": strings.Title,
"truncate": truncateWithLength,
"upper": strings.ToUpper,
} }
// NormalizeFormat reads given go template format provided by CLI and munges it into what we need // NormalizeFormat reads given go template format provided by CLI and munges it into what we need
@ -55,6 +65,22 @@ func NormalizeFormat(format string) string {
return f return f
} }
// padWithSpace adds spaces*prefix and spaces*suffix to the input when it is non-empty
func padWithSpace(source string, prefix, suffix int) string {
if source == "" {
return source
}
return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix)
}
// truncateWithLength truncates the source string up to the length provided by the input
func truncateWithLength(source string, length int) string {
if len(source) < length {
return source
}
return source[:length]
}
// Headers queries the interface for field names. // Headers queries the interface for field names.
// Array of map is returned to support range templates // Array of map is returned to support range templates
// Note: unexported fields can be supported by adding field to overrides // Note: unexported fields can be supported by adding field to overrides
@ -96,7 +122,7 @@ func Headers(object interface{}, overrides map[string]string) []map[string]strin
// NewTemplate creates a new template object // NewTemplate creates a new template object
func NewTemplate(name string) *Template { func NewTemplate(name string) *Template {
return &Template{Template: template.New(name).Funcs(template.FuncMap(defaultFuncs))} return &Template{Template: template.New(name).Funcs(template.FuncMap(DefaultFuncs))}
} }
// Parse parses text as a template body for t // Parse parses text as a template body for t
@ -108,7 +134,7 @@ func (t *Template) Parse(text string) (*Template, error) {
text = NormalizeFormat(text) text = NormalizeFormat(text)
} }
tt, err := t.Template.Funcs(template.FuncMap(defaultFuncs)).Parse(text) tt, err := t.Template.Funcs(template.FuncMap(DefaultFuncs)).Parse(text)
return &Template{tt, t.isTable}, err return &Template{tt, t.isTable}, err
} }
@ -116,7 +142,7 @@ func (t *Template) Parse(text string) (*Template, error) {
// A default template function will be replace if there is a key collision. // A default template function will be replace if there is a key collision.
func (t *Template) Funcs(funcMap FuncMap) *Template { func (t *Template) Funcs(funcMap FuncMap) *Template {
m := make(FuncMap) m := make(FuncMap)
for k, v := range defaultFuncs { for k, v := range DefaultFuncs {
m[k] = v m[k] = v
} }
for k, v := range funcMap { for k, v := range funcMap {

View File

@ -48,9 +48,9 @@ func TestNormalizeFormat(t *testing.T) {
input string input string
expected string expected string
}{ }{
{"{{.ID}}\t{{.ID}}\n", "{{.ID}}\t{{.ID}}\n"}, {"{{.ID}}\t{{.ID}}", "{{.ID}}\t{{.ID}}\n"},
{`{{.ID}}\t{{.ID}}\n`, "{{.ID}}\t{{.ID}}\n"}, {`{{.ID}}\t{{.ID}}`, "{{.ID}}\t{{.ID}}\n"},
{`{{.ID}} {{.ID}}\n`, "{{.ID}} {{.ID}}\n"}, {`{{.ID}} {{.ID}}`, "{{.ID}} {{.ID}}\n"},
{`table {{.ID}}\t{{.ID}}`, "{{.ID}}\t{{.ID}}\n"}, {`table {{.ID}}\t{{.ID}}`, "{{.ID}}\t{{.ID}}\n"},
{`table {{.ID}} {{.ID}}`, "{{.ID}}\t{{.ID}}\n"}, {`table {{.ID}} {{.ID}}`, "{{.ID}}\t{{.ID}}\n"},
} }
@ -68,7 +68,6 @@ func TestTemplate_Parse(t *testing.T) {
testCase := []string{ testCase := []string{
"table {{.ID}}", "table {{.ID}}",
"table {{ .ID}}", "table {{ .ID}}",
`table {{ .ID}}\n`,
"table {{ .ID}}\n", "table {{ .ID}}\n",
"{{range .}}{{.ID}}{{end}}", "{{range .}}{{.ID}}{{end}}",
`{{range .}}{{.ID}}{{end}}`, `{{range .}}{{.ID}}{{end}}`,
@ -98,7 +97,7 @@ func TestTemplate_IsTable(t *testing.T) {
assert.True(t, tmpl.isTable) assert.True(t, tmpl.isTable)
} }
func TestTemplate_Funcs(t *testing.T) { func TestTemplate_trim(t *testing.T) {
tmpl := NewTemplate("TestTemplate") tmpl := NewTemplate("TestTemplate")
tmpl, e := tmpl.Funcs(FuncMap{"trim": strings.TrimSpace}).Parse("{{.ID |trim}}") tmpl, e := tmpl.Funcs(FuncMap{"trim": strings.TrimSpace}).Parse("{{.ID |trim}}")
assert.NoError(t, e) assert.NoError(t, e)
@ -114,7 +113,7 @@ func TestTemplate_Funcs(t *testing.T) {
func TestTemplate_DefaultFuncs(t *testing.T) { func TestTemplate_DefaultFuncs(t *testing.T) {
tmpl := NewTemplate("TestTemplate") tmpl := NewTemplate("TestTemplate")
// Throw in trim function to ensure default 'join' is still available // Throw in trim function to ensure default 'join' is still available
tmpl, e := tmpl.Funcs(FuncMap{"trim": strings.TrimSpace}).Parse(`{{join .ID ","}}`) tmpl, e := tmpl.Funcs(FuncMap{"trim": strings.TrimSpace}).Parse(`{{join .ID "\n"}}`)
assert.NoError(t, e) assert.NoError(t, e)
var buf bytes.Buffer var buf bytes.Buffer
@ -122,7 +121,7 @@ func TestTemplate_DefaultFuncs(t *testing.T) {
"ID": {"ident1", "ident2", "ident3"}, "ID": {"ident1", "ident2", "ident3"},
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "ident1,ident2,ident3\n", buf.String()) assert.Equal(t, "ident1\nident2\nident3\n", buf.String())
} }
func TestTemplate_ReplaceFuncs(t *testing.T) { func TestTemplate_ReplaceFuncs(t *testing.T) {
@ -138,3 +137,17 @@ func TestTemplate_ReplaceFuncs(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "ident\n", buf.String()) assert.Equal(t, "ident\n", buf.String())
} }
func TestTemplate_json(t *testing.T) {
tmpl := NewTemplate("TestTemplate")
// yes, we're overriding upper with lower :-)
tmpl, e := tmpl.Parse(`{{json .ID}}`)
assert.NoError(t, e)
var buf bytes.Buffer
err := tmpl.Execute(&buf, map[string][]string{
"ID": {"ident1", "ident2", "ident3"},
})
assert.NoError(t, err)
assert.Equal(t, `["ident1","ident2","ident3"]`+"\n", buf.String())
}