feat(template): custom compare functions

resolves #3218
This commit is contained in:
Jan De Dobbeleer 2022-12-18 14:48:35 +01:00 committed by Jan De Dobbeleer
parent 80b92505bc
commit 2255f9fd44
5 changed files with 88 additions and 10 deletions

View file

@ -689,7 +689,7 @@ func (env *Shell) Close() {
func (env *Shell) LoadTemplateCache() {
defer env.Trace(time.Now(), "LoadTemplateCache")
val, OK := env.fileCache.Get(TEMPLATECACHE)
val, OK := env.fileCache.Get("template_cache_91508")
if !OK {
return
}

35
src/template/compare.go Normal file
View file

@ -0,0 +1,35 @@
package template
func interFaceToInt(e interface{}) int {
if val, OK := e.(int); OK {
return val
}
if val, OK := e.(float64); OK {
return int(val)
}
return 0
}
func interfaceToFloat64(e interface{}) float64 {
if val, OK := e.(float64); OK {
return val
}
if val, OK := e.(int); OK {
return float64(val)
}
return 0
}
func gt(e1, e2 interface{}) bool {
if val, OK := e1.(int); OK {
return val > interFaceToInt(e2)
}
if val, OK := e1.(float64); OK {
return val > interfaceToFloat64(e2)
}
return false
}
func lt(e1, e2 interface{}) bool {
return !gt(e1, e2)
}

View file

@ -0,0 +1,50 @@
package template
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGt(t *testing.T) {
cases := []struct {
Case string
Expected bool
E1 interface{}
E2 interface{}
}{
{Case: "Float vs int", Expected: false, E1: float64(3), E2: 4},
{Case: "Int vs float", Expected: false, E1: 3, E2: float64(4)},
{Case: "Int vs Int", Expected: false, E1: 3, E2: 4},
{Case: "Float vs Float", Expected: false, E1: float64(3), E2: float64(4)},
{Case: "Float vs String", Expected: true, E1: float64(3), E2: "test"},
{Case: "Int vs String", Expected: true, E1: 3, E2: "test"},
{Case: "String vs String", Expected: false, E1: "test", E2: "test"},
}
for _, tc := range cases {
got := gt(tc.E1, tc.E2)
assert.Equal(t, tc.Expected, got, tc.Case)
}
}
func TestLt(t *testing.T) {
cases := []struct {
Case string
Expected bool
E1 interface{}
E2 interface{}
}{
{Case: "Float vs int", Expected: true, E1: float64(3), E2: 4},
{Case: "Int vs float", Expected: true, E1: 3, E2: float64(4)},
{Case: "Int vs Int", Expected: true, E1: 3, E2: 4},
{Case: "Float vs Float", Expected: true, E1: float64(3), E2: float64(4)},
{Case: "Float vs String", Expected: false, E1: float64(3), E2: "test"},
{Case: "String vs String", Expected: true, E1: "test", E2: "test"},
}
for _, tc := range cases {
got := lt(tc.E1, tc.E2)
assert.Equal(t, tc.Expected, got, tc.Case)
}
}

View file

@ -14,6 +14,8 @@ func funcMap() template.FuncMap {
"glob": glob,
"matchP": matchP,
"replaceP": replaceP,
"gt": gt,
"lt": lt,
}
for key, fun := range sprig.TxtFuncMap() {
if _, ok := funcMap[key]; !ok {

View file

@ -185,15 +185,6 @@ If you want to know if a specific segment is active, you can use the `.Segments.
"template": "{{ if .Segments.Contains \"Git\" }}\uf7d3{{ else if gt .Code 0 }}\uf00d{{ else }}\uf00c{{ end }} "
```
:::tip
Due to the way the segments data is cached, all numbers are converted to `float64`. If you want to use a number in a
template, you need to compare it to a `float64`:
```json
"template": "{{ if gt .Segments.Git.StashCount (float64 0) }}Stash!{{ end }}"
```
:::
## Text decoration
You can make use of the following syntax to decorate text: