feat(backup): CLI backup/list/restore (#89)

Implement CLI interface for the backup module with three subcommands:
- backup: create a backup and apply rotation
- list: list available backups
- restore: restore a specific backup

Also add __main__.py to enable 'python -m src.backup'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Colin Maudry
2026-06-24 17:23:57 +02:00
parent ded5e66ccc
commit 1453990f7a
3 changed files with 92 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
import sqlite3
from pathlib import Path
from cryptography.fernet import Fernet
from src.backup import cli
from tests.backup.fakes import FakeStorage
def _env(tmp_path: Path) -> dict:
db = tmp_path / "users.sqlite"
conn = sqlite3.connect(str(db))
conn.execute("CREATE TABLE t (val TEXT)")
conn.execute("INSERT INTO t VALUES ('v1')")
conn.commit()
conn.close()
return {
"USERS_DB_PATH": str(db),
"S3_BUCKET": "b",
"S3_BACKUP_PREFIX": "backups",
"S3_ENDPOINT_URL": "",
"S3_ACCESS_KEY_ID": "AK",
"S3_SECRET_ACCESS_KEY": "SK",
"BACKUP_ENCRYPTION_KEY": Fernet.generate_key().decode(),
}
def test_backup_then_list(tmp_path, capsys):
env = _env(tmp_path)
storage = FakeStorage()
assert cli.main(["backup"], env=env, storage=storage) == 0
assert cli.main(["list"], env=env, storage=storage) == 0
out = capsys.readouterr().out
assert "users-" in out
assert len(storage.objects) == 1