From c20951b30935468aabecd43cd358c252e5b0eda9 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 9 Jul 2025 13:11:00 -0400 Subject: [PATCH] Add config set subcommand --- src/seedpass/cli.py | 34 +++++++++++++++++++++++++++++++++- src/tests/test_typer_cli.py | 27 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/seedpass/cli.py b/src/seedpass/cli.py index 2bce5e5..49896a2 100644 --- a/src/seedpass/cli.py +++ b/src/seedpass/cli.py @@ -22,7 +22,7 @@ fingerprint_option = typer.Option( entry_app = typer.Typer(help="Manage individual entries") vault_app = typer.Typer(help="Manage the entire vault") nostr_app = typer.Typer(help="Interact with Nostr relays") -config_app = typer.Typer(help="Manage configuration values") +config_app = typer.Typer(help="Get or set configuration values") fingerprint_app = typer.Typer(help="Manage seed profiles") util_app = typer.Typer(help="Utility commands") api_app = typer.Typer(help="Run the API server") @@ -354,6 +354,38 @@ def config_get(ctx: typer.Context, key: str) -> None: typer.echo(str(value)) +@config_app.command("set") +def config_set(ctx: typer.Context, key: str, value: str) -> None: + """Set a configuration value.""" + pm = _get_pm(ctx) + cfg = pm.config_manager + + mapping = { + "inactivity_timeout": lambda v: cfg.set_inactivity_timeout(float(v)), + "secret_mode_enabled": lambda v: cfg.set_secret_mode_enabled( + v.lower() in ("1", "true", "yes", "y", "on") + ), + "clipboard_clear_delay": lambda v: cfg.set_clipboard_clear_delay(int(v)), + "additional_backup_path": lambda v: cfg.set_additional_backup_path(v or None), + "relays": lambda v: cfg.set_relays( + [r.strip() for r in v.split(",") if r.strip()], require_pin=False + ), + } + + action = mapping.get(key) + if action is None: + typer.echo("Unknown key") + raise typer.Exit(code=1) + + try: + action(value) + except Exception as exc: # pragma: no cover - pass through errors + typer.echo(f"Error: {exc}") + raise typer.Exit(code=1) + + typer.echo("Updated") + + @fingerprint_app.command("list") def fingerprint_list(ctx: typer.Context) -> None: """List available seed profiles.""" diff --git a/src/tests/test_typer_cli.py b/src/tests/test_typer_cli.py index ea0969a..148c222 100644 --- a/src/tests/test_typer_cli.py +++ b/src/tests/test_typer_cli.py @@ -118,6 +118,33 @@ def test_config_get(monkeypatch): assert "1" in result.stdout +def test_config_set(monkeypatch): + called = {} + + def set_timeout(val): + called["timeout"] = float(val) + + pm = SimpleNamespace( + config_manager=SimpleNamespace(set_inactivity_timeout=set_timeout), + select_fingerprint=lambda fp: None, + ) + monkeypatch.setattr(cli, "PasswordManager", lambda: pm) + result = runner.invoke(app, ["config", "set", "inactivity_timeout", "5"]) + assert result.exit_code == 0 + assert called["timeout"] == 5.0 + assert "Updated" in result.stdout + + +def test_config_set_unknown_key(monkeypatch): + pm = SimpleNamespace( + config_manager=SimpleNamespace(), select_fingerprint=lambda fp: None + ) + monkeypatch.setattr(cli, "PasswordManager", lambda: pm) + result = runner.invoke(app, ["config", "set", "bogus", "val"]) + assert result.exit_code != 0 + assert "Unknown key" in result.stdout + + def test_nostr_sync(monkeypatch): called = {}