feat(config/m7-363): branding config field + defaults
This commit is contained in:
@@ -19,6 +19,7 @@ type Config struct {
|
||||
Subsonic SubsonicConfig `yaml:"subsonic"`
|
||||
Events EventsConfig `yaml:"events"`
|
||||
Recommendation RecommendationConfig `yaml:"recommendation"`
|
||||
Branding BrandingConfig `yaml:"branding"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
@@ -37,6 +38,14 @@ type StorageConfig struct {
|
||||
DataDir string `yaml:"data_dir"`
|
||||
}
|
||||
|
||||
// BrandingConfig drives per-instance UI labelling: the app name shown
|
||||
// in the header / tab title and the description used in OG share-preview
|
||||
// metadata. Both default to sensible values when unset.
|
||||
type BrandingConfig struct {
|
||||
AppName string `yaml:"app_name"`
|
||||
Description string `yaml:"description"`
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
URL string `yaml:"url"`
|
||||
}
|
||||
@@ -98,6 +107,10 @@ func Default() Config {
|
||||
Storage: StorageConfig{DataDir: "./data"},
|
||||
Database: DatabaseConfig{URL: ""},
|
||||
Log: LogConfig{Level: "info", Format: "text"},
|
||||
Branding: BrandingConfig{
|
||||
AppName: "Minstrel",
|
||||
Description: "Self-hosted music server with Subsonic compatibility, smart shuffle, and Lidarr integration.",
|
||||
},
|
||||
Events: EventsConfig{
|
||||
SessionTimeoutMinutes: 30,
|
||||
SkipMaxCompletionRatio: 0.5,
|
||||
@@ -150,6 +163,12 @@ func applyEnv(cfg *Config) {
|
||||
if v, ok := os.LookupEnv("SMARTMUSIC_LOG_FORMAT"); ok {
|
||||
cfg.Log.Format = strings.ToLower(v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("SMARTMUSIC_BRANDING_APP_NAME"); ok {
|
||||
cfg.Branding.AppName = v
|
||||
}
|
||||
if v, ok := os.LookupEnv("SMARTMUSIC_BRANDING_DESCRIPTION"); ok {
|
||||
cfg.Branding.Description = v
|
||||
}
|
||||
if v, ok := os.LookupEnv("SMARTMUSIC_AUTH_ADMIN_USERNAME"); ok {
|
||||
cfg.Auth.AdminBootstrap.Username = v
|
||||
}
|
||||
|
||||
@@ -151,3 +151,50 @@ func TestLibraryYAMLLoads(t *testing.T) {
|
||||
t.Error("scan_on_startup = false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBrandingDefaults(t *testing.T) {
|
||||
cfg := Default()
|
||||
if cfg.Branding.AppName != "Minstrel" {
|
||||
t.Errorf("AppName: got %q, want %q", cfg.Branding.AppName, "Minstrel")
|
||||
}
|
||||
if cfg.Branding.Description == "" {
|
||||
t.Errorf("Description: empty after Default(); want default tagline")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBrandingYAMLOverride(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.yaml")
|
||||
content := []byte(`branding:
|
||||
app_name: "Family Jukebox"
|
||||
description: "Our home library."
|
||||
`)
|
||||
if err := os.WriteFile(path, content, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg, err := Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
if cfg.Branding.AppName != "Family Jukebox" {
|
||||
t.Errorf("AppName: got %q", cfg.Branding.AppName)
|
||||
}
|
||||
if cfg.Branding.Description != "Our home library." {
|
||||
t.Errorf("Description: got %q", cfg.Branding.Description)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBrandingEnvOverride(t *testing.T) {
|
||||
t.Setenv("SMARTMUSIC_BRANDING_APP_NAME", "Office Music")
|
||||
t.Setenv("SMARTMUSIC_BRANDING_DESCRIPTION", "Office tunes.")
|
||||
cfg, err := Load("")
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
if cfg.Branding.AppName != "Office Music" {
|
||||
t.Errorf("AppName: got %q", cfg.Branding.AppName)
|
||||
}
|
||||
if cfg.Branding.Description != "Office tunes." {
|
||||
t.Errorf("Description: got %q", cfg.Branding.Description)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user