Skip to content

feat: per-user TOML config for default voice/speed/lang#19

Merged
StuBehan merged 1 commit into
mainfrom
feat/user-config-file
Apr 30, 2026
Merged

feat: per-user TOML config for default voice/speed/lang#19
StuBehan merged 1 commit into
mainfrom
feat/user-config-file

Conversation

@StuBehan
Copy link
Copy Markdown
Collaborator

Summary

Small config-file layer so users don't have to pass `--voice bf_emma --speed 1.1` on every invocation. Drop the values into a TOML file and they become argparse defaults; flags still override.

```toml

~/.config/stackvox/config.toml

[defaults]
voice = "bf_emma"
speed = 1.1
lang = "en-gb"
```

Resolution rules

  • File location: `STACKVOX_CONFIG` env var > `$XDG_CONFIG_HOME/stackvox/config.toml` > `~/.config/stackvox/config.toml`.
  • Value priority: CLI flag > config file > built-in engine default, per key.
  • Tolerant: missing file → built-ins. Malformed TOML → warning logged, built-ins. `defaults` not a table → warning, built-ins. Never blocks startup.

Changes

  • New `stackvox/config.py` — `Defaults` dataclass, `config_path()`, `load_defaults()`. 36 statements, 100% line coverage.
  • `cli.py`: `_build_parser(defaults)` and `_add_voice_args(parser, defaults)` accept a `Defaults` object; `main()` calls `config.load_defaults()` and feeds it through.
  • `pyproject.toml`: `tomli>=2.0;python_version<'3.11'` (3.11+ uses stdlib `tomllib`); `mypy` `ignore_missing_imports` extended to `tomli` so the 3.10 fallback branch type-checks on 3.11+.
  • README: new "Configuration" section showing the file format.
  • `tests/test_config.py`: path resolution (env + XDG + ~/.config), loading (missing/empty/full/partial/malformed/wrong-shape), and smoke tests that argparse defaults pick up the config and that explicit flags still override.

Coverage

84 tests pass (was 73). Overall coverage: 87% → 87% (new module fully tested). `stackvox/config.py` at 100%.

Test plan

  • CI passes (lint, format, mypy, tests 3.10–3.13 Ubuntu, test-macos py3.12, PR-title, commit lint).
  • Manually: drop a config.toml with a voice override, run `stackvox "hi"`, verify it uses the configured voice.
  • Manually: pass `--voice X` on the command line, verify it overrides the config.

Adds a small config-file layer so users don't have to repeat
`--voice bf_emma --speed 1.1` on every invocation.

 - Reads `$XDG_CONFIG_HOME/stackvox/config.toml` (falling back to
   `~/.config/stackvox/config.toml`) or whatever `STACKVOX_CONFIG`
   points at if set.
 - File format: a [defaults] table with `voice`, `speed`, `lang` keys.
   Per-key fallback to built-in engine defaults — set only what you
   care about.
 - Tolerant: missing file → built-ins, malformed TOML → warning + built-ins,
   wrong shape → warning + built-ins. Never blocks startup.
 - Argparse priority: CLI flag > config file > engine default.
 - tomllib on 3.11+, conditional `tomli>=2.0` dep on 3.10.

 - tests/test_config.py: path resolution (env + XDG + ~/.config),
   loading (missing/empty/full/partial/malformed/wrong-shape), and
   smoke tests that argparse defaults pick up the config (and that
   explicit flags still override it).
 - README gets a Configuration section showing the file.
 - mypy `ignore_missing_imports` extended to `tomli` so the 3.10
   fallback branch type-checks on 3.11+.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@StuBehan StuBehan force-pushed the feat/user-config-file branch from 2ff279d to 78189bf Compare April 30, 2026 11:50
@StuBehan StuBehan merged commit 2eaefff into main Apr 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant