Skip to content
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ report.xml
*.cid
*.iid
*.out
*.test

.vscode
1 change: 1 addition & 0 deletions conv/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
// All other values are considered false.
//
// See ToBool also for a more flexible version.
//
// Deprecated: use ToBool instead
func Bool(in string) bool {
if b, err := strconv.ParseBool(in); err == nil {
Expand Down
2 changes: 2 additions & 0 deletions funcs/base64.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
)

// Base64NS - the base64 namespace
//
// Deprecated: don't use
func Base64NS() *Base64Funcs {
return &Base64Funcs{}
}

// AddBase64Funcs -
//
// Deprecated: use CreateBase64Funcs instead
func AddBase64Funcs(f map[string]interface{}) {
for k, v := range CreateBase64Funcs(context.Background()) {
Expand Down
1 change: 1 addition & 0 deletions funcs/cel_exports.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions funcs/coll.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import (
)

// CollNS -
//
// Deprecated: don't use
func CollNS() *CollFuncs {
return &CollFuncs{}
}

// AddCollFuncs -
//
// Deprecated: use CreateCollFuncs instead
func AddCollFuncs(f map[string]interface{}) {
for k, v := range CreateCollFuncs(context.Background()) {
Expand Down Expand Up @@ -78,7 +80,7 @@ func (CollFuncs) Dict(in ...interface{}) (map[string]interface{}, error) {

// Keys -
func (CollFuncs) Keys(in map[string]any) []string {
keys := []string{}
keys := make([]string, 0, len(in))
for k := range in {
keys = append(keys, k)
}
Expand All @@ -87,7 +89,7 @@ func (CollFuncs) Keys(in map[string]any) []string {

// Values -
func (CollFuncs) Values(in map[string]any) []any {
values := []any{}
values := make([]any, 0, len(in))
for _, v := range in {
values = append(values, v)
}
Expand Down
6 changes: 6 additions & 0 deletions funcs/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
)

// ConvNS -
//
// Deprecated: don't use
func ConvNS() *ConvFuncs {
return &ConvFuncs{}
}

// AddConvFuncs -
//
// Deprecated: use CreateConvFuncs instead
func AddConvFuncs(f map[string]interface{}) {
for k, v := range CreateConvFuncs(context.Background()) {
Expand Down Expand Up @@ -43,6 +45,7 @@ type ConvFuncs struct {
}

// Bool -
//
// Deprecated: use ToBool instead
func (f *ConvFuncs) Bool(s interface{}) bool {
return conv.Bool(conv.ToString(s))
Expand All @@ -59,6 +62,7 @@ func (ConvFuncs) ToBools(in ...interface{}) []bool {
}

// Slice -
//
// Deprecated: use coll.Slice instead
func (f *ConvFuncs) Slice(args ...interface{}) []interface{} {
return coll.Slice(args...)
Expand All @@ -70,6 +74,7 @@ func (ConvFuncs) Join(in interface{}, sep string) (string, error) {
}

// Has -
//
// Deprecated: use coll.Has instead
func (f *ConvFuncs) Has(in interface{}, key string) bool {
return coll.Has(in, key)
Expand Down Expand Up @@ -149,6 +154,7 @@ func (ConvFuncs) Default(def, in interface{}) interface{} {
}

// Dict -
//
// Deprecated: use coll.Dict instead
func (f *ConvFuncs) Dict(in ...interface{}) (map[string]interface{}, error) {
return coll.Dict(in...)
Expand Down
2 changes: 2 additions & 0 deletions funcs/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (
)

// CryptoNS - the crypto namespace
//
// Deprecated: don't use
func CryptoNS() *CryptoFuncs {
return &CryptoFuncs{}
}

// AddCryptoFuncs -
//
// Deprecated: use CreateCryptoFuncs instead
func AddCryptoFuncs(f map[string]interface{}) {
for k, v := range CreateCryptoFuncs(context.Background()) {
Expand Down
1 change: 1 addition & 0 deletions funcs/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
)

// DataNS -
//
// Deprecated: don't use
func DataNS() *DataFuncs {
return &DataFuncs{}
Expand Down
2 changes: 2 additions & 0 deletions funcs/filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
)

// FilePathNS - the Path namespace
//
// Deprecated: don't use
func FilePathNS() *FilePathFuncs {
return &FilePathFuncs{}
}

// AddFilePathFuncs -
//
// Deprecated: use CreateFilePathFuncs instead
func AddFilePathFuncs(f map[string]interface{}) {
for k, v := range CreateFilePathFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import (
)

// MathNS - the math namespace
//
// Deprecated: don't use
func MathNS() *MathFuncs {
return &MathFuncs{}
}

// AddMathFuncs -
//
// Deprecated: use CreateMathFuncs instead
func AddMathFuncs(f map[string]interface{}) {
for k, v := range CreateMathFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
)

// PathNS - the Path namespace
//
// Deprecated: don't use
func PathNS() *PathFuncs {
return &PathFuncs{}
}

// AddPathFuncs -
//
// Deprecated: use CreatePathFuncs instead
func AddPathFuncs(f map[string]interface{}) {
for k, v := range CreatePathFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import (
)

// RandomNS -
//
// Deprecated: don't use
func RandomNS() *RandomFuncs {
return &RandomFuncs{}
}

// AddRandomFuncs -
//
// Deprecated: use CreateRandomFuncs instead
func AddRandomFuncs(f map[string]interface{}) {
for k, v := range CreateRandomFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
)

// ReNS -
//
// Deprecated: don't use
func ReNS() *ReFuncs {
return &ReFuncs{}
}

// AddReFuncs -
//
// Deprecated: use CreateReFuncs instead
func AddReFuncs(f map[string]interface{}) {
for k, v := range CreateReFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ import (
)

// StrNS -
//
// Deprecated: don't use
func StrNS() *StringFuncs {
return &StringFuncs{}
}

// AddStringFuncs -
//
// Deprecated: use CreateStringFuncs instead
func AddStringFuncs(f map[string]interface{}) {
for k, v := range CreateStringFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
)

// TestNS -
//
// Deprecated: don't use
func TestNS() *TestFuncs {
return &TestFuncs{}
}

// AddTestFuncs -
//
// Deprecated: use CreateTestFuncs instead
func AddTestFuncs(f map[string]interface{}) {
for k, v := range CreateTestFuncs(context.Background()) {
Expand Down
2 changes: 2 additions & 0 deletions funcs/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
)

// TimeNS -
//
// Deprecated: don't use
func TimeNS() *TimeFuncs {
return &TimeFuncs{
Expand All @@ -39,6 +40,7 @@ func TimeNS() *TimeFuncs {
}

// AddTimeFuncs -
//
// Deprecated: use CreateTimeFuncs instead
func AddTimeFuncs(f map[string]interface{}) {
for k, v := range CreateTimeFuncs(context.Background()) {
Expand Down
20 changes: 20 additions & 0 deletions funcs/uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ package funcs

import (
"context"
"crypto/sha256"

"github.com/flanksource/gomplate/v3/conv"

"github.com/google/uuid"
)

// UUIDNS -
//
// Deprecated: don't use
func UUIDNS() *UUIDFuncs {
return &UUIDFuncs{}
}

// AddUUIDFuncs -
//
// Deprecated: use CreateUUIDFuncs instead
func AddUUIDFuncs(f map[string]interface{}) {
for k, v := range CreateUUIDFuncs(context.Background()) {
Expand Down Expand Up @@ -79,3 +82,20 @@ func (UUIDFuncs) Parse(in interface{}) (string, error) {
}
return u.String(), err
}

// HashUUID - return a deterministic UUID based on the SHA256 hash of the input arguments.
// This function always returns the same UUID for the same input, making it idempotent.
// It uses the nil UUID as the namespace and SHA256 as the hashing algorithm.
func (UUIDFuncs) HashUUID(args ...interface{}) (string, error) {
// Concatenate all arguments into a single byte slice
data := make([]byte, 0, len(args)*16)
for _, arg := range args {
data = append(data, []byte(conv.ToString(arg))...)
}

// Use uuid.Nil as the namespace
// Generate a version 5-style UUID (SHA-based) using SHA256
u := uuid.NewHash(sha256.New(), uuid.Nil, data, 5)

return u.String(), nil
}
26 changes: 26 additions & 0 deletions funcs/uuid_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions funcs/uuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,63 @@ func TestParse(t *testing.T) {
assert.Equal(t, in, uid)
}
}

func TestHashUUID(t *testing.T) {
t.Parallel()

u := UUIDNS()

// Test that the same input produces the same UUID
uuid1, err := u.HashUUID("test")
assert.NoError(t, err)
assert.NotEmpty(t, uuid1)

uuid2, err := u.HashUUID("test")
assert.NoError(t, err)
assert.Equal(t, uuid1, uuid2, "Same input should produce same UUID")

// Test that different inputs produce different UUIDs
uuid3, err := u.HashUUID("different")
assert.NoError(t, err)
assert.NotEqual(t, uuid1, uuid3, "Different inputs should produce different UUIDs")

// Test with multiple arguments
uuid4, err := u.HashUUID("arg1", "arg2", "arg3")
assert.NoError(t, err)
assert.NotEmpty(t, uuid4)

uuid5, err := u.HashUUID("arg1", "arg2", "arg3")
assert.NoError(t, err)
assert.Equal(t, uuid4, uuid5, "Same multiple arguments should produce same UUID")

// Test that order matters
uuid6, err := u.HashUUID("arg2", "arg1", "arg3")
assert.NoError(t, err)
assert.NotEqual(t, uuid4, uuid6, "Different order should produce different UUIDs")

// Test with numeric arguments
uuid7, err := u.HashUUID(123, 456)
assert.NoError(t, err)
assert.NotEmpty(t, uuid7)

uuid8, err := u.HashUUID(123, 456)
assert.NoError(t, err)
assert.Equal(t, uuid7, uuid8, "Same numeric arguments should produce same UUID")

// Test with no arguments
uuid9, err := u.HashUUID()
assert.NoError(t, err)
assert.NotEmpty(t, uuid9)

uuid10, err := u.HashUUID()
assert.NoError(t, err)
assert.Equal(t, uuid9, uuid10, "No arguments should produce same UUID each time")

// Verify the UUID format is valid (version 5, SHA-based)
parsed, err := u.Parse(uuid1)
assert.NoError(t, err)
assert.Equal(t, uuid1, parsed)

// Check that it's a valid UUID v5 pattern
assert.Regexp(t, "^[[:xdigit:]]{8}-[[:xdigit:]]{4}-5[[:xdigit:]]{3}-[89ab][[:xdigit:]]{3}-[[:xdigit:]]{12}$", uuid1)
}
Loading
Loading