mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-11 02:44:30 +00:00
Normalize drum part pointer identities
This commit is contained in:
+12
-3
@@ -790,14 +790,23 @@ def _resolve_drum_parts(
|
|||||||
primary_name = None
|
primary_name = None
|
||||||
extra_parts: list[dict] = []
|
extra_parts: list[dict] = []
|
||||||
seen_rels: set[str] = set()
|
seen_rels: set[str] = set()
|
||||||
|
# Use the same canonical, traversal-safe identity as zip member lookup so
|
||||||
|
# equivalent spellings ("x.json", "./x.json", or backslashes) identify
|
||||||
|
# one file. Otherwise an alias pointer can reload and duplicate the primary.
|
||||||
|
primary_rel_key = (
|
||||||
|
_zip_member_key(drum_tab_rel.strip())
|
||||||
|
if isinstance(drum_tab_rel, str) and drum_tab_rel.strip() else None
|
||||||
|
)
|
||||||
for entry in drum_pointer_entries:
|
for entry in drum_pointer_entries:
|
||||||
rel = str(entry.get("drum_tab") or "").strip()
|
rel = str(entry.get("drum_tab") or "").strip()
|
||||||
if not rel or rel in seen_rels:
|
rel_key = _zip_member_key(rel) if rel else None
|
||||||
|
rel_identity = rel_key or rel
|
||||||
|
if not rel or rel_identity in seen_rels:
|
||||||
continue
|
continue
|
||||||
seen_rels.add(rel)
|
seen_rels.add(rel_identity)
|
||||||
entry_id = str(entry.get("id") or "").strip()
|
entry_id = str(entry.get("id") or "").strip()
|
||||||
entry_name = str(entry.get("name") or "").strip()
|
entry_name = str(entry.get("name") or "").strip()
|
||||||
if isinstance(drum_tab_rel, str) and rel == drum_tab_rel.strip():
|
if primary_rel_key is not None and rel_key == primary_rel_key:
|
||||||
if entry_id:
|
if entry_id:
|
||||||
primary_id = entry_id
|
primary_id = entry_id
|
||||||
if entry_name:
|
if entry_name:
|
||||||
|
|||||||
@@ -118,6 +118,24 @@ def test_two_parts_resolve_primary_first_with_alias_identity(tmp_path: Path):
|
|||||||
assert loaded.drum_parts[1]["drum_tab"]["hits"][0]["t"] == 2.0
|
assert loaded.drum_parts[1]["drum_tab"]["hits"][0]["t"] == 2.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_primary_pointer_equivalent_path_is_not_duplicated(tmp_path: Path):
|
||||||
|
manifest = {
|
||||||
|
"drum_tab": "drum_tab.json",
|
||||||
|
"arrangements": [
|
||||||
|
{"id": "lead", "name": "Lead", "file": "arrangements/lead.json"},
|
||||||
|
{"id": "kit", "name": "Live Kit", "type": "drums",
|
||||||
|
"drum_tab": "./drum_tab.json"},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
pak = _write_pak(tmp_path, manifest, {"drum_tab.json": _tab("Drums")})
|
||||||
|
loaded = _load(pak, tmp_path)
|
||||||
|
assert loaded.drum_parts is not None
|
||||||
|
assert [(p["id"], p["name"]) for p in loaded.drum_parts] == [
|
||||||
|
("kit", "Live Kit"),
|
||||||
|
]
|
||||||
|
assert loaded.drum_parts[0]["drum_tab"] is loaded.drum_tab
|
||||||
|
|
||||||
|
|
||||||
def test_legacy_single_drum_pack_gets_a_one_part_list(tmp_path: Path):
|
def test_legacy_single_drum_pack_gets_a_one_part_list(tmp_path: Path):
|
||||||
pak = _write_pak(tmp_path, {"drum_tab": "drum_tab.json"}, {
|
pak = _write_pak(tmp_path, {"drum_tab": "drum_tab.json"}, {
|
||||||
"drum_tab.json": _tab("Drums"),
|
"drum_tab.json": _tab("Drums"),
|
||||||
|
|||||||
Reference in New Issue
Block a user