diff --git a/gates/profiles.py b/gates/profiles.py index 17d4051..069ee4c 100644 --- a/gates/profiles.py +++ b/gates/profiles.py @@ -80,3 +80,21 @@ def delete_profile(base, pid): if d.exists(): shutil.rmtree(d) return reg + + +def duplicate_profile(base, src_id, name, new_id, ts=0): + reg = read_registry(base) + if not find_by_id(reg, src_id): + raise KeyError(src_id) + if find_by_name(reg, name): + raise ValueError(f"profile name already exists: {name}") + src = Path(base) / src_id + dst = Path(base) / new_id + if src.exists(): + shutil.copytree(src, dst) + else: + dst.mkdir(parents=True, exist_ok=True) + entry = {"id": new_id, "name": name, "created": ts} + reg["profiles"].append(entry) + write_registry(base, reg) + return entry diff --git a/tests/test_profiles.py b/tests/test_profiles.py index 62f9a6f..40ecd1a 100644 --- a/tests/test_profiles.py +++ b/tests/test_profiles.py @@ -54,3 +54,16 @@ def test_delete_profile_removes_dir_and_entry(tmp_path): pr.delete_profile(str(tmp_path), "id1") assert not (tmp_path / "id1").exists() assert pr.find_by_id(pr.read_registry(str(tmp_path)), "id1") is None + +def test_duplicate_copies_images(tmp_path): + pr.create_profile(str(tmp_path), "src", "id1") + (tmp_path / "id1" / "img_0001.png").write_bytes(b"abc") + e = pr.duplicate_profile(str(tmp_path), "id1", "copy", "id2", ts=5) + assert e == {"id": "id2", "name": "copy", "created": 5} + assert (tmp_path / "id2" / "img_0001.png").read_bytes() == b"abc" + +def test_duplicate_duplicate_name_raises(tmp_path): + import pytest + pr.create_profile(str(tmp_path), "src", "id1") + with pytest.raises(ValueError): + pr.duplicate_profile(str(tmp_path), "id1", "src", "id2")