feat: add archive_folder support for preserving previous generations
When archive_folder is set in the project config, artifacts are moved to numbered archive copies (e.g. x.01.jpg, x.02.jpg) instead of being overwritten or deleted. - Build command archives existing artifacts before rebuilding dirty targets - Clean command moves files to archive instead of deleting them - Subfolder structure is preserved in the archive directory - State file is always deleted, never archived
This commit is contained in:
parent
9ace38c806
commit
24cade558a
7 changed files with 272 additions and 8 deletions
75
tests/test_archive.py
Normal file
75
tests/test_archive.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"""Tests for hokusai.archive."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from hokusai.archive import archive_file
|
||||
|
||||
|
||||
class TestArchiveFile:
|
||||
"""Test the archive_file helper."""
|
||||
|
||||
def test_archives_with_01_suffix(self, tmp_path: Path) -> None:
|
||||
src = tmp_path / "image.jpg"
|
||||
_ = src.write_text("v1")
|
||||
|
||||
dest = archive_file(src, tmp_path, "archive")
|
||||
|
||||
assert dest is not None
|
||||
assert dest == tmp_path / "archive" / "image.01.jpg"
|
||||
assert dest.read_text() == "v1"
|
||||
assert not src.exists()
|
||||
|
||||
def test_increments_number(self, tmp_path: Path) -> None:
|
||||
archive_dir = tmp_path / "archive"
|
||||
archive_dir.mkdir()
|
||||
_ = (archive_dir / "image.01.jpg").write_text("old")
|
||||
|
||||
src = tmp_path / "image.jpg"
|
||||
_ = src.write_text("v2")
|
||||
|
||||
dest = archive_file(src, tmp_path, "archive")
|
||||
|
||||
assert dest is not None
|
||||
assert dest == archive_dir / "image.02.jpg"
|
||||
assert dest.read_text() == "v2"
|
||||
|
||||
def test_preserves_subfolder_structure(self, tmp_path: Path) -> None:
|
||||
sub = tmp_path / "img"
|
||||
sub.mkdir()
|
||||
src = sub / "photo.png"
|
||||
_ = src.write_text("data")
|
||||
|
||||
dest = archive_file(src, tmp_path, "archive")
|
||||
|
||||
assert dest is not None
|
||||
assert dest == tmp_path / "archive" / "img" / "photo.01.png"
|
||||
|
||||
def test_returns_none_for_missing_file(self, tmp_path: Path) -> None:
|
||||
src = tmp_path / "nonexistent.txt"
|
||||
assert archive_file(src, tmp_path, "archive") is None
|
||||
|
||||
def test_creates_archive_dir(self, tmp_path: Path) -> None:
|
||||
src = tmp_path / "file.txt"
|
||||
_ = src.write_text("content")
|
||||
|
||||
dest = archive_file(src, tmp_path, "my_archive")
|
||||
|
||||
assert dest is not None
|
||||
assert (tmp_path / "my_archive").is_dir()
|
||||
|
||||
def test_skips_existing_numbers(self, tmp_path: Path) -> None:
|
||||
archive_dir = tmp_path / "archive"
|
||||
archive_dir.mkdir()
|
||||
_ = (archive_dir / "x.01.txt").write_text("a")
|
||||
_ = (archive_dir / "x.02.txt").write_text("b")
|
||||
_ = (archive_dir / "x.03.txt").write_text("c")
|
||||
|
||||
src = tmp_path / "x.txt"
|
||||
_ = src.write_text("d")
|
||||
|
||||
dest = archive_file(src, tmp_path, "archive")
|
||||
|
||||
assert dest is not None
|
||||
assert dest == archive_dir / "x.04.txt"
|
||||
Loading…
Add table
Add a link
Reference in a new issue