Fixed lint issues and missing documentation

This commit is contained in:
bwilliams committed 2026-10-13 12:21:32 +01:00
1 parent 7fd321df97
commit 6e6dec68c0
34 files changed
+346 -156

No files matched your search

+47 -5
View File
@@ -36,6 +36,32 @@ var (
timeType = reflect.TypeOf(time.Time{})
)
// Section is the method set of every configuration section, including
// JobSearchConfig itself, implemented on the section's pointer type. Keys are
// dotted paths relative to the section, e.g. "sleeper.interval" in
// JobSearchConfigSources. Durations are given out as strings such as "10m0s",
// matching TypeOf's reflect.String for them. TestSections checks every
// section, found by walking JobSearchConfig, implements it.
type Section interface {
// Map returns the section as a map of keys to values, with nested
// sections as nested maps.
Map() map[string]any
// Flatten returns the section as a flat map of dotted keys, each
// prefixed with the section's own key (its JSCK* constant), so a
// section's keys match how its parent flattens it. JobSearchConfig and
// the embedded JobSearchConfigSource have no prefix.
Flatten() map[string]any
// TypeOf returns the kind of the value at key, which is how it is read
// from Viper, or an error for an unknown key.
TypeOf(key string) (reflect.Kind, error)
// ValueOf returns the value at key, or an error for an unknown key.
ValueOf(key string) (any, error)
// SetValue stores value at key. value may be of the field's type or a
// string to parse (e.g. "10m", "true", "42"). The section's validation,
// if any, runs first; on error the field is unchanged.
SetValue(key string, value any) error
}
// validator is implemented by sections that need to reject some values.
// key is the field's own key within the section; value has already been
// converted to the field's type.
@@ -43,6 +69,8 @@ type validator interface {
validate(key string, value any) error
}
// field is a section struct field that is part of the configuration (see
// fieldsOf).
type field struct {
key string
index []int // path for reflect.Value.FieldByIndex
@@ -136,16 +164,15 @@ func mapOf(v any) map[string]any {
return mapOfValue(structValue(v))
}
// mapOfValue is mapOf for a section struct value.
func mapOfValue(section reflect.Value) map[string]any {
m := map[string]any{}
for _, f := range fieldsOf(section.Type()) {
fv := section.FieldByIndex(f.index)
if f.section {
m[f.key] = mapOfValue(fv)
} else if f.typ == durationType {
m[f.key] = fv.Interface().(time.Duration).String()
} else {
m[f.key] = fv.Interface()
m[f.key] = exportValue(fv)
}
}
return m
@@ -159,6 +186,8 @@ func flattenOf(prefix string, v any) map[string]any {
return m
}
// flattenInto adds section's keys to m, dotted and prefixed with prefix (if
// non-empty), descending into nested sections.
func flattenInto(m map[string]any, prefix string, section reflect.Value) {
for _, f := range fieldsOf(section.Type()) {
fv := section.FieldByIndex(f.index)
@@ -166,11 +195,21 @@ func flattenInto(m map[string]any, prefix string, section reflect.Value) {
if f.section {
flattenInto(m, key, fv)
} else {
m[key] = fv.Interface()
m[key] = exportValue(fv)
}
}
}
// exportValue returns a field's value as Map, Flatten and ValueOf give it
// out: durations become strings such as "1m30s", so values agree with kindOf
// and can be passed back to SetValue; everything else is unchanged.
func exportValue(fv reflect.Value) any {
if fv.Type() == durationType {
return time.Duration(fv.Int()).String()
}
return fv.Interface()
}
// kindOf is the kind reported by TypeOf, i.e. how the value is read from
// Viper. Durations are read as strings and parsed by SetValue.
func kindOf(t reflect.Type) reflect.Kind {
@@ -180,6 +219,8 @@ func kindOf(t reflect.Type) reflect.Kind {
return t.Kind()
}
// typeOf returns the kind of the dotted key in section v (see kindOf), or
// errUnknownKey.
func typeOf(v any, key string) (reflect.Kind, error) {
_, f, err := lookup(structValue(v), key)
if err != nil {
@@ -188,12 +229,13 @@ func typeOf(v any, key string) (reflect.Kind, error) {
return kindOf(f.typ), nil
}
// valueOf returns the value of the dotted key in section v, or errUnknownKey.
func valueOf(v any, key string) (any, error) {
section, f, err := lookup(structValue(v), key)
if err != nil {
return nil, err
}
return section.FieldByIndex(f.index).Interface(), nil
return exportValue(section.FieldByIndex(f.index)), nil
}
// setValue sets a dotted key on the section that ptr points to.