Shortened configuration struct names from JobSearchConfig to JSC since they are distinguished by being in the config package anyway
This commit is contained in:
1 parent
5ec4b65b91
commit
be4770cbab
11 files changed
+71
-67
No files matched your search
@@ -5,31 +5,31 @@ import "reflect"
|
||||
// JSCKDatabase is the database section's configuration key.
|
||||
const JSCKDatabase string = "database"
|
||||
|
||||
// JobSearchConfigDatabase configures the SQLite database. File is the path to
|
||||
// JSCDatabase configures the SQLite database. File is the path to
|
||||
// the database file.
|
||||
type JobSearchConfigDatabase struct {
|
||||
type JSCDatabase struct {
|
||||
File string `cfg:"file"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
// Keys returns the keys directly in the section.
|
||||
func (c *JobSearchConfigDatabase) Keys() []string { return keysOf(c) }
|
||||
func (c *JSCDatabase) Keys() []string { return keysOf(c) }
|
||||
|
||||
func (c JobSearchConfigDatabase) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCDatabase) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigDatabase) Flatten() map[string]any {
|
||||
func (c JSCDatabase) Flatten() map[string]any {
|
||||
return flattenOf(JSCKDatabase, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigDatabase) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCDatabase) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigDatabase) ValueOf(key string) (any, error) {
|
||||
func (c JSCDatabase) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigDatabase) SetValue(key string, value any) error {
|
||||
func (c *JSCDatabase) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
@@ -9,40 +9,40 @@ import (
|
||||
// JSCKLogging is the logging section's configuration key.
|
||||
const JSCKLogging string = "logging"
|
||||
|
||||
// JobSearchConfigLogging configures logging. Level is one of debug, info,
|
||||
// JSCLogging configures logging. Level is one of debug, info,
|
||||
// warn or error. File, if set, is where commands that log to a file write.
|
||||
type JobSearchConfigLogging struct {
|
||||
type JSCLogging struct {
|
||||
Level string `cfg:"level" default:"warn"`
|
||||
File string `cfg:"file"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigLogging) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCLogging) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigLogging) Flatten() map[string]any {
|
||||
func (c JSCLogging) Flatten() map[string]any {
|
||||
return flattenOf(JSCKLogging, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigLogging) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCLogging) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigLogging) ValueOf(key string) (any, error) {
|
||||
func (c JSCLogging) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigLogging) SetValue(key string, value any) error {
|
||||
func (c *JSCLogging) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
|
||||
// Keys returns the keys directly in the section.
|
||||
func (c *JobSearchConfigLogging) Keys() []string { return keysOf(c) }
|
||||
func (c *JSCLogging) Keys() []string { return keysOf(c) }
|
||||
|
||||
// ---------- Section specific methods ----------
|
||||
|
||||
// validate checks values before they are stored (see validator).
|
||||
func (c *JobSearchConfigLogging) validate(key string, value any) error {
|
||||
func (c *JSCLogging) validate(key string, value any) error {
|
||||
switch key {
|
||||
case "level":
|
||||
switch value.(string) {
|
||||
@@ -74,6 +74,6 @@ func ConfigLevelToLogLevel(level string) slog.Level {
|
||||
|
||||
// LogLevel returns the configured level as an slog level. An unknown level
|
||||
// gives 99, above every real level, so nothing is logged.
|
||||
func (c *JobSearchConfigLogging) LogLevel() slog.Level {
|
||||
func (c *JSCLogging) LogLevel() slog.Level {
|
||||
return ConfigLevelToLogLevel(c.Level)
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func TestDefaults(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoggingSection(t *testing.T) {
|
||||
c := JobSearchConfigLogging{Level: "info", File: "/tmp/x.log"}
|
||||
c := JSCLogging{Level: "info", File: "/tmp/x.log"}
|
||||
|
||||
if got, want := c.Keys(), []string{"level", "file"}; !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Keys = %v; want %v", got, want)
|
||||
@@ -100,7 +100,7 @@ func TestLoggingSection(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoggingLevelValidation(t *testing.T) {
|
||||
var c JobSearchConfigLogging
|
||||
var c JSCLogging
|
||||
for _, lvl := range []string{"debug", "info", "warn", "error"} {
|
||||
if err := c.SetValue("level", lvl); err != nil || c.Level != lvl {
|
||||
t.Errorf("SetValue(level, %q) = %v, Level = %q", lvl, err, c.Level)
|
||||
@@ -142,7 +142,7 @@ func TestConfigLevelToLogLevel(t *testing.T) {
|
||||
if got := ConfigLevelToLogLevel(in); got != want {
|
||||
t.Errorf("ConfigLevelToLogLevel(%q) = %v; want %v", in, got, want)
|
||||
}
|
||||
c := JobSearchConfigLogging{Level: in}
|
||||
c := JSCLogging{Level: in}
|
||||
if got := c.LogLevel(); got != want {
|
||||
t.Errorf("LogLevel() with %q = %v; want %v", in, got, want)
|
||||
}
|
||||
@@ -187,9 +187,9 @@ func TestConcreteSourceSections(t *testing.T) {
|
||||
apiRoot bool
|
||||
blockShutdown bool
|
||||
}{
|
||||
{JSCKSourceFindATender, &JobSearchConfigSourceFindATender{}, true, false},
|
||||
{JSCKSourceFTSMock, &JobSearchConfigSourceFTSMock{}, true, false},
|
||||
{JSCKSourceSleeper, &JobSearchConfigSourceSleeper{}, false, true},
|
||||
{JSCKSourceFindATender, &JSCSourceFindATender{}, true, false},
|
||||
{JSCKSourceFTSMock, &JSCSourceFTSMock{}, true, false},
|
||||
{JSCKSourceSleeper, &JSCSourceSleeper{}, false, true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.prefix, func(t *testing.T) {
|
||||
@@ -252,7 +252,7 @@ func TestConcreteSourceSections(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSourcesSection(t *testing.T) {
|
||||
var c JobSearchConfigSources
|
||||
var c JSCSources
|
||||
if err := c.SetValue("fts_mock.api_root", "http://mock"); err != nil {
|
||||
t.Fatalf("SetValue: %v", err)
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func TestLoadFromViperInvalidValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDatabaseSection(t *testing.T) {
|
||||
c := JobSearchConfigDatabase{File: "./jobsearch.db"}
|
||||
c := JSCDatabase{File: "./jobsearch.db"}
|
||||
|
||||
if got, want := c.Keys(), []string{"file"}; !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Keys = %v; want %v", got, want)
|
||||
@@ -501,6 +501,8 @@ func TestViperValue(t *testing.T) {
|
||||
viper.Set("s", "text")
|
||||
viper.Set("i", "42") // strings are converted
|
||||
viper.Set("b", "true")
|
||||
viper.Set("env_list", "a, b") // e.g. from an environment variable
|
||||
viper.Set("file_list", []any{"a", "b"}) // e.g. from a YAML list
|
||||
|
||||
for _, tt := range []struct {
|
||||
key string
|
||||
@@ -510,13 +512,15 @@ func TestViperValue(t *testing.T) {
|
||||
{"s", reflect.String, "text"},
|
||||
{"i", reflect.Int, 42},
|
||||
{"b", reflect.Bool, true},
|
||||
{"env_list", reflect.Slice, "a, b"}, // split by SetValue
|
||||
{"file_list", reflect.Slice, []string{"a", "b"}},
|
||||
} {
|
||||
got, ok := viperValue(tt.key, tt.kind)
|
||||
if !ok || got != tt.want {
|
||||
if !ok || !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("viperValue(%q, %v) = %#v, %v; want %#v", tt.key, tt.kind, got, ok, tt.want)
|
||||
}
|
||||
}
|
||||
for _, kind := range []reflect.Kind{reflect.Float64, reflect.Int8, reflect.Slice} {
|
||||
for _, kind := range []reflect.Kind{reflect.Float64, reflect.Int8, reflect.Map} {
|
||||
if got, ok := viperValue("i", kind); ok {
|
||||
t.Errorf("viperValue(i, %v) = %#v, true; want unhandled", kind, got)
|
||||
}
|
||||
|
||||
@@ -5,29 +5,29 @@ import "reflect"
|
||||
// JSCKSourceFindATender is the Find a Tender source's configuration key.
|
||||
const JSCKSourceFindATender string = "find_a_tender"
|
||||
|
||||
// JobSearchConfigSourceFindATender configures fetching from the Find a Tender
|
||||
// JSCSourceFindATender configures fetching from the Find a Tender
|
||||
// OCDS API at APIRoot.
|
||||
type JobSearchConfigSourceFindATender struct {
|
||||
type JSCSourceFindATender struct {
|
||||
JobSearchConfigSource
|
||||
APIRoot string `cfg:"api_root" default:"https://www.find-tender.service.gov.uk/api/1.0"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigSourceFindATender) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCSourceFindATender) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigSourceFindATender) Flatten() map[string]any {
|
||||
func (c JSCSourceFindATender) Flatten() map[string]any {
|
||||
return flattenOf(JSCKSourceFindATender, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceFindATender) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCSourceFindATender) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceFindATender) ValueOf(key string) (any, error) {
|
||||
func (c JSCSourceFindATender) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigSourceFindATender) SetValue(key string, value any) error {
|
||||
func (c *JSCSourceFindATender) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
@@ -5,29 +5,29 @@ import "reflect"
|
||||
// JSCKSourceFTSMock is the Find a Tender mock source's configuration key.
|
||||
const JSCKSourceFTSMock string = "fts_mock"
|
||||
|
||||
// JobSearchConfigSourceFTSMock configures fetching from a Find a Tender mock
|
||||
// JSCSourceFTSMock configures fetching from a Find a Tender mock
|
||||
// server (cmd/mock-fts) at APIRoot.
|
||||
type JobSearchConfigSourceFTSMock struct {
|
||||
type JSCSourceFTSMock struct {
|
||||
JobSearchConfigSource
|
||||
APIRoot string `cfg:"api_root"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigSourceFTSMock) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCSourceFTSMock) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigSourceFTSMock) Flatten() map[string]any {
|
||||
func (c JSCSourceFTSMock) Flatten() map[string]any {
|
||||
return flattenOf(JSCKSourceFTSMock, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceFTSMock) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCSourceFTSMock) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceFTSMock) ValueOf(key string) (any, error) {
|
||||
func (c JSCSourceFTSMock) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigSourceFTSMock) SetValue(key string, value any) error {
|
||||
func (c *JSCSourceFTSMock) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
@@ -5,30 +5,30 @@ import "reflect"
|
||||
// JSCKSourceSleeper is the sleeper source's configuration key.
|
||||
const JSCKSourceSleeper string = "sleeper"
|
||||
|
||||
// JobSearchConfigSourceSleeper configures the sleeper, a test source that
|
||||
// JSCSourceSleeper configures the sleeper, a test source that
|
||||
// simulates work by sleeping. With BlockShutdown its work ignores
|
||||
// cancellation, to test shutdown waiting on a non-cooperative task.
|
||||
type JobSearchConfigSourceSleeper struct {
|
||||
type JSCSourceSleeper struct {
|
||||
JobSearchConfigSource
|
||||
BlockShutdown bool `cfg:"block_shutdown"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigSourceSleeper) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCSourceSleeper) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigSourceSleeper) Flatten() map[string]any {
|
||||
func (c JSCSourceSleeper) Flatten() map[string]any {
|
||||
return flattenOf(JSCKSourceSleeper, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceSleeper) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCSourceSleeper) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSourceSleeper) ValueOf(key string) (any, error) {
|
||||
func (c JSCSourceSleeper) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigSourceSleeper) SetValue(key string, value any) error {
|
||||
func (c *JSCSourceSleeper) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
@@ -8,35 +8,35 @@ import (
|
||||
// JSCKSources is the sources section's configuration key.
|
||||
const JSCKSources string = "sources"
|
||||
|
||||
// JobSearchConfigSources configures each source of opportunities, one field
|
||||
// JSCSources configures each source of opportunities, one field
|
||||
// per source. Each field's cfg tag must match the section's JSCK* constant.
|
||||
type JobSearchConfigSources struct {
|
||||
FindATender JobSearchConfigSourceFindATender `cfg:"find_a_tender"`
|
||||
FTSMock JobSearchConfigSourceFTSMock `cfg:"fts_mock"`
|
||||
Sleeper JobSearchConfigSourceSleeper `cfg:"sleeper"`
|
||||
type JSCSources struct {
|
||||
FindATender JSCSourceFindATender `cfg:"find_a_tender"`
|
||||
FTSMock JSCSourceFTSMock `cfg:"fts_mock"`
|
||||
Sleeper JSCSourceSleeper `cfg:"sleeper"`
|
||||
}
|
||||
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigSources) Map() map[string]any { return mapOf(c) }
|
||||
func (c JSCSources) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
func (c JobSearchConfigSources) Flatten() map[string]any {
|
||||
func (c JSCSources) Flatten() map[string]any {
|
||||
return flattenOf(JSCKSources, c)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSources) TypeOf(key string) (reflect.Kind, error) {
|
||||
func (c JSCSources) TypeOf(key string) (reflect.Kind, error) {
|
||||
return typeOf(c, key)
|
||||
}
|
||||
|
||||
func (c JobSearchConfigSources) ValueOf(key string) (any, error) {
|
||||
func (c JSCSources) ValueOf(key string) (any, error) {
|
||||
return valueOf(c, key)
|
||||
}
|
||||
|
||||
func (c *JobSearchConfigSources) SetValue(key string, value any) error {
|
||||
func (c *JSCSources) SetValue(key string, value any) error {
|
||||
return setValue(c, key, value)
|
||||
}
|
||||
|
||||
// ---------- Generic Source definition ----------
|
||||
// ========== Generic source ==========
|
||||
|
||||
// JobSearchConfigSource holds the settings every source has, and is embedded
|
||||
// in each source's section. Interval is how often an enabled source fetches.
|
||||
@@ -45,7 +45,7 @@ type JobSearchConfigSource struct {
|
||||
Interval time.Duration `cfg:"interval" default:"10m"`
|
||||
}
|
||||
|
||||
// ---------- Section methods for Source (see Section) ----------
|
||||
// ---------- Section methods (see Section) ----------
|
||||
|
||||
func (c JobSearchConfigSource) Map() map[string]any { return mapOf(c) }
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ const EtcConfigPath string = "/etc/job-search"
|
||||
// JobSearchConfig is the application's whole configuration, one field per
|
||||
// section. Each field's cfg tag must match the section's JSCK* constant.
|
||||
type JobSearchConfig struct {
|
||||
Logging JobSearchConfigLogging `cfg:"logging"`
|
||||
Database JobSearchConfigDatabase `cfg:"database"`
|
||||
Sources JobSearchConfigSources `cfg:"sources"`
|
||||
Database JSCDatabase `cfg:"database"`
|
||||
Logging JSCLogging `cfg:"logging"`
|
||||
Sources JSCSources `cfg:"sources"`
|
||||
}
|
||||
|
||||
// LoadDefaultConfig sets Viper's defaults from the configuration's default
|
||||
|
||||
@@ -106,7 +106,7 @@ func TestInitKeepsCommandLineLevel(t *testing.T) {
|
||||
initDir(t, []string{}, "logging:\n level: info\n")
|
||||
logs := captureLogs(t, slog.LevelDebug)
|
||||
|
||||
conf := JobSearchConfig{Logging: JobSearchConfigLogging{Level: level}}
|
||||
conf := JobSearchConfig{Logging: JSCLogging{Level: level}}
|
||||
if err := Init("", &conf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user