From a3424c36e5fb739b4d4c0ea27422a255a8d143d5 Mon Sep 17 00:00:00 2001 From: m3ta-chiron Date: Sun, 18 Oct 2026 20:46:39 +0200 Subject: [PATCH] feat(config): Ansage-Label wrap.label mit Env-Override TALK_WRAP_LABEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Config-Schlüssel [wrap] label für talk wrap (Task 07): ersetzt den Basisnamen des Befehls in der Ansage („Deployment erfolgreich. Dauer: …“ statt „terraform erfolgreich. …“). Auflösung wie üblich Defaults → config.toml → Env (TALK_WRAP_LABEL schlägt die Datei); Tisch-Tests für alle drei Schichten. --- internal/config/config.go | 15 ++++++++++ internal/config/config_test.go | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/internal/config/config.go b/internal/config/config.go index 325abf1..6b32f93 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -61,6 +61,9 @@ type Config struct { // eingebauten neutralen Defaults; das CLI-Flag --voice schlägt alles. Voice map[string]map[string]string `toml:"voice"` + // Wrap steuert die Befehlsummwicklung `talk wrap` (Task 07). + Wrap Wrap `toml:"wrap"` + // QuietHours ist das Ruhezeit-Fenster "HH:MM-HH:MM" in lokaler Zeit // (überspannt Mitternacht, z. B. "18:00-08:00"); leer = deaktiviert. // Bewusst kein Default-Fenster: Ein aktives Gesetz, das nach Uhrzeit @@ -96,6 +99,15 @@ type Server struct { AllowedOrigins []string `toml:"allowed_origins"` } +// Wrap sind die Einstellungen von `talk wrap` (TOML `[wrap]`). +type Wrap struct { + // Label ersetzt den Basisnamen des Befehls in der Ansage — z. B. + // `label = "Deployment"` für „Deployment erfolgreich. Dauer: …" + // statt „terraform erfolgreich. Dauer: …" (Env-Override + // TALK_WRAP_LABEL schlägt die Datei). + Label string `toml:"label"` +} + // Queue sind die Rate-Limit-Gesetze des Daemons (TOML `[queue]`). type Queue struct { // RateLimit ist der Mindestabstand zwischen zwei Ansage-Starten als @@ -198,6 +210,9 @@ func applyEnv(cfg Config, getenv func(string) string) (Config, error) { cfg.Server.AllowedOrigins = origins } } + if v := getenv("TALK_WRAP_LABEL"); v != "" { + cfg.Wrap.Label = v + } if v := getenv("TALK_RATE_LIMIT"); v != "" { d, err := time.ParseDuration(v) if err != nil || d < 0 { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 86efe94..80184b2 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -294,6 +294,58 @@ de = "de-DE-KatjaNeural" // TestLoadServerPort deckt die Task-04-Felder ab: Daemon-Port per Defaults // (7800), TOML [server] port, Env-Override TALK_PORT samt Validierung. +// TestLoadWrapLabel: das Ansage-Label von `talk wrap` (Task 07) — +// Defaults → TOML → Env nach dem üblichen Schichten-Muster. +func TestLoadWrapLabel(t *testing.T) { + writeTOML := func(t *testing.T, content string) string { + t.Helper() + path := filepath.Join(t.TempDir(), "config.toml") + if err := os.WriteFile(path, []byte(content), 0o644); err != nil { + t.Fatal(err) + } + return path + } + + t.Run("Default leer (Basisname des Befehls)", func(t *testing.T) { + cfg, err := Load(Options{ + File: filepath.Join(t.TempDir(), "gibt-es-nicht.toml"), + Getenv: env(nil), + }) + if err != nil { + t.Fatalf("Load: %v", err) + } + if cfg.Wrap.Label != "" { + t.Errorf("Wrap.Label = %q, want leer (Default)", cfg.Wrap.Label) + } + }) + + t.Run("TOML überschreibt Default", func(t *testing.T) { + cfg, err := Load(Options{ + File: writeTOML(t, "[wrap]\nlabel = \"Deployment\"\n"), + Getenv: env(nil), + }) + if err != nil { + t.Fatalf("Load: %v", err) + } + if cfg.Wrap.Label != "Deployment" { + t.Errorf("Wrap.Label = %q, want %q aus TOML", cfg.Wrap.Label, "Deployment") + } + }) + + t.Run("TALK_WRAP_LABEL schlägt Datei", func(t *testing.T) { + cfg, err := Load(Options{ + File: writeTOML(t, "[wrap]\nlabel = \"Deployment\"\n"), + Getenv: env(map[string]string{"TALK_WRAP_LABEL": "Nightly Build"}), + }) + if err != nil { + t.Fatalf("Load: %v", err) + } + if cfg.Wrap.Label != "Nightly Build" { + t.Errorf("Wrap.Label = %q, want Env-Override %q", cfg.Wrap.Label, "Nightly Build") + } + }) +} + func TestLoadServerPort(t *testing.T) { writeTOML := func(t *testing.T, content string) string { t.Helper()