Merge remote-tracking branch 'origin/feat/drum-parts-loader' into feat/drum-part-picker

This commit is contained in:
ChrisBeWithYou 2026-07-20 23:01:21 -05:00
commit 2281e6ce5e
2 changed files with 30 additions and 3 deletions

View File

@ -790,14 +790,23 @@ def _resolve_drum_parts(
primary_name = None
extra_parts: list[dict] = []
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:
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
seen_rels.add(rel)
seen_rels.add(rel_identity)
entry_id = str(entry.get("id") 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:
primary_id = entry_id
if entry_name:

View File

@ -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
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):
pak = _write_pak(tmp_path, {"drum_tab": "drum_tab.json"}, {
"drum_tab.json": _tab("Drums"),