mirror of https://github.com/fluxcd/cli-utils.git
fix: Clean up object.FieldPath
- Use string.Builder to be slightly more efficient - Format invalid types with Go syntax, wrapped with brackets - Test that invalid types don't panic
This commit is contained in:
parent
476197d25b
commit
a0743e6912
|
@ -6,6 +6,7 @@ package object
|
|||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
@ -76,25 +77,30 @@ func NotFound(fieldPath []interface{}, value interface{}) *field.Error {
|
|||
}
|
||||
}
|
||||
|
||||
// Simplistic jsonpath formatter, just for NestedField errors.
|
||||
// FieldPath formats a list of KRM field keys as a JSONPath expression.
|
||||
// The only valid field keys in KRM are strings (map keys) and ints (list keys).
|
||||
// Simple strings (see isSimpleString) will be delimited with a period.
|
||||
// Complex strings will be wrapped with square brackets and double quotes.
|
||||
// Integers will be wrapped with square brackets.
|
||||
// All other types will be formatted best-effort within square brackets.
|
||||
func FieldPath(fieldPath []interface{}) string {
|
||||
path := ""
|
||||
var sb strings.Builder
|
||||
for _, field := range fieldPath {
|
||||
switch typedField := field.(type) {
|
||||
case string:
|
||||
if isSimpleString(typedField) {
|
||||
path += fmt.Sprintf(".%s", typedField)
|
||||
_, _ = fmt.Fprintf(&sb, ".%s", typedField)
|
||||
} else {
|
||||
path += fmt.Sprintf("[%q]", typedField)
|
||||
_, _ = fmt.Fprintf(&sb, "[%q]", typedField)
|
||||
}
|
||||
case int:
|
||||
path += fmt.Sprintf("[%d]", typedField)
|
||||
_, _ = fmt.Fprintf(&sb, "[%d]", typedField)
|
||||
default:
|
||||
// invalid. try anyway...
|
||||
path += fmt.Sprintf(".%v", typedField)
|
||||
// invalid type. try anyway...
|
||||
_, _ = fmt.Fprintf(&sb, "[%#v]", typedField)
|
||||
}
|
||||
}
|
||||
return path
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
var simpleStringRegex = regexp.MustCompile(`^[a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$`)
|
||||
|
|
|
@ -78,6 +78,15 @@ func TestFieldPath(t *testing.T) {
|
|||
fieldPath: []interface{}{"spec", "abc\n123"},
|
||||
expected: `.spec["abc\n123"]`,
|
||||
},
|
||||
// result from invalid input doesn't matter, as long as it doesn't panic
|
||||
"invalid type: float": {
|
||||
fieldPath: []interface{}{"spec", float64(-1.0)},
|
||||
expected: `.spec[-1]`,
|
||||
},
|
||||
"invalid type: struct": {
|
||||
fieldPath: []interface{}{"spec", struct{ Field string }{Field: "value"}},
|
||||
expected: `.spec[struct { Field string }{Field:"value"}]`,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
|
|
Loading…
Reference in New Issue