feat(operations): backup-to-template grouping fix + artifact/backup delete

_template_of_backup only stripped one "_"-chunk off the archive name,
so real Template_<name>_%Y%m%d_%H%M%S.7z files (date *and* time) never
matched their template -- backups silently failed to show up grouped
under it. Replaced with a regex that strips the full optional
date+time suffix and tolerates underscores in template names.

Also adds delete_artifact/delete_backup (mirrored, containment-checked
single-file deletion) and backups_by_template (groups list_backups()
output by parsed template name, newest-first) for the web dashboard's
per-item delete actions and the Templates panel's per-row backup list.
This commit is contained in:
2026-07-24 22:04:25 +02:00
parent 2dabdf0ae1
commit 4541dccf9c
2 changed files with 147 additions and 0 deletions
+21
View File
@@ -162,6 +162,27 @@ def test_list_templates_last_backup_picks_newest_matching_archive(tmp_path: Path
assert info.last_backup.name == "Template_LinuxBuild2404_20260601_000000.7z"
@pytest.mark.parametrize(
("filename", "expected"),
[
# Real archive shape: ``Template_<name>_%Y%m%d_%H%M%S.7z`` -- both the
# date and the time chunk must be stripped (regression: only the time
# chunk was, leaving "LinuxBuild2404_20260722").
("Template_LinuxBuild2404_20260722_145001.7z", "LinuxBuild2404"),
("Template_WinBuild2025_20260101_000000.7z", "WinBuild2025"),
# Template names containing underscores survive intact.
("Template_Win_Build_2025_20260722_145001.7z", "Win_Build_2025"),
# Date-only shape (no time chunk) is still tolerated.
("Template_LinuxBuild2404_20260722.7z", "LinuxBuild2404"),
# Non-matching names parse to None.
("not-a-template-archive.7z", None),
("Template_no_timestamp.txt", None),
],
)
def test_template_of_backup_strips_full_timestamp(filename: str, expected: str | None) -> None:
assert inventory_module._template_of_backup(filename) == expected
def test_list_templates_last_backup_none_when_no_backups_dir(tmp_path: Path) -> None:
(tmp_path / "templates" / "LinuxBuild2404").mkdir(parents=True)
config = _make_config(tmp_path)