mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-10 13:33:24 -05:00
fix: record a release only from finished packs
This commit is contained in:
1 parent
6c75f5ae15
commit
170b7d93ae
2 files changed
+44
-3
No files matched your search
@@ -24,7 +24,7 @@ import zipfile
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import split_pack
|
import split_pack
|
||||||
from common import write_text_atomic
|
from common import ArtifactLockBusy, artifact_lock, write_text_atomic
|
||||||
|
|
||||||
RECORD = "release.json"
|
RECORD = "release.json"
|
||||||
|
|
||||||
@@ -34,11 +34,32 @@ def _match_key(value: str) -> str:
|
|||||||
return re.sub(r"[^a-z0-9]", "", value.lower())
|
return re.sub(r"[^a-z0-9]", "", value.lower())
|
||||||
|
|
||||||
|
|
||||||
|
class UnfinishedSplit(Exception):
|
||||||
|
"""A pack lies beside its own parts: a split is running or was killed."""
|
||||||
|
|
||||||
|
|
||||||
def build_record(dist: Path, tag: str) -> dict:
|
def build_record(dist: Path, tag: str) -> dict:
|
||||||
"""Read every pack of a directory, parts counted once across them."""
|
"""Read every pack of a directory, parts counted once across them.
|
||||||
|
|
||||||
|
Read under the shared artifact lock, so a split that is reading its parts
|
||||||
|
back cannot be recorded half done. A pack still beside its parts after
|
||||||
|
that is a split that never finished: summed, it doubled the download size
|
||||||
|
and named an asset that is never published.
|
||||||
|
"""
|
||||||
|
with artifact_lock(str(dist), exclusive=False):
|
||||||
|
return _read_record(Path(dist), tag)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_record(dist: Path, tag: str) -> dict:
|
||||||
assets: dict[str, list[Path]] = {}
|
assets: dict[str, list[Path]] = {}
|
||||||
for path in sorted(Path(dist).glob("*_BIOS_Pack*.zip")):
|
for path in sorted(dist.glob("*_BIOS_Pack*.zip")):
|
||||||
assets.setdefault(split_pack.pack_of(path.name), []).append(path)
|
assets.setdefault(split_pack.pack_of(path.name), []).append(path)
|
||||||
|
for name, paths in sorted(assets.items()):
|
||||||
|
whole = [p for p in paths if not split_pack.is_part(p.name)]
|
||||||
|
if whole and len(paths) > len(whole):
|
||||||
|
raise UnfinishedSplit(
|
||||||
|
f"{whole[0].name} lies beside its parts: the split did not finish"
|
||||||
|
)
|
||||||
|
|
||||||
packs = {}
|
packs = {}
|
||||||
for name, paths in sorted(assets.items()):
|
for name, paths in sorted(assets.items()):
|
||||||
@@ -110,7 +131,11 @@ def main() -> int:
|
|||||||
parser.add_argument("--output", default=RECORD, type=Path)
|
parser.add_argument("--output", default=RECORD, type=Path)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
record = build_record(args.dist, args.tag)
|
record = build_record(args.dist, args.tag)
|
||||||
|
except (UnfinishedSplit, ArtifactLockBusy) as exc:
|
||||||
|
print(f"Error: {exc}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
if not record["packs"]:
|
if not record["packs"]:
|
||||||
print(f"Error: no pack in {args.dist}", file=sys.stderr)
|
print(f"Error: no pack in {args.dist}", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -352,6 +352,22 @@ class ReleaseRecord(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_pack_beside_its_parts_is_refused(self):
|
||||||
|
"""A split reading its parts back, or one killed before removing the
|
||||||
|
pack, leaves both: summed, the download size doubled."""
|
||||||
|
self._pack(
|
||||||
|
"Demo_2.0_BIOS_Pack.zip",
|
||||||
|
{f"dir/file{n}.bin": bytes([n]) * 700 + bytes(range(256)) for n in range(6)},
|
||||||
|
)
|
||||||
|
with self.assertRaises(release_record.UnfinishedSplit):
|
||||||
|
release_record.build_record(self.dist, "v1")
|
||||||
|
|
||||||
|
def test_a_directory_being_written_is_not_read(self):
|
||||||
|
with common.artifact_lock(str(self.dist)), \
|
||||||
|
self.assertRaises(common.ArtifactLockBusy):
|
||||||
|
release_record.build_record(self.dist, "v1")
|
||||||
|
|
||||||
|
|
||||||
class TheCollectionTotalNamesTheCollection(unittest.TestCase):
|
class TheCollectionTotalNamesTheCollection(unittest.TestCase):
|
||||||
COMPOSITION = {
|
COMPOSITION = {
|
||||||
"systems": {"files": 5030},
|
"systems": {"files": 5030},
|
||||||
|
|||||||
Reference in new issue
Block a user