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
|
|
@ -412,6 +412,66 @@ class TestRunBuild:
|
|||
assert result.failed == {}
|
||||
|
||||
|
||||
class TestArchiveOnBuild:
|
||||
"""Test that build archives existing artifacts when archive_folder is set."""
|
||||
|
||||
async def test_build_archives_existing_file(
|
||||
self, project_dir: Path, write_config: WriteConfig
|
||||
) -> None:
|
||||
config = write_config(
|
||||
{
|
||||
"archive_folder": "archive",
|
||||
"targets": {"out.txt": {"prompt": "version 1"}},
|
||||
}
|
||||
)
|
||||
with patch("hokusai.builder._create_providers", return_value=_fake_providers()):
|
||||
r1 = await run_build(config, project_dir, _PROJECT)
|
||||
assert r1.built == ["out.txt"]
|
||||
v1_content = (project_dir / "out.txt").read_text()
|
||||
|
||||
config2 = write_config(
|
||||
{
|
||||
"archive_folder": "archive",
|
||||
"targets": {"out.txt": {"prompt": "version 2"}},
|
||||
}
|
||||
)
|
||||
r2 = await run_build(config2, project_dir, _PROJECT)
|
||||
assert r2.built == ["out.txt"]
|
||||
|
||||
# v1 should be archived, v2 should be current
|
||||
archived = project_dir / "archive" / "out.01.txt"
|
||||
assert archived.exists()
|
||||
assert archived.read_text() == v1_content
|
||||
assert (project_dir / "out.txt").exists()
|
||||
|
||||
async def test_build_no_archive_without_setting(
|
||||
self, project_dir: Path, simple_text_config: ProjectConfig
|
||||
) -> None:
|
||||
with patch("hokusai.builder._create_providers", return_value=_fake_providers()):
|
||||
r1 = await run_build(simple_text_config, project_dir, _PROJECT)
|
||||
assert r1.built == ["output.txt"]
|
||||
|
||||
assert not (project_dir / "archive").exists()
|
||||
|
||||
async def test_build_archives_increment(
|
||||
self, project_dir: Path, write_config: WriteConfig
|
||||
) -> None:
|
||||
config_raw: dict[str, object] = {
|
||||
"archive_folder": "archive",
|
||||
"targets": {"out.txt": {"prompt": "v"}},
|
||||
}
|
||||
with patch("hokusai.builder._create_providers", return_value=_fake_providers()):
|
||||
for i in range(1, 4):
|
||||
cfg = write_config(
|
||||
{**config_raw, "targets": {"out.txt": {"prompt": f"v{i}"}}}
|
||||
)
|
||||
_ = await run_build(cfg, project_dir, _PROJECT)
|
||||
|
||||
assert (project_dir / "archive" / "out.01.txt").exists()
|
||||
assert (project_dir / "archive" / "out.02.txt").exists()
|
||||
assert not (project_dir / "archive" / "out.03.txt").exists()
|
||||
|
||||
|
||||
class TestDownloadTarget:
|
||||
"""Tests for download-type targets that fetch files from URLs."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue