fix: resolve bios case collisions

Delete duplicate lowercase variants (identical MD5) of 12 files
that prevented clean checkout on case-insensitive filesystems
(Windows, macOS).

Canonical chosen per upstream source code:
- Atari 2600 KV*.WAV: uppercase (stella2023 hardcode)
- Vectrex VEC_Minestorm.vec: lowercase (BizHawk hardcode)
- MSX MSX{,2,2EXT}.ROM: uppercase (fMSX hardcode, 6/7 platforms)
- Doom DOOM2.WAD: uppercase (matches dir convention)

Add aliases to stella2014 and clk profiles so resolution still
finds the canonical source. Correct retrodeck Vectrex casing to
match upstream. Merge Commodore/Vic-20 into VIC-20.

Add tests/test_no_case_collisions.py as a CI guard.

Closes #49
This commit is contained in:
Abdessamad Derraz
2026-04-18 10:01:29 +02:00
parent c8b27cac5e
commit e90095abd9
27 changed files with 134 additions and 290 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
{
"generated_at": "2026-04-02T12:45:07Z",
"generated_at": "2026-04-18T07:32:14Z",
"total_files": 7302,
"total_size": 9190488848,
"files": {
@@ -30814,8 +30814,8 @@
"adler32": "87461161"
},
"65d07426b520ddd3115d40f255511e0fd2e20ae7": {
"path": "bios/GCE/Vectrex/VEC_MineStorm.vec",
"name": "VEC_MineStorm.vec",
"path": "bios/GCE/Vectrex/VEC_Minestorm.vec",
"name": "VEC_Minestorm.vec",
"size": 8192,
"sha1": "65d07426b520ddd3115d40f255511e0fd2e20ae7",
"md5": "ab082fa8c8e632dd68589a8c7741388f",
@@ -89077,7 +89077,7 @@
"VEC_Bios.bin": [
"b9bbf5bb0eac52d039a4a993a2d8064b862c9e28"
],
"VEC_MineStorm.vec": [
"VEC_Minestorm.vec": [
"65d07426b520ddd3115d40f255511e0fd2e20ae7"
],
"CHRGEN.BIN": [
@@ -89087,8 +89087,7 @@
"aea7a4c0c7ffe1f212f7b9faecfd728862ac6904"
],
"doom2.wad": [
"6d559b7ceece4f5ad457415049711992370d520a",
"7ec7652fcfce8ddc6e801839291f0e28ef1d5ae7"
"6d559b7ceece4f5ad457415049711992370d520a"
],
"freedoom1.wad": [
"97bb88094a51457a8dcad98c58be22a2d0fa9a37"
@@ -101523,27 +101522,6 @@
"samesame.zip": [
"cdb09d3ffaa867ff9e7387cf1934e9011565d546"
],
"kvb1.wav": [
"6a582aebcefd6e2a97bdd8968202aab9851a889c"
],
"kvb2.wav": [
"60a425c6bde3226ab731995562716321be20fc49"
],
"kvb3.wav": [
"5e34125c4d6c209b21d1c892f3df0ec1644fd0d8"
],
"kvs1.wav": [
"b094c2c1fca81a0e531e0541f302346150ec4604"
],
"kvs2.wav": [
"8b83b2eea01b3e08ceb885aeb153d4084bddb63c"
],
"kvs3.wav": [
"86896a1e272d8715489de9b407f0b8a42f82d4a0"
],
"kvshared.wav": [
"9adf10cdf1de833b194c7d8797ad1f041ad98dd3"
],
"atari_osb.rom": [
"db1031585968cfc6ec2ecda5c9a5a52f61444a3b"
],
@@ -101754,18 +101732,18 @@
"kernal.318004-05.bin": [
"7c7e07f016391174a557e790c4ef1cbe33512cdb"
],
"characters-japanese.bin": [
"dae61ac03065aa2904af5c123ce821855898c555"
],
"kernel-japanese.bin": [
"c9ead45e6674d1042ca6199160e8583c23aeac22"
],
"basic.bin": [
"587d1e90950675ab6b12d91248a3f0d640d02e8d"
],
"characters-english.bin": [
"4fd85ab6647ee2ac7ba40f729323f2472d35b9b4"
],
"characters-japanese.bin": [
"dae61ac03065aa2904af5c123ce821855898c555"
],
"kernel-japanese.bin": [
"c9ead45e6674d1042ca6199160e8583c23aeac22"
],
"kernel-ntsc.bin": [
"06de7ec017a5e78bd6746d89c2ecebb646efeb19"
],
@@ -101818,9 +101796,6 @@
"sl90025.bin": [
"759e2ed31fbde4a2d8daf8b9f3e0dffebc90dae2"
],
"VEC_Minestorm.vec": [
"65d07426b520ddd3115d40f255511e0fd2e20ae7"
],
"Vectrex_Bios.bin": [
"b9bbf5bb0eac52d039a4a993a2d8064b862c9e28"
],
@@ -101849,15 +101824,6 @@
"px-7_basic-bios1.rom": [
"302afb5d8be26c758309ca3df611ae69cced2821"
],
"msx.rom": [
"409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498"
],
"Machines/Shared Roms/MSX.rom": [
"409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498"
],
"msx2.rom": [
"6103b39f1e38d1aa2d84b1c3219c44f1abb5436e"
],
"nms8250_basic-bios2.rom": [
"6103b39f1e38d1aa2d84b1c3219c44f1abb5436e"
],
@@ -101867,9 +101833,6 @@
"nms8245_basic-bios2.rom": [
"6103b39f1e38d1aa2d84b1c3219c44f1abb5436e"
],
"msx2ext.rom": [
"5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02"
],
"nms8250_msx2sub.rom": [
"5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02"
],
@@ -103332,6 +103295,9 @@
"EXOS21.ROM": [
"55315b20fecb4441a07ee4bc5dc7153f396e0a2e"
],
"Machines/Shared Roms/MSX.rom": [
"409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498"
],
"sony-playstation:239665b1a3dade1b5a52c06338011044": [
"343883a7b555646da8cee54aadd2795b6e7dd070"
],
@@ -132695,14 +132661,12 @@
"81193965a374d77b99b4743d317824b53c3e3c78",
"8f70d1b74483ba3a37e86cf16c849d601a8c3d2c",
"759e2ed31fbde4a2d8daf8b9f3e0dffebc90dae2",
"65d07426b520ddd3115d40f255511e0fd2e20ae7",
"5a65b922b562cb1f57dab51b73151283f0e20c7a",
"f9608bb4ad1cfe3640d02844c7ad8e0bcd974917",
"000ac11b702a4c42e40f135df12fa5f2f13e20a1",
"3656bb3bbc17d280d2016fe4f6ff3cded3082a41",
"e998f0c441f4f1800ef44e42cd1659150206cf79",
"302afb5d8be26c758309ca3df611ae69cced2821",
"409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498",
"6103b39f1e38d1aa2d84b1c3219c44f1abb5436e",
"5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02",
"5aff2d9b6efc723bc395b0f96f0adfa83cc54a49",
@@ -132865,6 +132829,7 @@
"9451a1a09d8f75944dbd6f91193fc360f1de80ac",
"03bbb386cf530e804363acdfc1d13e64cf28af2e",
"55315b20fecb4441a07ee4bc5dc7153f396e0a2e",
"409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498",
"343883a7b555646da8cee54aadd2795b6e7dd070",
"15c94da3cc5a38a582429575af4198c487fe893c",
"73107d468fc7cb1d2c5b18b269715dd889ecef06",

View File

@@ -720,7 +720,8 @@ files:
# MSX (machine_name: "MSX")
# -------------------------------------------------------
- name: msx.rom
path: MSX/msx.rom
aliases: [MSX.ROM]
path: MSX/MSX.ROM
description: "Generic MSX BIOS"
size: 32768
crc32: "94ee12f3"
@@ -768,7 +769,8 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:763-769"
- name: msx2.rom
path: MSX/msx2.rom
aliases: [MSX2.ROM]
path: MSX/MSX2.ROM
description: "Generic MSX2 BIOS"
size: 32768
crc32: "6cdaf3a5"
@@ -778,7 +780,8 @@ files:
source_ref: "Machines/Utility/ROMCatalogue.cpp:771-778"
- name: msx2ext.rom
path: MSX/msx2ext.rom
aliases: [MSX2EXT.ROM]
path: MSX/MSX2EXT.ROM
description: "MSX2 extension ROM"
size: 16384
crc32: "66237ecf"

View File

@@ -24,36 +24,43 @@ notes: |
files:
- name: kvs1.wav
aliases: [KVS1.WAV]
description: "KidVid Voice Module audio tape 1 (Smurfs Save the Day)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvs2.wav
aliases: [KVS2.WAV]
description: "KidVid Voice Module audio tape 2 (Smurfs Save the Day)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvs3.wav
aliases: [KVS3.WAV]
description: "KidVid Voice Module audio tape 3 (Smurfs Save the Day)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb1.wav
aliases: [KVB1.WAV]
description: "KidVid Voice Module audio tape 1 (Berenstain Bears)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb2.wav
aliases: [KVB2.WAV]
description: "KidVid Voice Module audio tape 2 (Berenstain Bears)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvb3.wav
aliases: [KVB3.WAV]
description: "KidVid Voice Module audio tape 3 (Berenstain Bears)"
required: false
category: game_data
source_ref: "stella/src/emucore/KidVid.cxx:167,182"
- name: kvshared.wav
aliases: [KVSHARED.WAV]
description: "KidVid Voice Module shared audio samples"
required: false
category: game_data

View File

@@ -4,7 +4,7 @@
"platform": "batocera",
"display_name": "Batocera",
"version": "1.0",
"generated": "2026-04-03T09:43:11Z",
"generated": "2026-04-18T07:55:01Z",
"base_destination": "bios",
"detect": [
{
@@ -230,8 +230,8 @@
}
}
],
"total_files": 1547,
"total_size": 4371484317,
"total_files": 1540,
"total_size": 4337691265,
"files": [
{
"dest": "panafz1.bin",
@@ -4722,7 +4722,7 @@
]
},
{
"dest": "MSX/msx.rom",
"dest": "MSX/MSX.ROM",
"sha1": "409e82adac40f6bdd18eb6c84e8b2fbdc7fb5498",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX.ROM",
@@ -4767,7 +4767,7 @@
]
},
{
"dest": "MSX/msx2.rom",
"dest": "MSX/MSX2.ROM",
"sha1": "6103b39f1e38d1aa2d84b1c3219c44f1abb5436e",
"size": 32768,
"repo_path": "bios/Microsoft/MSX/MSX2.ROM",
@@ -4776,7 +4776,7 @@
]
},
{
"dest": "MSX/msx2ext.rom",
"dest": "MSX/MSX2EXT.ROM",
"sha1": "5c1f9c7fb655e43d38e5dd1fcc6b942b2ff68b02",
"size": 16384,
"repo_path": "bios/Microsoft/MSX/MSX2EXT.ROM",
@@ -9375,69 +9375,6 @@
"SquirrelJME"
]
},
{
"dest": "kvs1.wav",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs2.wav",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs3.wav",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb1.wav",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb2.wav",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb3.wav",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvshared.wav",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",

View File

@@ -4,7 +4,7 @@
"platform": "bizhawk",
"display_name": "BizHawk",
"version": "1.0",
"generated": "2026-04-02T13:52:21Z",
"generated": "2026-04-18T07:55:07Z",
"base_destination": "Firmware",
"detect": [
{
@@ -285,7 +285,7 @@
"dest": "VEC_Minestorm.vec",
"sha1": "65d07426b520ddd3115d40f255511e0fd2e20ae7",
"size": 8192,
"repo_path": "bios/GCE/Vectrex/VEC_MineStorm.vec",
"repo_path": "bios/GCE/Vectrex/VEC_Minestorm.vec",
"cores": null
},
{

View File

@@ -4,7 +4,7 @@
"platform": "lakka",
"display_name": "Lakka",
"version": "1.0",
"generated": "2026-04-02T13:52:45Z",
"generated": "2026-04-18T07:55:35Z",
"base_destination": "system",
"detect": [
{
@@ -9837,66 +9837,66 @@
]
},
{
"dest": "kvs1.wav",
"dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvs2.wav",
"dest": "KVS2.WAV",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvs3.wav",
"dest": "KVS3.WAV",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb1.wav",
"dest": "KVB1.WAV",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb2.wav",
"dest": "KVB2.WAV",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb3.wav",
"dest": "KVB3.WAV",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvshared.wav",
"dest": "KVSHARED.WAV",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{

View File

@@ -4,7 +4,7 @@
"platform": "recalbox",
"display_name": "Recalbox",
"version": "1.0",
"generated": "2026-04-03T09:44:06Z",
"generated": "2026-04-18T07:56:06Z",
"base_destination": "bios",
"detect": [
{
@@ -230,8 +230,8 @@
}
}
],
"total_files": 1107,
"total_size": 3980096655,
"total_files": 1100,
"total_size": 3946303603,
"files": [
{
"dest": "3do/panafz1.bin",
@@ -6968,69 +6968,6 @@
"SAME CDi"
]
},
{
"dest": "kvs1.wav",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs2.wav",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs3.wav",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb1.wav",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb2.wav",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb3.wav",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvshared.wav",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",

View File

@@ -4,7 +4,7 @@
"platform": "retroarch",
"display_name": "RetroArch",
"version": "1.0",
"generated": "2026-04-03T09:43:38Z",
"generated": "2026-04-18T07:55:35Z",
"base_destination": "system",
"detect": [
{
@@ -10070,66 +10070,66 @@
]
},
{
"dest": "kvs1.wav",
"dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvs2.wav",
"dest": "KVS2.WAV",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvs3.wav",
"dest": "KVS3.WAV",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb1.wav",
"dest": "KVB1.WAV",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb2.wav",
"dest": "KVB2.WAV",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvb3.wav",
"dest": "KVB3.WAV",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{
"dest": "kvshared.wav",
"dest": "KVSHARED.WAV",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
"Stella 2023"
]
},
{

View File

@@ -4,7 +4,7 @@
"platform": "retrodeck",
"display_name": "RetroDECK",
"version": "1.0",
"generated": "2026-04-03T09:44:33Z",
"generated": "2026-04-18T07:56:37Z",
"base_destination": "",
"detect": [
{
@@ -230,8 +230,8 @@
}
}
],
"total_files": 3153,
"total_size": 6351500734,
"total_files": 3146,
"total_size": 6317707682,
"files": [
{
"dest": "bios/panafz1.bin",
@@ -13879,10 +13879,10 @@
"cores": null
},
{
"dest": "bios/VEC_MineStorm.vec",
"dest": "bios/VEC_Minestorm.vec",
"sha1": "65d07426b520ddd3115d40f255511e0fd2e20ae7",
"size": 8192,
"repo_path": "bios/GCE/Vectrex/VEC_MineStorm.vec",
"repo_path": "bios/GCE/Vectrex/VEC_Minestorm.vec",
"cores": null
},
{
@@ -20436,69 +20436,6 @@
"SquirrelJME"
]
},
{
"dest": "kvs1.wav",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",
"size": 3436329,
"repo_path": "bios/Atari/2600/KVS1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs2.wav",
"sha1": "8b83b2eea01b3e08ceb885aeb153d4084bddb63c",
"size": 2086275,
"repo_path": "bios/Atari/2600/KVS2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvs3.wav",
"sha1": "86896a1e272d8715489de9b407f0b8a42f82d4a0",
"size": 3720920,
"repo_path": "bios/Atari/2600/KVS3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb1.wav",
"sha1": "6a582aebcefd6e2a97bdd8968202aab9851a889c",
"size": 4219542,
"repo_path": "bios/Atari/2600/KVB1.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb2.wav",
"sha1": "60a425c6bde3226ab731995562716321be20fc49",
"size": 9593878,
"repo_path": "bios/Atari/2600/KVB2.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvb3.wav",
"sha1": "5e34125c4d6c209b21d1c892f3df0ec1644fd0d8",
"size": 7676992,
"repo_path": "bios/Atari/2600/KVB3.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "kvshared.wav",
"sha1": "9adf10cdf1de833b194c7d8797ad1f041ad98dd3",
"size": 3059116,
"repo_path": "bios/Atari/2600/KVSHARED.WAV",
"cores": [
"Stella 2014"
]
},
{
"dest": "KVS1.WAV",
"sha1": "b094c2c1fca81a0e531e0541f302346150ec4604",

View File

@@ -7978,8 +7978,8 @@ systems:
- name: Vectrex_Bios.bin
destination: bios/Vectrex_Bios.bin
required: false
- name: VEC_MineStorm.vec
destination: bios/VEC_MineStorm.vec
- name: VEC_Minestorm.vec
destination: bios/VEC_Minestorm.vec
required: false
vsmile:
files:

View File

@@ -0,0 +1,58 @@
from __future__ import annotations
import os
import unittest
from collections import defaultdict
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
BIOS_ROOT = REPO_ROOT / "bios"
class TestNoCaseCollisions(unittest.TestCase):
"""Guard against case-colliding paths in bios/.
On case-insensitive filesystems (Windows, macOS default), git can only
check out one path per casefold-equivalence class, silently corrupting
clones. Issue #33 and #49 both stemmed from this.
.variants/ subdirs are exempt: they intentionally hold genuine content
variants disambiguated by hash suffix (e.g., BIOS.ROM.910fae67).
"""
def test_bios_has_no_case_colliding_paths(self) -> None:
if not BIOS_ROOT.is_dir():
self.skipTest("bios/ directory not present")
collisions: list[str] = []
for root, dirs, files in os.walk(BIOS_ROOT):
if ".variants" in Path(root).parts:
continue
dir_groups: dict[str, list[str]] = defaultdict(list)
for d in dirs:
dir_groups[d.casefold()].append(d)
for variants in dir_groups.values():
if len(variants) > 1:
rel = Path(root).relative_to(REPO_ROOT)
collisions.append(f"DIR {rel}: {sorted(variants)}")
file_groups: dict[str, list[str]] = defaultdict(list)
for f in files:
file_groups[f.casefold()].append(f)
for variants in file_groups.values():
if len(variants) > 1:
rel = Path(root).relative_to(REPO_ROOT)
collisions.append(f"FILE {rel}: {sorted(variants)}")
self.assertEqual(
collisions,
[],
"Case-colliding paths in bios/ would break Windows/macOS clones:\n"
+ "\n".join(collisions),
)
if __name__ == "__main__":
unittest.main()