Support for post annotation label reassignement.

This commit is contained in:
sebastien committed 2026-10-11 19:03:04 +02:00
1 parent 698ac4240c
commit 370f3252ef
10 files changed
+242 -36

No files matched your search

+42
View File
@@ -92,3 +92,45 @@ def staged_files(
if not destination_path.exists():
saved.replace(destination_path)
_remove_path(backup)
def publish_file_sets(file_sets: dict[Path, tuple[Path, Iterable[str]]]) -> None:
"""Commit several staged file sets together, rolling every set back on error.
Staging and destination directories must be on the same filesystem. Unlike
nesting staged_files, failure in a later directory restores earlier ones too.
"""
token = uuid.uuid4().hex
backups: list[tuple[Path, Path]] = []
committed: list[Path] = []
try:
for target, (staging, remove) in file_sets.items():
target.mkdir(parents=True, exist_ok=True)
backup = target / f".publish-{token}.backup"
backup.mkdir()
backups.append((target, backup))
staged = sorted(path for path in staging.iterdir() if path.is_file())
names = {path.name for path in staged} | set(remove)
for name in sorted(names):
if Path(name).name != name:
raise ValueError(f"Invalid output filename: {name}")
destination = target / name
if destination.exists() or destination.is_symlink():
destination.replace(backup / name)
for source in staged:
destination = target / source.name
source.replace(destination)
committed.append(destination)
except Exception:
for destination in reversed(committed):
_remove_path(destination)
for target, backup in reversed(backups):
for saved in backup.iterdir():
saved.replace(target / saved.name)
raise
finally:
for _, backup in backups:
if backup.exists() and not any(backup.iterdir()):
backup.rmdir()
for _, backup in backups:
_remove_path(backup)