codex-manager 5.0.0__tar.gz → 7.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_manager-5.0.0 → codex_manager-7.0.0}/PKG-INFO +1 -1
- {codex_manager-5.0.0 → codex_manager-7.0.0}/pyproject.toml +1 -1
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/__init__.py +1 -1
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/args.py +8 -1
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cli.py +9 -2
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/PKG-INFO +1 -1
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/SOURCES.txt +1 -0
- codex_manager-7.0.0/tests/test_backup_ux.py +36 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_more.py +1 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/README.md +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/setup.cfg +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/account_status.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/backup.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cloud.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/config.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/cooldown.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/credentials.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/doctor.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/list_backups.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/profile.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/prune.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/prune_backups.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/purge.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/recommend.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/registry.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/remove.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/restore.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/status.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/sync.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/ui.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/use_account.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager/utils.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/dependency_links.txt +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/entry_points.txt +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/requires.txt +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/src/codex_manager.egg-info/top_level.txt +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_account_status_coverage.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_account_status_more2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli_3.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_args_cli_extra.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_backup.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_backup2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_3.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_4.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_5.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_6.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_7.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_8.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cli_coverage_extra.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cloud.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_config.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cooldown.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_cooldown2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_credentials2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_doctor.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_doctor2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_dry_run_coverage.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups3.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_list_backups_coverage.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_next_gen_upgrade.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_profile.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune_backups.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_prune_backups2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_purge.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_recommend.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_recommend2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_registry_coverage_more.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_registry_dry_run_coverage.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_remove.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_restore.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_restore2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_status3.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_sync.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_sync2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_ui.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_ui_2.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_use.py +0 -0
- {codex_manager-5.0.0 → codex_manager-7.0.0}/tests/test_use2.py +0 -0
|
@@ -507,7 +507,14 @@ def get_parser() -> argparse.ArgumentParser:
|
|
|
507
507
|
list_backups_parser.add_argument(
|
|
508
508
|
"--latest-per-email",
|
|
509
509
|
action="store_true",
|
|
510
|
-
|
|
510
|
+
default=True,
|
|
511
|
+
help="Only show the latest backup for each email (Default).",
|
|
512
|
+
)
|
|
513
|
+
list_backups_parser.add_argument(
|
|
514
|
+
"--all",
|
|
515
|
+
action="store_false",
|
|
516
|
+
dest="latest_per_email",
|
|
517
|
+
help="Show all backups, including historical and duplicate entries.",
|
|
511
518
|
)
|
|
512
519
|
list_backups_parser.add_argument(
|
|
513
520
|
"--ready",
|
|
@@ -31,7 +31,8 @@ from .use_account import perform_use, use_result_to_text
|
|
|
31
31
|
|
|
32
32
|
def list_entries_from_args(args: Any) -> list[BackupEntry]:
|
|
33
33
|
force_latest = args.command in ["cooldown", "recommend"]
|
|
34
|
-
|
|
34
|
+
# For list-backups, it now defaults to True in args.py, but we ensure it here
|
|
35
|
+
latest_per_email = getattr(args, "latest_per_email", True) or force_latest
|
|
35
36
|
all_entries: list[BackupEntry] = []
|
|
36
37
|
|
|
37
38
|
backup_dir = Path(args.backup_dir).expanduser()
|
|
@@ -283,7 +284,13 @@ def handle_status(args: Any) -> None:
|
|
|
283
284
|
|
|
284
285
|
|
|
285
286
|
def handle_backup(args: Any) -> None:
|
|
286
|
-
|
|
287
|
+
try:
|
|
288
|
+
archive_path, metadata_path, metadata = perform_backup(args)
|
|
289
|
+
except FileExistsError as exc:
|
|
290
|
+
console.print(f"[bold red]Stop:[/] {exc}")
|
|
291
|
+
console.print(f"[dim]Note: Backups are named after the account's weekly reset time.[/]")
|
|
292
|
+
console.print(f"[dim]If you want to update your current snapshot, run with: [bold white]--force[/][/]")
|
|
293
|
+
sys.exit(1)
|
|
287
294
|
|
|
288
295
|
if getattr(args, "cloud", False):
|
|
289
296
|
cp = get_cloud_provider(args)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from types import SimpleNamespace
|
|
4
|
+
from codex_manager.cli import handle_backup
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
def test_handle_backup_file_exists_clean_error(tmp_path, capsys, mocker):
|
|
8
|
+
# Setup
|
|
9
|
+
backup_dir = tmp_path / "backups"
|
|
10
|
+
backup_dir.mkdir()
|
|
11
|
+
archive_name = "2026-01-01-test@example.com-codex.tar.gz"
|
|
12
|
+
(backup_dir / archive_name).write_text("existing")
|
|
13
|
+
|
|
14
|
+
args = SimpleNamespace(
|
|
15
|
+
command="backup",
|
|
16
|
+
backup_dir=str(backup_dir),
|
|
17
|
+
force=False,
|
|
18
|
+
cloud=False,
|
|
19
|
+
dry_run=False
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Mock perform_backup to raise the error like it does in real life
|
|
23
|
+
mocker.patch("codex_manager.cli.perform_backup", side_effect=FileExistsError(f"Archive already exists: {archive_name}. Use --force to overwrite."))
|
|
24
|
+
|
|
25
|
+
with pytest.raises(SystemExit) as exc:
|
|
26
|
+
handle_backup(args)
|
|
27
|
+
|
|
28
|
+
assert exc.value.code == 1
|
|
29
|
+
captured = capsys.readouterr()
|
|
30
|
+
assert "Stop:" in captured.out
|
|
31
|
+
assert "--force" in captured.out
|
|
32
|
+
assert "weekly reset time" in captured.out
|
|
33
|
+
|
|
34
|
+
if __name__ == "__main__":
|
|
35
|
+
# Just a simple run to see it visually if needed
|
|
36
|
+
pass
|
|
@@ -44,6 +44,7 @@ def test_list_entries_from_args_cooldown_no_cloud(mocker, tmp_path):
|
|
|
44
44
|
backup_dir = str(tmp_path)
|
|
45
45
|
cloud = False
|
|
46
46
|
args = Args()
|
|
47
|
+
mocker.patch("codex_manager.cli.get_cloud_provider", return_value=None)
|
|
47
48
|
entries = list_entries_from_args(args)
|
|
48
49
|
assert entries == []
|
|
49
50
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|